src/video/x11/SDL_x11gl.c
author Ryan C. Gordon <icculus@icculus.org>
Sat, 12 Sep 2009 06:25:36 +0000
branchSDL-1.2
changeset 4183 39e748f251c6
parent 4159 a1b03ba2fcd0
child 4268 d48035d857d3
permissions -rw-r--r--
Patched X11 code to compile on Mac OS X 10.6 SDK.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_x11video.h"
    25 #include "../../events/SDL_events_c.h"
    26 #include "SDL_x11dga_c.h"
    27 #include "SDL_x11gl_c.h"
    28 
    29 #if defined(__IRIX__)
    30 /* IRIX doesn't have a GL library versioning system */
    31 #define DEFAULT_OPENGL	"libGL.so"
    32 #elif defined(__MACOSX__)
    33 #define DEFAULT_OPENGL	"/usr/X11R6/lib/libGL.1.dylib"
    34 #elif defined(__QNXNTO__)
    35 #define DEFAULT_OPENGL	"libGL.so.3"
    36 #elif defined(__OpenBSD__)
    37 #define DEFAULT_OPENGL	"libGL.so.4.0"
    38 #else
    39 #define DEFAULT_OPENGL	"libGL.so.1"
    40 #endif
    41 
    42 #ifndef GLX_ARB_multisample
    43 #define GLX_ARB_multisample
    44 #define GLX_SAMPLE_BUFFERS_ARB             100000
    45 #define GLX_SAMPLES_ARB                    100001
    46 #endif
    47 
    48 /* GLX_EXT_visual_rating stuff that might not be in the system headers... */
    49 #ifndef GLX_VISUAL_CAVEAT_EXT
    50 #define GLX_VISUAL_CAVEAT_EXT              0x20
    51 #endif
    52 #ifndef GLX_NONE_EXT
    53 #define GLX_NONE_EXT                       0x8000
    54 #endif
    55 #ifndef GLX_SLOW_VISUAL_EXT
    56 #define GLX_SLOW_VISUAL_EXT                0x8001
    57 #endif
    58 #ifndef GLX_NON_CONFORMANT_VISUAL_EXT
    59 #define GLX_NON_CONFORMANT_VISUAL_EXT      0x800D
    60 #endif
    61 
    62 
    63 #if SDL_VIDEO_OPENGL_GLX
    64 static int glXExtensionSupported(_THIS, const char *extension)
    65 {
    66 	const char *extensions;
    67 	const char *start;
    68 	const char *where, *terminator;
    69 
    70 	/* Extension names should not have spaces. */
    71 	where = SDL_strchr(extension, ' ');
    72 	if ( where || *extension == '\0' ) {
    73 	      return 0;
    74 	}
    75 
    76 	extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen);
    77 	/* It takes a bit of care to be fool-proof about parsing the
    78 	 * OpenGL extensions string. Don't be fooled by sub-strings, etc.
    79 	 */
    80 	
    81 	start = extensions;
    82 	
    83 	for (;;) {
    84 		where = SDL_strstr(start, extension);
    85 		if (!where) break;
    86 		
    87 		terminator = where + strlen(extension);
    88 		if (where == start || *(where - 1) == ' ')
    89 	        if (*terminator == ' ' || *terminator == '\0') return 1;
    90 						  
    91 		start = terminator;
    92 	}
    93 	return 0;
    94 }
    95 #endif /* SDL_VIDEO_OPENGL_GLX */
    96 
    97 XVisualInfo *X11_GL_GetVisual(_THIS)
    98 {
    99 #if SDL_VIDEO_OPENGL_GLX
   100 	/* 64 seems nice. */
   101 	int attribs[64];
   102 	int i;
   103 
   104 	/* load the gl driver from a default path */
   105 	if ( ! this->gl_config.driver_loaded ) {
   106 	        /* no driver has been loaded, use default (ourselves) */
   107 	        if ( X11_GL_LoadLibrary(this, NULL) < 0 ) {
   108 		        return NULL;
   109 		}
   110 	}
   111 
   112 	/* See if we already have a window which we must use */
   113 	if ( SDL_windowid ) {
   114 		XWindowAttributes a;
   115 		XVisualInfo vi_in;
   116 		int out_count;
   117 
   118 		XGetWindowAttributes(SDL_Display, SDL_Window, &a);
   119 		vi_in.screen = SDL_Screen;
   120 		vi_in.visualid = XVisualIDFromVisual(a.visual);
   121 		glx_visualinfo = XGetVisualInfo(SDL_Display,
   122 	                     VisualScreenMask|VisualIDMask, &vi_in, &out_count);
   123 		return glx_visualinfo;
   124 	}
   125 
   126         /* Setup our GLX attributes according to the gl_config. */
   127 	i = 0;
   128 	attribs[i++] = GLX_RGBA;
   129 	attribs[i++] = GLX_RED_SIZE;
   130 	attribs[i++] = this->gl_config.red_size;
   131 	attribs[i++] = GLX_GREEN_SIZE;
   132 	attribs[i++] = this->gl_config.green_size;
   133 	attribs[i++] = GLX_BLUE_SIZE;
   134 	attribs[i++] = this->gl_config.blue_size;
   135 
   136 	if( this->gl_config.alpha_size ) {
   137 		attribs[i++] = GLX_ALPHA_SIZE;
   138 		attribs[i++] = this->gl_config.alpha_size;
   139 	}
   140 
   141 	if( this->gl_config.buffer_size ) {
   142 		attribs[i++] = GLX_BUFFER_SIZE;
   143 		attribs[i++] = this->gl_config.buffer_size;
   144 	}
   145 
   146 	if( this->gl_config.double_buffer ) {
   147 		attribs[i++] = GLX_DOUBLEBUFFER;
   148 	}
   149 
   150 	attribs[i++] = GLX_DEPTH_SIZE;
   151 	attribs[i++] = this->gl_config.depth_size;
   152 
   153 	if( this->gl_config.stencil_size ) {
   154 		attribs[i++] = GLX_STENCIL_SIZE;
   155 		attribs[i++] = this->gl_config.stencil_size;
   156 	}
   157 
   158 	if( this->gl_config.accum_red_size ) {
   159 		attribs[i++] = GLX_ACCUM_RED_SIZE;
   160 		attribs[i++] = this->gl_config.accum_red_size;
   161 	}
   162 
   163 	if( this->gl_config.accum_green_size ) {
   164 		attribs[i++] = GLX_ACCUM_GREEN_SIZE;
   165 		attribs[i++] = this->gl_config.accum_green_size;
   166 	}
   167 
   168 	if( this->gl_config.accum_blue_size ) {
   169 		attribs[i++] = GLX_ACCUM_BLUE_SIZE;
   170 		attribs[i++] = this->gl_config.accum_blue_size;
   171 	}
   172 
   173 	if( this->gl_config.accum_alpha_size ) {
   174 		attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
   175 		attribs[i++] = this->gl_config.accum_alpha_size;
   176 	}
   177 
   178 	if( this->gl_config.stereo ) {
   179 		attribs[i++] = GLX_STEREO;
   180 	}
   181 	
   182 	if( this->gl_config.multisamplebuffers ) {
   183 		attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
   184 		attribs[i++] = this->gl_config.multisamplebuffers;
   185 	}
   186 	
   187 	if( this->gl_config.multisamplesamples ) {
   188 		attribs[i++] = GLX_SAMPLES_ARB;
   189 		attribs[i++] = this->gl_config.multisamplesamples;
   190 	}
   191 
   192 	if( this->gl_config.accelerated >= 0 &&
   193 	    glXExtensionSupported(this, "GLX_EXT_visual_rating") ) {
   194 		attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
   195 		attribs[i++] = GLX_NONE_EXT;
   196 	}
   197 
   198 #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */
   199 	if ( !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) {
   200 		attribs[i++] = GLX_X_VISUAL_TYPE;
   201 		attribs[i++] = GLX_DIRECT_COLOR;
   202 	}
   203 #endif
   204 	attribs[i++] = None;
   205 
   206  	glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, 
   207 						  SDL_Screen, attribs);
   208 #ifdef GLX_DIRECT_COLOR
   209 	if( !glx_visualinfo && !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { /* No DirectColor visual?  Try again.. */
   210 		attribs[i-3] = None;
   211  		glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, 
   212 						  SDL_Screen, attribs);
   213 	}
   214 #endif
   215 	if( !glx_visualinfo ) {
   216 		SDL_SetError( "Couldn't find matching GLX visual");
   217 		return NULL;
   218 	}
   219 /*
   220 	printf("Found GLX visual 0x%x\n", glx_visualinfo->visualid);
   221 */
   222 	return glx_visualinfo;
   223 #else
   224 	SDL_SetError("X11 driver not configured with OpenGL");
   225 	return NULL;
   226 #endif
   227 }
   228 
   229 int X11_GL_CreateWindow(_THIS, int w, int h)
   230 {
   231 	int retval;
   232 #if SDL_VIDEO_OPENGL_GLX
   233 	XSetWindowAttributes attributes;
   234 	unsigned long mask;
   235 	unsigned long black;
   236 
   237 	black = (glx_visualinfo->visual == DefaultVisual(SDL_Display,
   238 						 	SDL_Screen))
   239 	       	? BlackPixel(SDL_Display, SDL_Screen) : 0;
   240 	attributes.background_pixel = black;
   241 	attributes.border_pixel = black;
   242 	attributes.colormap = SDL_XColorMap;
   243 	mask = CWBackPixel | CWBorderPixel | CWColormap;
   244 
   245 	SDL_Window = XCreateWindow(SDL_Display, WMwindow,
   246 			0, 0, w, h, 0, glx_visualinfo->depth,
   247 			InputOutput, glx_visualinfo->visual,
   248 			mask, &attributes);
   249 	if ( !SDL_Window ) {
   250 		SDL_SetError("Could not create window");
   251 		return -1;
   252 	}
   253 	retval = 0;
   254 #else
   255 	SDL_SetError("X11 driver not configured with OpenGL");
   256 	retval = -1;
   257 #endif
   258 	return(retval);
   259 }
   260 
   261 int X11_GL_CreateContext(_THIS)
   262 {
   263 	int retval;
   264 #if SDL_VIDEO_OPENGL_GLX
   265 
   266 	/* We do this to create a clean separation between X and GLX errors. */
   267 	XSync( SDL_Display, False );
   268 	glx_context = this->gl_data->glXCreateContext(GFX_Display, 
   269 				     glx_visualinfo, NULL, True);
   270 	XSync( GFX_Display, False );
   271 
   272 	if ( glx_context == NULL ) {
   273 		SDL_SetError("Could not create GL context");
   274 		return(-1);
   275 	}
   276 	if ( X11_GL_MakeCurrent(this) < 0 ) {
   277 		return(-1);
   278 	}
   279 	gl_active = 1;
   280 
   281 	if ( !glXExtensionSupported(this, "GLX_SGI_swap_control") ) {
   282 		this->gl_data->glXSwapIntervalSGI = NULL;
   283 	}
   284 	if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) {
   285 		this->gl_data->glXSwapIntervalMESA = NULL;
   286 		this->gl_data->glXGetSwapIntervalMESA = NULL;
   287 	}
   288 	if ( this->gl_config.swap_control >= 0 ) {
   289 		if ( this->gl_data->glXSwapIntervalMESA ) {
   290 			this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control);
   291 		} else if ( this->gl_data->glXSwapIntervalSGI ) {
   292 			this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control);
   293 		}
   294 	}
   295 #else
   296 	SDL_SetError("X11 driver not configured with OpenGL");
   297 #endif
   298 	if ( gl_active ) {
   299 		retval = 0;
   300 	} else {
   301 		retval = -1;
   302 	}
   303 	return(retval);
   304 }
   305 
   306 void X11_GL_Shutdown(_THIS)
   307 {
   308 #if SDL_VIDEO_OPENGL_GLX
   309 	/* Clean up OpenGL */
   310 	if( glx_context ) {
   311 		this->gl_data->glXMakeCurrent(GFX_Display, None, NULL);
   312 
   313 		if (glx_context != NULL)
   314 			this->gl_data->glXDestroyContext(GFX_Display, glx_context);
   315 
   316 		glx_context = NULL;
   317 	}
   318 	gl_active = 0;
   319 #endif /* SDL_VIDEO_OPENGL_GLX */
   320 }
   321 
   322 #if SDL_VIDEO_OPENGL_GLX
   323 
   324 /* Make the current context active */
   325 int X11_GL_MakeCurrent(_THIS)
   326 {
   327 	int retval;
   328 	
   329 	retval = 0;
   330 	if ( ! this->gl_data->glXMakeCurrent(GFX_Display,
   331 	                                     SDL_Window, glx_context) ) {
   332 		SDL_SetError("Unable to make GL context current");
   333 		retval = -1;
   334 	}
   335 	XSync( GFX_Display, False );
   336 
   337 	/* More Voodoo X server workarounds... Grr... */
   338 	SDL_Lock_EventThread();
   339 	X11_CheckDGAMouse(this);
   340 	SDL_Unlock_EventThread();
   341 
   342 	return(retval);
   343 }
   344 
   345 /* Get attribute data from glX. */
   346 int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   347 {
   348 	int retval = -1;
   349 	int unsupported = 0;
   350 	int glx_attrib = None;
   351 
   352 	switch( attrib ) {
   353 	    case SDL_GL_RED_SIZE:
   354 		glx_attrib = GLX_RED_SIZE;
   355 		break;
   356 	    case SDL_GL_GREEN_SIZE:
   357 		glx_attrib = GLX_GREEN_SIZE;
   358 		break;
   359 	    case SDL_GL_BLUE_SIZE:
   360 		glx_attrib = GLX_BLUE_SIZE;
   361 		break;
   362 	    case SDL_GL_ALPHA_SIZE:
   363 		glx_attrib = GLX_ALPHA_SIZE;
   364 		break;
   365 	    case SDL_GL_DOUBLEBUFFER:
   366 		glx_attrib = GLX_DOUBLEBUFFER;
   367 		break;
   368 	    case SDL_GL_BUFFER_SIZE:
   369 		glx_attrib = GLX_BUFFER_SIZE;
   370 		break;
   371 	    case SDL_GL_DEPTH_SIZE:
   372 		glx_attrib = GLX_DEPTH_SIZE;
   373 		break;
   374 	    case SDL_GL_STENCIL_SIZE:
   375 		glx_attrib = GLX_STENCIL_SIZE;
   376 		break;
   377 	    case SDL_GL_ACCUM_RED_SIZE:
   378 		glx_attrib = GLX_ACCUM_RED_SIZE;
   379 		break;
   380 	    case SDL_GL_ACCUM_GREEN_SIZE:
   381 		glx_attrib = GLX_ACCUM_GREEN_SIZE;
   382 		break;
   383 	    case SDL_GL_ACCUM_BLUE_SIZE:
   384 		glx_attrib = GLX_ACCUM_BLUE_SIZE;
   385 		break;
   386 	    case SDL_GL_ACCUM_ALPHA_SIZE:
   387 		glx_attrib = GLX_ACCUM_ALPHA_SIZE;
   388 		break;
   389 	    case SDL_GL_STEREO:
   390 		glx_attrib = GLX_STEREO;
   391 		break;
   392  	    case SDL_GL_MULTISAMPLEBUFFERS:
   393  		glx_attrib = GLX_SAMPLE_BUFFERS_ARB;
   394  		break;
   395  	    case SDL_GL_MULTISAMPLESAMPLES:
   396  		glx_attrib = GLX_SAMPLES_ARB;
   397  		break;
   398  	    case SDL_GL_ACCELERATED_VISUAL:
   399 		if ( glXExtensionSupported(this, "GLX_EXT_visual_rating") ) {
   400 			glx_attrib = GLX_VISUAL_CAVEAT_EXT;
   401 			retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value);
   402 			if ( *value == GLX_SLOW_VISUAL_EXT ) {
   403 				*value = SDL_FALSE;
   404 			} else {
   405 				*value = SDL_TRUE;
   406 			}
   407 			return retval;
   408 		} else {
   409 			unsupported = 1;
   410 		}
   411 		break;
   412 	    case SDL_GL_SWAP_CONTROL:
   413 		if ( this->gl_data->glXGetSwapIntervalMESA ) {
   414 			*value = this->gl_data->glXGetSwapIntervalMESA();
   415 			return(0);
   416 		} else {
   417 			unsupported = 1;
   418 		}
   419 		break;
   420 	    default:
   421 			unsupported = 1;
   422 			break;
   423 	}
   424 
   425 	if (unsupported) {
   426 		SDL_SetError("OpenGL attribute is unsupported on this system");
   427 	} else {
   428 		retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value);
   429 	}
   430 	return retval;
   431 }
   432 
   433 void X11_GL_SwapBuffers(_THIS)
   434 {
   435 	this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window);
   436 }
   437 
   438 #endif /* SDL_VIDEO_OPENGL_GLX */
   439 
   440 #define OPENGL_REQUIRS_DLOPEN
   441 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
   442 #include <dlfcn.h>
   443 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
   444 #define GL_LoadFunction		dlsym
   445 #define GL_UnloadObject		dlclose
   446 #else
   447 #define GL_LoadObject	SDL_LoadObject
   448 #define GL_LoadFunction	SDL_LoadFunction
   449 #define GL_UnloadObject	SDL_UnloadObject
   450 #endif
   451 
   452 void X11_GL_UnloadLibrary(_THIS)
   453 {
   454 #if SDL_VIDEO_OPENGL_GLX
   455 	if ( this->gl_config.driver_loaded ) {
   456 
   457 		GL_UnloadObject(this->gl_config.dll_handle);
   458 
   459 		this->gl_data->glXGetProcAddress = NULL;
   460 		this->gl_data->glXChooseVisual = NULL;
   461 		this->gl_data->glXCreateContext = NULL;
   462 		this->gl_data->glXDestroyContext = NULL;
   463 		this->gl_data->glXMakeCurrent = NULL;
   464 		this->gl_data->glXSwapBuffers = NULL;
   465 		this->gl_data->glXSwapIntervalSGI = NULL;
   466 		this->gl_data->glXSwapIntervalMESA = NULL;
   467 		this->gl_data->glXGetSwapIntervalMESA = NULL;
   468 
   469 		this->gl_config.dll_handle = NULL;
   470 		this->gl_config.driver_loaded = 0;
   471 	}
   472 #endif
   473 }
   474 
   475 #if SDL_VIDEO_OPENGL_GLX
   476 
   477 /* Passing a NULL path means load pointers from the application */
   478 int X11_GL_LoadLibrary(_THIS, const char* path) 
   479 {
   480 	void* handle = NULL;
   481 
   482 	if ( gl_active ) {
   483 		SDL_SetError("OpenGL context already created");
   484 		return -1;
   485 	}
   486 
   487 	if ( path == NULL ) {
   488 		path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   489 		if ( path == NULL ) {
   490 			path = DEFAULT_OPENGL;
   491 		}
   492 	}
   493 
   494 	handle = GL_LoadObject(path);
   495 	if ( handle == NULL ) {
   496 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
   497 		SDL_SetError("Failed loading %s", path);
   498 #else
   499 		/* SDL_LoadObject() will call SDL_SetError() for us. */
   500 #endif
   501 		return -1;
   502 	}
   503 
   504 	/* Unload the old driver and reset the pointers */
   505 	X11_GL_UnloadLibrary(this);
   506 
   507 	/* Load new function pointers */
   508 	this->gl_data->glXGetProcAddress =
   509 		(void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB");
   510 	this->gl_data->glXChooseVisual =
   511 		(XVisualInfo *(*)(Display *, int, int *)) GL_LoadFunction(handle, "glXChooseVisual");
   512 	this->gl_data->glXCreateContext =
   513 		(GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) GL_LoadFunction(handle, "glXCreateContext");
   514 	this->gl_data->glXDestroyContext =
   515 		(void (*)(Display *, GLXContext)) GL_LoadFunction(handle, "glXDestroyContext");
   516 	this->gl_data->glXMakeCurrent =
   517 		(int (*)(Display *, GLXDrawable, GLXContext)) GL_LoadFunction(handle, "glXMakeCurrent");
   518 	this->gl_data->glXSwapBuffers =
   519 		(void (*)(Display *, GLXDrawable)) GL_LoadFunction(handle, "glXSwapBuffers");
   520 	this->gl_data->glXGetConfig =
   521 		(int (*)(Display *, XVisualInfo *, int, int *)) GL_LoadFunction(handle, "glXGetConfig");
   522 	this->gl_data->glXQueryExtensionsString =
   523 		(const char *(*)(Display *, int)) GL_LoadFunction(handle, "glXQueryExtensionsString");
   524 	this->gl_data->glXSwapIntervalSGI =
   525 		(int (*)(int)) GL_LoadFunction(handle, "glXSwapIntervalSGI");
   526 	this->gl_data->glXSwapIntervalMESA =
   527 		(GLint (*)(unsigned)) GL_LoadFunction(handle, "glXSwapIntervalMESA");
   528 	this->gl_data->glXGetSwapIntervalMESA =
   529 		(GLint (*)(void)) GL_LoadFunction(handle, "glXGetSwapIntervalMESA");
   530 
   531 	if ( (this->gl_data->glXChooseVisual == NULL) || 
   532 	     (this->gl_data->glXCreateContext == NULL) ||
   533 	     (this->gl_data->glXDestroyContext == NULL) ||
   534 	     (this->gl_data->glXMakeCurrent == NULL) ||
   535 	     (this->gl_data->glXSwapBuffers == NULL) ||
   536 	     (this->gl_data->glXGetConfig == NULL) ||
   537 	     (this->gl_data->glXQueryExtensionsString == NULL)) {
   538 		SDL_SetError("Could not retrieve OpenGL functions");
   539 		return -1;
   540 	}
   541 
   542 	this->gl_config.dll_handle = handle;
   543 	this->gl_config.driver_loaded = 1;
   544 	if ( path ) {
   545 		SDL_strlcpy(this->gl_config.driver_path, path,
   546 			SDL_arraysize(this->gl_config.driver_path));
   547 	} else {
   548 		*this->gl_config.driver_path = '\0';
   549 	}
   550 	return 0;
   551 }
   552 
   553 void *X11_GL_GetProcAddress(_THIS, const char* proc)
   554 {
   555 	void* handle;
   556 	
   557 	handle = this->gl_config.dll_handle;
   558 	if ( this->gl_data->glXGetProcAddress ) {
   559 		return this->gl_data->glXGetProcAddress((const GLubyte *)proc);
   560 	}
   561 	return GL_LoadFunction(handle, proc);
   562 }
   563 
   564 #endif /* SDL_VIDEO_OPENGL_GLX */