src/video/x11/SDL_x11opengl.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 13 Oct 2011 01:08:30 -0400
changeset 5981 75caa8a7d559
parent 5630 39e74dab5ebb
child 6044 35448a5ea044
permissions -rw-r--r--
Fixed a whole slew of compiler warnings that -Wall exposed.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 #include "SDL_x11video.h"
    23 #include "SDL_assert.h"
    24 
    25 /* GLX implementation of SDL OpenGL support */
    26 
    27 #if SDL_VIDEO_OPENGL_GLX
    28 #include "SDL_loadso.h"
    29 
    30 #if defined(__IRIX__)
    31 /* IRIX doesn't have a GL library versioning system */
    32 #define DEFAULT_OPENGL	"libGL.so"
    33 #elif defined(__MACOSX__)
    34 #define DEFAULT_OPENGL	"/usr/X11R6/lib/libGL.1.dylib"
    35 #elif defined(__QNXNTO__)
    36 #define DEFAULT_OPENGL	"libGL.so.3"
    37 #else
    38 #define DEFAULT_OPENGL	"libGL.so.1"
    39 #endif
    40 
    41 #ifndef GLX_NONE_EXT
    42 #define GLX_NONE_EXT                       0x8000
    43 #endif
    44 
    45 #ifndef GLX_ARB_multisample
    46 #define GLX_ARB_multisample
    47 #define GLX_SAMPLE_BUFFERS_ARB             100000
    48 #define GLX_SAMPLES_ARB                    100001
    49 #endif
    50 
    51 #ifndef GLX_EXT_visual_rating
    52 #define GLX_EXT_visual_rating
    53 #define GLX_VISUAL_CAVEAT_EXT              0x20
    54 #define GLX_NONE_EXT                       0x8000
    55 #define GLX_SLOW_VISUAL_EXT                0x8001
    56 #define GLX_NON_CONFORMANT_VISUAL_EXT      0x800D
    57 #endif
    58 
    59 #ifndef GLX_ARB_create_context
    60 #define GLX_ARB_create_context
    61 #define GLX_CONTEXT_MAJOR_VERSION_ARB      0x2091
    62 #define GLX_CONTEXT_MINOR_VERSION_ARB      0x2092
    63 #define GLX_CONTEXT_FLAGS_ARB              0x2094
    64 #define GLX_CONTEXT_DEBUG_BIT_ARB          0x0001
    65 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
    66 
    67 #ifndef GLX_EXT_swap_control
    68 #define GLX_SWAP_INTERVAL_EXT              0x20F1
    69 #define GLX_MAX_SWAP_INTERVAL_EXT          0x20F2
    70 #endif
    71 
    72 /* Typedef for the GL 3.0 context creation function */
    73 typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
    74                                                         GLXFBConfig config,
    75                                                         GLXContext
    76                                                         share_context,
    77                                                         Bool direct,
    78                                                         const int
    79                                                         *attrib_list);
    80 #endif
    81 
    82 #define OPENGL_REQUIRS_DLOPEN
    83 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
    84 #include <dlfcn.h>
    85 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
    86 #define GL_LoadFunction		dlsym
    87 #define GL_UnloadObject		dlclose
    88 #else
    89 #define GL_LoadObject	SDL_LoadObject
    90 #define GL_LoadFunction	SDL_LoadFunction
    91 #define GL_UnloadObject	SDL_UnloadObject
    92 #endif
    93 
    94 static void X11_GL_InitExtensions(_THIS);
    95 
    96 
    97 int
    98 X11_GL_LoadLibrary(_THIS, const char *path)
    99 {
   100     void *handle;
   101 
   102     /* Load the OpenGL library */
   103     if (path == NULL) {
   104         path = SDL_getenv("SDL_OPENGL_LIBRARY");
   105     }
   106     if (path == NULL) {
   107         path = DEFAULT_OPENGL;
   108     }
   109     _this->gl_config.dll_handle = SDL_LoadObject(path);
   110     if (!_this->gl_config.dll_handle) {
   111         return -1;
   112     }
   113     SDL_strlcpy(_this->gl_config.driver_path, path,
   114                 SDL_arraysize(_this->gl_config.driver_path));
   115 
   116     /* Allocate OpenGL memory */
   117     _this->gl_data =
   118         (struct SDL_GLDriverData *) SDL_calloc(1,
   119                                                sizeof(struct
   120                                                       SDL_GLDriverData));
   121     if (!_this->gl_data) {
   122         SDL_OutOfMemory();
   123         return -1;
   124     }
   125 
   126     /* Load function pointers */
   127     handle = _this->gl_config.dll_handle;
   128     _this->gl_data->glXGetProcAddress =
   129         (void *(*)(const GLubyte *))
   130             GL_LoadFunction(handle, "glXGetProcAddressARB");
   131     _this->gl_data->glXChooseVisual =
   132         (XVisualInfo * (*)(Display *, int, int *))
   133             X11_GL_GetProcAddress(_this, "glXChooseVisual");
   134     _this->gl_data->glXCreateContext =
   135         (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
   136             X11_GL_GetProcAddress(_this, "glXCreateContext");
   137     _this->gl_data->glXDestroyContext =
   138         (void (*)(Display *, GLXContext))
   139             X11_GL_GetProcAddress(_this, "glXDestroyContext");
   140     _this->gl_data->glXMakeCurrent =
   141         (int (*)(Display *, GLXDrawable, GLXContext))
   142             X11_GL_GetProcAddress(_this, "glXMakeCurrent");
   143     _this->gl_data->glXSwapBuffers =
   144         (void (*)(Display *, GLXDrawable))
   145             X11_GL_GetProcAddress(_this, "glXSwapBuffers");
   146     _this->gl_data->glXQueryDrawable =
   147         (void (*)(Display*,GLXDrawable,int,unsigned int*))
   148             X11_GL_GetProcAddress(_this, "glXQueryDrawable");
   149 
   150     if (!_this->gl_data->glXChooseVisual ||
   151         !_this->gl_data->glXCreateContext ||
   152         !_this->gl_data->glXDestroyContext ||
   153         !_this->gl_data->glXMakeCurrent ||
   154         !_this->gl_data->glXSwapBuffers) {
   155         SDL_SetError("Could not retrieve OpenGL functions");
   156         return -1;
   157     }
   158 
   159     /* Initialize extensions */
   160     X11_GL_InitExtensions(_this);
   161 
   162     return 0;
   163 }
   164 
   165 void *
   166 X11_GL_GetProcAddress(_THIS, const char *proc)
   167 {
   168     if (_this->gl_data->glXGetProcAddress) {
   169         return _this->gl_data->glXGetProcAddress((const GLubyte *) proc);
   170     }
   171     return GL_LoadFunction(_this->gl_config.dll_handle, proc);
   172 }
   173 
   174 void
   175 X11_GL_UnloadLibrary(_THIS)
   176 {
   177     /* Don't actually unload the library, since it may have registered
   178      * X11 shutdown hooks, per the notes at:
   179      * http://dri.sourceforge.net/doc/DRIuserguide.html
   180      */
   181 #if 0
   182     GL_UnloadObject(_this->gl_config.dll_handle);
   183     _this->gl_config.dll_handle = NULL;
   184 #endif
   185 
   186     /* Free OpenGL memory */
   187     SDL_free(_this->gl_data);
   188     _this->gl_data = NULL;
   189 }
   190 
   191 static SDL_bool
   192 HasExtension(const char *extension, const char *extensions)
   193 {
   194     const char *start;
   195     const char *where, *terminator;
   196 
   197     /* Extension names should not have spaces. */
   198     where = SDL_strchr(extension, ' ');
   199     if (where || *extension == '\0')
   200         return SDL_FALSE;
   201 
   202     if (!extensions)
   203         return SDL_FALSE;
   204 
   205     /* It takes a bit of care to be fool-proof about parsing the
   206      * OpenGL extensions string. Don't be fooled by sub-strings,
   207      * etc. */
   208 
   209     start = extensions;
   210 
   211     for (;;) {
   212         where = SDL_strstr(start, extension);
   213         if (!where)
   214             break;
   215 
   216         terminator = where + SDL_strlen(extension);
   217         if (where == start || *(where - 1) == ' ')
   218             if (*terminator == ' ' || *terminator == '\0')
   219                 return SDL_TRUE;
   220 
   221         start = terminator;
   222     }
   223     return SDL_FALSE;
   224 }
   225 
   226 static void
   227 X11_GL_InitExtensions(_THIS)
   228 {
   229     Display *display = ((SDL_VideoData *) _this->driverdata)->display;
   230     int screen = DefaultScreen(display);
   231     XVisualInfo *vinfo;
   232     XSetWindowAttributes xattr;
   233     Window w;
   234     GLXContext context;
   235     const char *(*glXQueryExtensionsStringFunc) (Display *, int);
   236     const char *extensions;
   237 
   238     vinfo = X11_GL_GetVisual(_this, display, screen);
   239     if (!vinfo) {
   240         return;
   241     }
   242     xattr.background_pixel = 0;
   243     xattr.border_pixel = 0;
   244     xattr.colormap =
   245         XCreateColormap(display, RootWindow(display, screen), vinfo->visual,
   246                         AllocNone);
   247     w = XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0,
   248                       vinfo->depth, InputOutput, vinfo->visual,
   249                       (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
   250     context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
   251     if (context) {
   252         _this->gl_data->glXMakeCurrent(display, w, context);
   253     }
   254     XFree(vinfo);
   255 
   256     glXQueryExtensionsStringFunc =
   257         (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this,
   258                                                                 "glXQueryExtensionsString");
   259     if (glXQueryExtensionsStringFunc) {
   260         extensions = glXQueryExtensionsStringFunc(display, screen);
   261     } else {
   262         extensions = NULL;
   263     }
   264 
   265     /* Check for GLX_EXT_swap_control */
   266     if (HasExtension("GLX_EXT_swap_control", extensions)) {
   267         _this->gl_data->glXSwapIntervalEXT =
   268             (int (*)(Display*,GLXDrawable,int))
   269                 X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
   270     }
   271 
   272     /* Check for GLX_MESA_swap_control */
   273     if (HasExtension("GLX_MESA_swap_control", extensions)) {
   274         _this->gl_data->glXSwapIntervalMESA =
   275             (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA");
   276         _this->gl_data->glXGetSwapIntervalMESA =
   277             (int(*)(void)) X11_GL_GetProcAddress(_this,
   278                                                    "glXGetSwapIntervalMESA");
   279     }
   280 
   281     /* Check for GLX_SGI_swap_control */
   282     if (HasExtension("GLX_SGI_swap_control", extensions)) {
   283         _this->gl_data->glXSwapIntervalSGI =
   284             (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
   285     }
   286 
   287     /* Check for GLX_EXT_visual_rating */
   288     if (HasExtension("GLX_EXT_visual_rating", extensions)) {
   289         _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE;
   290     }
   291 
   292     if (context) {
   293         _this->gl_data->glXMakeCurrent(display, None, NULL);
   294         _this->gl_data->glXDestroyContext(display, context);
   295     }
   296     XDestroyWindow(display, w);
   297     X11_PumpEvents(_this);
   298 }
   299 
   300 int 
   301 X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size)
   302 {
   303     int i = 0;
   304 
   305     /* assert buffer is large enough to hold all SDL attributes. */ 
   306     /* assert(size >= 32);*/
   307 
   308     /* Setup our GLX attributes according to the gl_config. */
   309     attribs[i++] = GLX_RGBA;
   310     attribs[i++] = GLX_RED_SIZE;
   311     attribs[i++] = _this->gl_config.red_size;
   312     attribs[i++] = GLX_GREEN_SIZE;
   313     attribs[i++] = _this->gl_config.green_size;
   314     attribs[i++] = GLX_BLUE_SIZE;
   315     attribs[i++] = _this->gl_config.blue_size;
   316 
   317     if (_this->gl_config.alpha_size) {
   318         attribs[i++] = GLX_ALPHA_SIZE;
   319         attribs[i++] = _this->gl_config.alpha_size;
   320     }
   321 
   322     if (_this->gl_config.buffer_size) {
   323         attribs[i++] = GLX_BUFFER_SIZE;
   324         attribs[i++] = _this->gl_config.buffer_size;
   325     }
   326 
   327     if (_this->gl_config.double_buffer) {
   328         attribs[i++] = GLX_DOUBLEBUFFER;
   329     }
   330 
   331     attribs[i++] = GLX_DEPTH_SIZE;
   332     attribs[i++] = _this->gl_config.depth_size;
   333 
   334     if (_this->gl_config.stencil_size) {
   335         attribs[i++] = GLX_STENCIL_SIZE;
   336         attribs[i++] = _this->gl_config.stencil_size;
   337     }
   338 
   339     if (_this->gl_config.accum_red_size) {
   340         attribs[i++] = GLX_ACCUM_RED_SIZE;
   341         attribs[i++] = _this->gl_config.accum_red_size;
   342     }
   343 
   344     if (_this->gl_config.accum_green_size) {
   345         attribs[i++] = GLX_ACCUM_GREEN_SIZE;
   346         attribs[i++] = _this->gl_config.accum_green_size;
   347     }
   348 
   349     if (_this->gl_config.accum_blue_size) {
   350         attribs[i++] = GLX_ACCUM_BLUE_SIZE;
   351         attribs[i++] = _this->gl_config.accum_blue_size;
   352     }
   353 
   354     if (_this->gl_config.accum_alpha_size) {
   355         attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
   356         attribs[i++] = _this->gl_config.accum_alpha_size;
   357     }
   358 
   359     if (_this->gl_config.stereo) {
   360         attribs[i++] = GLX_STEREO;
   361     }
   362 
   363     if (_this->gl_config.multisamplebuffers) {
   364         attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
   365         attribs[i++] = _this->gl_config.multisamplebuffers;
   366     }
   367 
   368     if (_this->gl_config.multisamplesamples) {
   369         attribs[i++] = GLX_SAMPLES_ARB;
   370         attribs[i++] = _this->gl_config.multisamplesamples;
   371     }
   372 
   373     if (_this->gl_config.accelerated >= 0 &&
   374         _this->gl_data->HAS_GLX_EXT_visual_rating) {
   375         attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
   376         attribs[i++] = _this->gl_config.accelerated ? GLX_NONE_EXT :
   377                                                       GLX_SLOW_VISUAL_EXT;
   378     }
   379 
   380     attribs[i++] = None;
   381  
   382     return i;
   383 }
   384 
   385 XVisualInfo *
   386 X11_GL_GetVisual(_THIS, Display * display, int screen)
   387 {
   388     XVisualInfo *vinfo;
   389 
   390     /* 64 seems nice. */
   391     const int max_attrs = 64;
   392     int attribs[max_attrs];
   393     const int i = X11_GL_GetAttributes(_this,display,screen,attribs,max_attrs);
   394     SDL_assert(i <= max_attrs);
   395 
   396     vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
   397     if (!vinfo) {
   398         SDL_SetError("Couldn't find matching GLX visual");
   399     }
   400     return vinfo;
   401 }
   402 
   403 SDL_GLContext
   404 X11_GL_CreateContext(_THIS, SDL_Window * window)
   405 {
   406     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   407     Display *display = data->videodata->display;
   408     int screen =
   409         ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen;
   410     XWindowAttributes xattr;
   411     XVisualInfo v, *vinfo;
   412     int n;
   413     GLXContext context = NULL;
   414 
   415     /* We do this to create a clean separation between X and GLX errors. */
   416     XSync(display, False);
   417     XGetWindowAttributes(display, data->xwindow, &xattr);
   418     v.screen = screen;
   419     v.visualid = XVisualIDFromVisual(xattr.visual);
   420     vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
   421     if (vinfo) {
   422         if (_this->gl_config.major_version < 3) {
   423             context =
   424                 _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
   425         } else {
   426             /* If we want a GL 3.0 context or later we need to get a temporary
   427                context to grab the new context creation function */
   428             GLXContext temp_context =
   429                 _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
   430             if (!temp_context) {
   431                 SDL_SetError("Could not create GL context");
   432                 return NULL;
   433             } else {
   434                 int attribs[] = {
   435                     GLX_CONTEXT_MAJOR_VERSION_ARB,
   436                     _this->gl_config.major_version,
   437                     GLX_CONTEXT_MINOR_VERSION_ARB,
   438                     _this->gl_config.minor_version,
   439                     0
   440                 };
   441 
   442                 /* Get a pointer to the context creation function for GL 3.0 */
   443                 PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
   444                     (PFNGLXCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
   445                     glXGetProcAddress((GLubyte *)
   446                                       "glXCreateContextAttribsARB");
   447                 if (!glXCreateContextAttribs) {
   448                     SDL_SetError("GL 3.x is not supported");
   449                     context = temp_context;
   450                 } else {
   451                     int glxAttribs[64];
   452 
   453                     /* Create a GL 3.x context */
   454                     GLXFBConfig *framebuffer_config = NULL;
   455                     int fbcount = 0;
   456                     GLXFBConfig *(*glXChooseFBConfig) (Display * disp,
   457                                                        int screen,
   458                                                        const int *attrib_list,
   459                                                        int *nelements);
   460 
   461                     glXChooseFBConfig =
   462                         (GLXFBConfig *
   463                          (*)(Display *, int, const int *,
   464                              int *)) _this->gl_data->
   465                         glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
   466 
   467                     X11_GL_GetAttributes(_this,display,screen,glxAttribs,64);
   468 
   469                     if (!glXChooseFBConfig
   470                         || !(framebuffer_config =
   471                              glXChooseFBConfig(display,
   472                                                DefaultScreen(display), glxAttribs,
   473                                                &fbcount))) {
   474                         SDL_SetError
   475                             ("No good framebuffers found. GL 3.x disabled");
   476                         context = temp_context;
   477                     } else {
   478                         context =
   479                             glXCreateContextAttribs(display,
   480                                                     framebuffer_config[0],
   481                                                     NULL, True, attribs);
   482                         _this->gl_data->glXDestroyContext(display,
   483                                                           temp_context);
   484                     }
   485                 }
   486             }
   487         }
   488         XFree(vinfo);
   489     }
   490     XSync(display, False);
   491 
   492     if (!context) {
   493         SDL_SetError("Could not create GL context");
   494         return NULL;
   495     }
   496 
   497     if (X11_GL_MakeCurrent(_this, window, context) < 0) {
   498         X11_GL_DeleteContext(_this, context);
   499         return NULL;
   500     }
   501 
   502     return context;
   503 }
   504 
   505 int
   506 X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   507 {
   508     Display *display = ((SDL_VideoData *) _this->driverdata)->display;
   509     Window drawable =
   510         (window ? ((SDL_WindowData *) window->driverdata)->xwindow : None);
   511     GLXContext glx_context = (GLXContext) context;
   512     int status;
   513 
   514     status = 0;
   515     if (!_this->gl_data->glXMakeCurrent(display, drawable, glx_context)) {
   516         SDL_SetError("Unable to make GL context current");
   517         status = -1;
   518     }
   519     XSync(display, False);
   520 
   521     return (status);
   522 }
   523 
   524 /* 
   525    0 is a valid argument to glxSwapInterval(MESA|EXT) and setting it to 0
   526    will undo the effect of a previous call with a value that is greater
   527    than zero (or at least that is what the docs say). OTOH, 0 is an invalid
   528    argument to glxSwapIntervalSGI and it returns an error if you call it
   529    with 0 as an argument.
   530 */
   531 
   532 static int swapinterval = -1;
   533 int
   534 X11_GL_SetSwapInterval(_THIS, int interval)
   535 {
   536     int status;
   537 
   538     if (_this->gl_data->glXSwapIntervalEXT) {
   539         Display *display = ((SDL_VideoData *) _this->driverdata)->display;
   540         const SDL_WindowData *windowdata = (SDL_WindowData *)
   541             _this->current_glwin->driverdata;
   542         Window drawable = windowdata->xwindow;
   543         status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval);
   544         if (status != 0) {
   545             SDL_SetError("glxSwapIntervalEXT failed");
   546             status = -1;
   547         } else {
   548             swapinterval = interval;
   549         }
   550     } else if (_this->gl_data->glXSwapIntervalMESA) {
   551         status = _this->gl_data->glXSwapIntervalMESA(interval);
   552         if (status != 0) {
   553             SDL_SetError("glxSwapIntervalMESA failed");
   554             status = -1;
   555         } else {
   556             swapinterval = interval;
   557         }
   558     } else if (_this->gl_data->glXSwapIntervalSGI) {
   559         status = _this->gl_data->glXSwapIntervalSGI(interval);
   560         if (status != 0) {
   561             SDL_SetError("glxSwapIntervalSGI failed");
   562             status = -1;
   563         } else {
   564             swapinterval = interval;
   565         }
   566     } else {
   567         SDL_Unsupported();
   568         status = -1;
   569     }
   570     return status;
   571 }
   572 
   573 int
   574 X11_GL_GetSwapInterval(_THIS)
   575 {
   576     if (_this->gl_data->glXSwapIntervalEXT) {
   577         Display *display = ((SDL_VideoData *) _this->driverdata)->display;
   578         const SDL_WindowData *windowdata = (SDL_WindowData *)
   579             _this->current_glwin->driverdata;
   580         Window drawable = windowdata->xwindow;
   581         unsigned int value = 0;
   582         _this->gl_data->glXQueryDrawable(display, drawable,
   583                                          GLX_SWAP_INTERVAL_EXT, &value);
   584         return (int) value;
   585     } else if (_this->gl_data->glXGetSwapIntervalMESA) {
   586         return _this->gl_data->glXGetSwapIntervalMESA();
   587     } else {
   588         return swapinterval;
   589     }
   590 }
   591 
   592 void
   593 X11_GL_SwapWindow(_THIS, SDL_Window * window)
   594 {
   595     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   596     Display *display = data->videodata->display;
   597 
   598     _this->gl_data->glXSwapBuffers(display, data->xwindow);
   599 }
   600 
   601 void
   602 X11_GL_DeleteContext(_THIS, SDL_GLContext context)
   603 {
   604     Display *display = ((SDL_VideoData *) _this->driverdata)->display;
   605     GLXContext glx_context = (GLXContext) context;
   606 
   607     _this->gl_data->glXDestroyContext(display, glx_context);
   608     XSync(display, False);
   609 }
   610 
   611 #endif /* SDL_VIDEO_OPENGL_GLX */
   612 
   613 /* vi: set ts=4 sw=4 expandtab: */