comparison src/video/x11/SDL_x11gl.c @ 1191:2bd4cec0de63

Seperate glX from HAVE_OPENGL, for platforms that have both an X server and a more official way to do OpenGL, explicitly check for glX on Mac OS X, and use SDL_LoadObject for platforms that have glX but don't have dlopen().
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 23 Nov 2005 11:46:36 +0000
parents e8e8dcb68e7a
children b81f54c3963f
comparison
equal deleted inserted replaced
1190:173c063d4f55 1191:2bd4cec0de63
35 #include "SDL_x11gl_c.h" 35 #include "SDL_x11gl_c.h"
36 36
37 #if defined(sgi) 37 #if defined(sgi)
38 /* IRIX doesn't have a GL library versioning system */ 38 /* IRIX doesn't have a GL library versioning system */
39 #define DEFAULT_OPENGL "libGL.so" 39 #define DEFAULT_OPENGL "libGL.so"
40 #elif defined(MACOSX)
41 #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib"
40 #else 42 #else
41 #define DEFAULT_OPENGL "libGL.so.1" 43 #define DEFAULT_OPENGL "libGL.so.1"
42 #endif 44 #endif
43 45
44 #ifndef GLX_ARB_multisample 46 #ifndef GLX_ARB_multisample
48 #endif 50 #endif
49 51
50 /* return the preferred visual to use for openGL graphics */ 52 /* return the preferred visual to use for openGL graphics */
51 XVisualInfo *X11_GL_GetVisual(_THIS) 53 XVisualInfo *X11_GL_GetVisual(_THIS)
52 { 54 {
53 #ifdef HAVE_OPENGL 55 #ifdef HAVE_OPENGL_X11
54 /* 64 seems nice. */ 56 /* 64 seems nice. */
55 int attribs[64]; 57 int attribs[64];
56 int i; 58 int i;
57 59
58 /* load the gl driver from a default path */ 60 /* load the gl driver from a default path */
173 } 175 }
174 176
175 int X11_GL_CreateWindow(_THIS, int w, int h) 177 int X11_GL_CreateWindow(_THIS, int w, int h)
176 { 178 {
177 int retval; 179 int retval;
178 #ifdef HAVE_OPENGL 180 #ifdef HAVE_OPENGL_X11
179 XSetWindowAttributes attributes; 181 XSetWindowAttributes attributes;
180 unsigned long mask; 182 unsigned long mask;
181 unsigned long black; 183 unsigned long black;
182 184
183 black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, 185 black = (glx_visualinfo->visual == DefaultVisual(SDL_Display,
205 } 207 }
206 208
207 int X11_GL_CreateContext(_THIS) 209 int X11_GL_CreateContext(_THIS)
208 { 210 {
209 int retval; 211 int retval;
210 #ifdef HAVE_OPENGL 212 #ifdef HAVE_OPENGL_X11
211 /* We do this to create a clean separation between X and GLX errors. */ 213 /* We do this to create a clean separation between X and GLX errors. */
212 pXSync( SDL_Display, False ); 214 pXSync( SDL_Display, False );
213 glx_context = this->gl_data->glXCreateContext(GFX_Display, 215 glx_context = this->gl_data->glXCreateContext(GFX_Display,
214 glx_visualinfo, NULL, True); 216 glx_visualinfo, NULL, True);
215 pXSync( GFX_Display, False ); 217 pXSync( GFX_Display, False );
231 return(retval); 233 return(retval);
232 } 234 }
233 235
234 void X11_GL_Shutdown(_THIS) 236 void X11_GL_Shutdown(_THIS)
235 { 237 {
236 #ifdef HAVE_OPENGL 238 #ifdef HAVE_OPENGL_X11
237 /* Clean up OpenGL */ 239 /* Clean up OpenGL */
238 if( glx_context ) { 240 if( glx_context ) {
239 this->gl_data->glXMakeCurrent(GFX_Display, None, NULL); 241 this->gl_data->glXMakeCurrent(GFX_Display, None, NULL);
240 242
241 if (glx_context != NULL) 243 if (glx_context != NULL)
245 this->gl_data->glXReleaseBuffersMESA(GFX_Display,SDL_Window); 247 this->gl_data->glXReleaseBuffersMESA(GFX_Display,SDL_Window);
246 } 248 }
247 glx_context = NULL; 249 glx_context = NULL;
248 } 250 }
249 gl_active = 0; 251 gl_active = 0;
250 #endif /* HAVE_OPENGL */ 252 #endif /* HAVE_OPENGL_X11 */
251 } 253 }
252 254
253 #ifdef HAVE_OPENGL 255 #ifdef HAVE_OPENGL_X11
254 256
255 static int ExtensionSupported(const char *extension) 257 static int ExtensionSupported(const char *extension)
256 { 258 {
257 const GLubyte *extensions = NULL; 259 const GLubyte *extensions = NULL;
258 const GLubyte *start; 260 const GLubyte *start;
393 void X11_GL_SwapBuffers(_THIS) 395 void X11_GL_SwapBuffers(_THIS)
394 { 396 {
395 this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window); 397 this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window);
396 } 398 }
397 399
398 #endif /* HAVE_OPENGL */ 400 #endif /* HAVE_OPENGL_X11 */
399 401
400 void X11_GL_UnloadLibrary(_THIS) 402 void X11_GL_UnloadLibrary(_THIS)
401 { 403 {
402 #ifdef HAVE_OPENGL 404 #ifdef HAVE_OPENGL_X11
403 if ( this->gl_config.driver_loaded ) { 405 if ( this->gl_config.driver_loaded ) {
406
407 /* !!! FIXME: Can we just use SDL_UnloadObject() everywhere? */
408 #ifdef USE_DLOPEN
404 dlclose(this->gl_config.dll_handle); 409 dlclose(this->gl_config.dll_handle);
410 #else
411 SDL_UnloadObject(this->gl_config.dll_handle);
412 #endif
405 413
406 this->gl_data->glXGetProcAddress = NULL; 414 this->gl_data->glXGetProcAddress = NULL;
407 this->gl_data->glXChooseVisual = NULL; 415 this->gl_data->glXChooseVisual = NULL;
408 this->gl_data->glXCreateContext = NULL; 416 this->gl_data->glXCreateContext = NULL;
409 this->gl_data->glXDestroyContext = NULL; 417 this->gl_data->glXDestroyContext = NULL;
414 this->gl_config.driver_loaded = 0; 422 this->gl_config.driver_loaded = 0;
415 } 423 }
416 #endif 424 #endif
417 } 425 }
418 426
419 #ifdef HAVE_OPENGL 427 #ifdef HAVE_OPENGL_X11
420 428
421 /* If this is wrong, please put some #ifdefs for your platform! */ 429 static void *do_dlsym(void *handle, const char *name)
422 #define DEFAULT_GL_DRIVER_PATH "libGL.so.1" 430 {
431 /* !!! FIXME: Can we just use SDL_LoadFunction() everywhere? */
432 #ifdef USE_DLOPEN
433 return dlsym(handle, name);
434 #else
435 return SDL_LoadFunction(handle, name);
436 #endif
437 }
438
439 #if defined(__OpenBSD__) && !defined(__ELF__)
440 #define do_dlsym(x,y) do_dlsym(x, "_" y)
441 #endif
423 442
424 /* Passing a NULL path means load pointers from the application */ 443 /* Passing a NULL path means load pointers from the application */
425 int X11_GL_LoadLibrary(_THIS, const char* path) 444 int X11_GL_LoadLibrary(_THIS, const char* path)
426 { 445 {
427 void* handle; 446 void* handle = NULL;
428 int dlopen_flags;
429 447
430 if ( gl_active ) { 448 if ( gl_active ) {
431 SDL_SetError("OpenGL context already created"); 449 SDL_SetError("OpenGL context already created");
432 return -1; 450 return -1;
433 } 451 }
434 452
435 if ( path == NULL ) { 453 if ( path == NULL ) {
436 path = DEFAULT_GL_DRIVER_PATH;
437 }
438
439 #ifdef RTLD_GLOBAL
440 dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
441 #else
442 dlopen_flags = RTLD_LAZY;
443 #endif
444 handle = dlopen(path, dlopen_flags);
445 /* Catch the case where the application isn't linked with GL */
446 if ( (dlsym(handle, "glXChooseVisual") == NULL) && (path == NULL) ) {
447 dlclose(handle);
448 path = getenv("SDL_VIDEO_GL_DRIVER"); 454 path = getenv("SDL_VIDEO_GL_DRIVER");
449 if ( path == NULL ) { 455 if ( path == NULL ) {
450 path = DEFAULT_OPENGL; 456 path = DEFAULT_OPENGL;
451 } 457 }
458 }
459
460 /* !!! FIXME: Can we just use SDL_LoadObject() everywhere? */
461 #ifdef USE_DLOPEN
462 {
463 #ifdef RTLD_GLOBAL
464 int dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
465 #else
466 int dlopen_flags = RTLD_LAZY;
467 #endif
452 handle = dlopen(path, dlopen_flags); 468 handle = dlopen(path, dlopen_flags);
453 } 469 }
470 #else
471 handle = SDL_LoadObject(path);
472 #endif
473
454 if ( handle == NULL ) { 474 if ( handle == NULL ) {
455 SDL_SetError("Could not load OpenGL library"); 475 SDL_SetError("Could not load OpenGL library");
456 return -1; 476 return -1;
457 } 477 }
458 478
459 /* Unload the old driver and reset the pointers */ 479 /* Unload the old driver and reset the pointers */
460 X11_GL_UnloadLibrary(this); 480 X11_GL_UnloadLibrary(this);
461 481
462 /* Load new function pointers */ 482 /* Load new function pointers */
463 this->gl_data->glXGetProcAddress = 483 this->gl_data->glXGetProcAddress =
464 (void *(*)(const GLubyte *)) dlsym(handle, "glXGetProcAddressARB"); 484 (void *(*)(const GLubyte *)) do_dlsym(handle, "glXGetProcAddressARB");
465 this->gl_data->glXChooseVisual = 485 this->gl_data->glXChooseVisual =
466 (XVisualInfo *(*)(Display *, int, int *)) dlsym(handle, "glXChooseVisual"); 486 (XVisualInfo *(*)(Display *, int, int *)) do_dlsym(handle, "glXChooseVisual");
467 this->gl_data->glXCreateContext = 487 this->gl_data->glXCreateContext =
468 (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) dlsym(handle, "glXCreateContext"); 488 (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) do_dlsym(handle, "glXCreateContext");
469 this->gl_data->glXDestroyContext = 489 this->gl_data->glXDestroyContext =
470 (void (*)(Display *, GLXContext)) dlsym(handle, "glXDestroyContext"); 490 (void (*)(Display *, GLXContext)) do_dlsym(handle, "glXDestroyContext");
471 this->gl_data->glXMakeCurrent = 491 this->gl_data->glXMakeCurrent =
472 (int (*)(Display *, GLXDrawable, GLXContext)) dlsym(handle, "glXMakeCurrent"); 492 (int (*)(Display *, GLXDrawable, GLXContext)) do_dlsym(handle, "glXMakeCurrent");
473 this->gl_data->glXSwapBuffers = 493 this->gl_data->glXSwapBuffers =
474 (void (*)(Display *, GLXDrawable)) dlsym(handle, "glXSwapBuffers"); 494 (void (*)(Display *, GLXDrawable)) do_dlsym(handle, "glXSwapBuffers");
475 this->gl_data->glXGetConfig = 495 this->gl_data->glXGetConfig =
476 (int (*)(Display *, XVisualInfo *, int, int *)) dlsym(handle, "glXGetConfig"); 496 (int (*)(Display *, XVisualInfo *, int, int *)) do_dlsym(handle, "glXGetConfig");
477 this->gl_data->glXQueryExtensionsString = 497 this->gl_data->glXQueryExtensionsString =
478 (const char *(*)(Display *, int)) dlsym(handle, "glXQueryExtensionsString"); 498 (const char *(*)(Display *, int)) do_dlsym(handle, "glXQueryExtensionsString");
479 499
480 /* We don't compare below for this in case we're not using Mesa. */ 500 /* We don't compare below for this in case we're not using Mesa. */
481 this->gl_data->glXReleaseBuffersMESA = 501 this->gl_data->glXReleaseBuffersMESA =
482 (void (*)(Display *, GLXDrawable)) dlsym( handle, "glXReleaseBuffersMESA" ); 502 (void (*)(Display *, GLXDrawable)) do_dlsym( handle, "glXReleaseBuffersMESA" );
483 503
484 504
485 if ( (this->gl_data->glXChooseVisual == NULL) || 505 if ( (this->gl_data->glXChooseVisual == NULL) ||
486 (this->gl_data->glXCreateContext == NULL) || 506 (this->gl_data->glXCreateContext == NULL) ||
487 (this->gl_data->glXDestroyContext == NULL) || 507 (this->gl_data->glXDestroyContext == NULL) ||
513 handle = this->gl_config.dll_handle; 533 handle = this->gl_config.dll_handle;
514 if ( this->gl_data->glXGetProcAddress ) { 534 if ( this->gl_data->glXGetProcAddress ) {
515 return this->gl_data->glXGetProcAddress(proc); 535 return this->gl_data->glXGetProcAddress(proc);
516 } 536 }
517 #if defined(__OpenBSD__) && !defined(__ELF__) 537 #if defined(__OpenBSD__) && !defined(__ELF__)
518 #undef dlsym(x,y); 538 #undef do_dlsym
519 #endif 539 #endif
520 retval = dlsym(handle, proc); 540 retval = do_dlsym(handle, proc);
521 if (!retval && strlen(proc) <= 1022) { 541 if (!retval && strlen(proc) <= 1022) {
522 procname[0] = '_'; 542 procname[0] = '_';
523 strcpy(procname + 1, proc); 543 strcpy(procname + 1, proc);
524 retval = dlsym(handle, procname); 544 retval = do_dlsym(handle, procname);
525 } 545 }
526 return retval; 546 return retval;
527 } 547 }
528 548
529 #endif /* HAVE_OPENGL */ 549 #endif /* HAVE_OPENGL_X11 */