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