twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

glx_context.c (22481B)


      1 //========================================================================
      2 // GLFW 3.3 GLX - www.glfw.org
      3 //------------------------------------------------------------------------
      4 // Copyright (c) 2002-2006 Marcus Geelnard
      5 // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
      6 //
      7 // This software is provided 'as-is', without any express or implied
      8 // warranty. In no event will the authors be held liable for any damages
      9 // arising from the use of this software.
     10 //
     11 // Permission is granted to anyone to use this software for any purpose,
     12 // including commercial applications, and to alter it and redistribute it
     13 // freely, subject to the following restrictions:
     14 //
     15 // 1. The origin of this software must not be misrepresented; you must not
     16 //    claim that you wrote the original software. If you use this software
     17 //    in a product, an acknowledgment in the product documentation would
     18 //    be appreciated but is not required.
     19 //
     20 // 2. Altered source versions must be plainly marked as such, and must not
     21 //    be misrepresented as being the original software.
     22 //
     23 // 3. This notice may not be removed or altered from any source
     24 //    distribution.
     25 //
     26 //========================================================================
     27 // It is fine to use C99 in this file because it will not be built with VS
     28 //========================================================================
     29 
     30 #include "internal.h"
     31 
     32 #include <string.h>
     33 #include <stdlib.h>
     34 #include <assert.h>
     35 
     36 #ifndef GLXBadProfileARB
     37  #define GLXBadProfileARB 13
     38 #endif
     39 
     40 
     41 // Returns the specified attribute of the specified GLXFBConfig
     42 //
     43 static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
     44 {
     45     int value;
     46     glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
     47     return value;
     48 }
     49 
     50 // Return the GLXFBConfig most closely matching the specified hints
     51 //
     52 static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
     53                                   GLXFBConfig* result)
     54 {
     55     GLXFBConfig* nativeConfigs;
     56     _GLFWfbconfig* usableConfigs;
     57     const _GLFWfbconfig* closest;
     58     int i, nativeCount, usableCount;
     59     const char* vendor;
     60     GLFWbool trustWindowBit = GLFW_TRUE;
     61 
     62     // HACK: This is a (hopefully temporary) workaround for Chromium
     63     //       (VirtualBox GL) not setting the window bit on any GLXFBConfigs
     64     vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
     65     if (vendor && strcmp(vendor, "Chromium") == 0)
     66         trustWindowBit = GLFW_FALSE;
     67 
     68     nativeConfigs =
     69         glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
     70     if (!nativeConfigs || !nativeCount)
     71     {
     72         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
     73         return GLFW_FALSE;
     74     }
     75 
     76     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
     77     usableCount = 0;
     78 
     79     for (i = 0;  i < nativeCount;  i++)
     80     {
     81         const GLXFBConfig n = nativeConfigs[i];
     82         _GLFWfbconfig* u = usableConfigs + usableCount;
     83 
     84         // Only consider RGBA GLXFBConfigs
     85         if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
     86             continue;
     87 
     88         // Only consider window GLXFBConfigs
     89         if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
     90         {
     91             if (trustWindowBit)
     92                 continue;
     93         }
     94 
     95         if (desired->transparent)
     96         {
     97             XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
     98             if (vi)
     99             {
    100                 u->transparent = _glfwIsVisualTransparentX11(vi->visual);
    101                 XFree(vi);
    102             }
    103         }
    104 
    105         u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
    106         u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
    107         u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
    108 
    109         u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
    110         u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
    111         u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
    112 
    113         u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
    114         u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
    115         u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
    116         u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
    117 
    118         u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
    119 
    120         if (getGLXFBConfigAttrib(n, GLX_STEREO))
    121             u->stereo = GLFW_TRUE;
    122         if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
    123             u->doublebuffer = GLFW_TRUE;
    124 
    125         if (_glfw.glx.ARB_multisample)
    126             u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
    127 
    128         if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
    129             u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
    130 
    131         u->handle = (uintptr_t) n;
    132         usableCount++;
    133     }
    134 
    135     closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
    136     if (closest)
    137         *result = (GLXFBConfig) closest->handle;
    138 
    139     XFree(nativeConfigs);
    140     free(usableConfigs);
    141 
    142     return closest != NULL;
    143 }
    144 
    145 // Create the OpenGL context using legacy API
    146 //
    147 static GLXContext createLegacyContextGLX(_GLFWwindow* window,
    148                                          GLXFBConfig fbconfig,
    149                                          GLXContext share)
    150 {
    151     return glXCreateNewContext(_glfw.x11.display,
    152                                fbconfig,
    153                                GLX_RGBA_TYPE,
    154                                share,
    155                                True);
    156 }
    157 
    158 static void makeContextCurrentGLX(_GLFWwindow* window)
    159 {
    160     if (window)
    161     {
    162         if (!glXMakeCurrent(_glfw.x11.display,
    163                             window->context.glx.window,
    164                             window->context.glx.handle))
    165         {
    166             _glfwInputError(GLFW_PLATFORM_ERROR,
    167                             "GLX: Failed to make context current");
    168             return;
    169         }
    170     }
    171     else
    172     {
    173         if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
    174         {
    175             _glfwInputError(GLFW_PLATFORM_ERROR,
    176                             "GLX: Failed to clear current context");
    177             return;
    178         }
    179     }
    180 
    181     _glfwPlatformSetTls(&_glfw.contextSlot, window);
    182 }
    183 
    184 static void swapBuffersGLX(_GLFWwindow* window)
    185 {
    186     glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
    187 }
    188 
    189 static void swapIntervalGLX(int interval)
    190 {
    191     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
    192 
    193     if (_glfw.glx.EXT_swap_control)
    194     {
    195         _glfw.glx.SwapIntervalEXT(_glfw.x11.display,
    196                                   window->context.glx.window,
    197                                   interval);
    198     }
    199     else if (_glfw.glx.MESA_swap_control)
    200         _glfw.glx.SwapIntervalMESA(interval);
    201     else if (_glfw.glx.SGI_swap_control)
    202     {
    203         if (interval > 0)
    204             _glfw.glx.SwapIntervalSGI(interval);
    205     }
    206 }
    207 
    208 static int extensionSupportedGLX(const char* extension)
    209 {
    210     const char* extensions =
    211         glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
    212     if (extensions)
    213     {
    214         if (_glfwStringInExtensionString(extension, extensions))
    215             return GLFW_TRUE;
    216     }
    217 
    218     return GLFW_FALSE;
    219 }
    220 
    221 static GLFWglproc getProcAddressGLX(const char* procname)
    222 {
    223     if (_glfw.glx.GetProcAddress)
    224         return _glfw.glx.GetProcAddress((const GLubyte*) procname);
    225     else if (_glfw.glx.GetProcAddressARB)
    226         return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
    227     else
    228         return _glfw_dlsym(_glfw.glx.handle, procname);
    229 }
    230 
    231 static void destroyContextGLX(_GLFWwindow* window)
    232 {
    233     if (window->context.glx.window)
    234     {
    235         glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
    236         window->context.glx.window = None;
    237     }
    238 
    239     if (window->context.glx.handle)
    240     {
    241         glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
    242         window->context.glx.handle = NULL;
    243     }
    244 }
    245 
    246 
    247 //////////////////////////////////////////////////////////////////////////
    248 //////                       GLFW internal API                      //////
    249 //////////////////////////////////////////////////////////////////////////
    250 
    251 // Initialize GLX
    252 //
    253 GLFWbool _glfwInitGLX(void)
    254 {
    255     int i;
    256     const char* sonames[] =
    257     {
    258 #if defined(_GLFW_GLX_LIBRARY)
    259         _GLFW_GLX_LIBRARY,
    260 #elif defined(__CYGWIN__)
    261         "libGL-1.so",
    262 #else
    263         "libGL.so.1",
    264         "libGL.so",
    265 #endif
    266         NULL
    267     };
    268 
    269     if (_glfw.glx.handle)
    270         return GLFW_TRUE;
    271 
    272     for (i = 0;  sonames[i];  i++)
    273     {
    274         _glfw.glx.handle = _glfw_dlopen(sonames[i]);
    275         if (_glfw.glx.handle)
    276             break;
    277     }
    278 
    279     if (!_glfw.glx.handle)
    280     {
    281         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
    282         return GLFW_FALSE;
    283     }
    284 
    285     _glfw.glx.GetFBConfigs =
    286         _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
    287     _glfw.glx.GetFBConfigAttrib =
    288         _glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
    289     _glfw.glx.GetClientString =
    290         _glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
    291     _glfw.glx.QueryExtension =
    292         _glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
    293     _glfw.glx.QueryVersion =
    294         _glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
    295     _glfw.glx.DestroyContext =
    296         _glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
    297     _glfw.glx.MakeCurrent =
    298         _glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
    299     _glfw.glx.SwapBuffers =
    300         _glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
    301     _glfw.glx.QueryExtensionsString =
    302         _glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
    303     _glfw.glx.CreateNewContext =
    304         _glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
    305     _glfw.glx.CreateWindow =
    306         _glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
    307     _glfw.glx.DestroyWindow =
    308         _glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
    309     _glfw.glx.GetProcAddress =
    310         _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
    311     _glfw.glx.GetProcAddressARB =
    312         _glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
    313     _glfw.glx.GetVisualFromFBConfig =
    314         _glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
    315 
    316     if (!_glfw.glx.GetFBConfigs ||
    317         !_glfw.glx.GetFBConfigAttrib ||
    318         !_glfw.glx.GetClientString ||
    319         !_glfw.glx.QueryExtension ||
    320         !_glfw.glx.QueryVersion ||
    321         !_glfw.glx.DestroyContext ||
    322         !_glfw.glx.MakeCurrent ||
    323         !_glfw.glx.SwapBuffers ||
    324         !_glfw.glx.QueryExtensionsString ||
    325         !_glfw.glx.CreateNewContext ||
    326         !_glfw.glx.CreateWindow ||
    327         !_glfw.glx.DestroyWindow ||
    328         !_glfw.glx.GetProcAddress ||
    329         !_glfw.glx.GetProcAddressARB ||
    330         !_glfw.glx.GetVisualFromFBConfig)
    331     {
    332         _glfwInputError(GLFW_PLATFORM_ERROR,
    333                         "GLX: Failed to load required entry points");
    334         return GLFW_FALSE;
    335     }
    336 
    337     if (!glXQueryExtension(_glfw.x11.display,
    338                            &_glfw.glx.errorBase,
    339                            &_glfw.glx.eventBase))
    340     {
    341         _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
    342         return GLFW_FALSE;
    343     }
    344 
    345     if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
    346     {
    347         _glfwInputError(GLFW_API_UNAVAILABLE,
    348                         "GLX: Failed to query GLX version");
    349         return GLFW_FALSE;
    350     }
    351 
    352     if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
    353     {
    354         _glfwInputError(GLFW_API_UNAVAILABLE,
    355                         "GLX: GLX version 1.3 is required");
    356         return GLFW_FALSE;
    357     }
    358 
    359     if (extensionSupportedGLX("GLX_EXT_swap_control"))
    360     {
    361         _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
    362             getProcAddressGLX("glXSwapIntervalEXT");
    363 
    364         if (_glfw.glx.SwapIntervalEXT)
    365             _glfw.glx.EXT_swap_control = GLFW_TRUE;
    366     }
    367 
    368     if (extensionSupportedGLX("GLX_SGI_swap_control"))
    369     {
    370         _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
    371             getProcAddressGLX("glXSwapIntervalSGI");
    372 
    373         if (_glfw.glx.SwapIntervalSGI)
    374             _glfw.glx.SGI_swap_control = GLFW_TRUE;
    375     }
    376 
    377     if (extensionSupportedGLX("GLX_MESA_swap_control"))
    378     {
    379         _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
    380             getProcAddressGLX("glXSwapIntervalMESA");
    381 
    382         if (_glfw.glx.SwapIntervalMESA)
    383             _glfw.glx.MESA_swap_control = GLFW_TRUE;
    384     }
    385 
    386     if (extensionSupportedGLX("GLX_ARB_multisample"))
    387         _glfw.glx.ARB_multisample = GLFW_TRUE;
    388 
    389     if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
    390         _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
    391 
    392     if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
    393         _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
    394 
    395     if (extensionSupportedGLX("GLX_ARB_create_context"))
    396     {
    397         _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
    398             getProcAddressGLX("glXCreateContextAttribsARB");
    399 
    400         if (_glfw.glx.CreateContextAttribsARB)
    401             _glfw.glx.ARB_create_context = GLFW_TRUE;
    402     }
    403 
    404     if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
    405         _glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
    406 
    407     if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
    408         _glfw.glx.ARB_create_context_profile = GLFW_TRUE;
    409 
    410     if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
    411         _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
    412 
    413     if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
    414         _glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
    415 
    416     if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
    417         _glfw.glx.ARB_context_flush_control = GLFW_TRUE;
    418 
    419     return GLFW_TRUE;
    420 }
    421 
    422 // Terminate GLX
    423 //
    424 void _glfwTerminateGLX(void)
    425 {
    426     // NOTE: This function must not call any X11 functions, as it is called
    427     //       after XCloseDisplay (see _glfwPlatformTerminate for details)
    428 
    429     if (_glfw.glx.handle)
    430     {
    431         _glfw_dlclose(_glfw.glx.handle);
    432         _glfw.glx.handle = NULL;
    433     }
    434 }
    435 
    436 #define setAttrib(a, v) \
    437 { \
    438     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
    439     attribs[index++] = a; \
    440     attribs[index++] = v; \
    441 }
    442 
    443 // Create the OpenGL or OpenGL ES context
    444 //
    445 GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
    446                                const _GLFWctxconfig* ctxconfig,
    447                                const _GLFWfbconfig* fbconfig)
    448 {
    449     int attribs[40];
    450     GLXFBConfig native = NULL;
    451     GLXContext share = NULL;
    452 
    453     if (ctxconfig->share)
    454         share = ctxconfig->share->context.glx.handle;
    455 
    456     if (!chooseGLXFBConfig(fbconfig, &native))
    457     {
    458         _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
    459                         "GLX: Failed to find a suitable GLXFBConfig");
    460         return GLFW_FALSE;
    461     }
    462 
    463     if (ctxconfig->client == GLFW_OPENGL_ES_API)
    464     {
    465         if (!_glfw.glx.ARB_create_context ||
    466             !_glfw.glx.ARB_create_context_profile ||
    467             !_glfw.glx.EXT_create_context_es2_profile)
    468         {
    469             _glfwInputError(GLFW_API_UNAVAILABLE,
    470                             "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
    471             return GLFW_FALSE;
    472         }
    473     }
    474 
    475     if (ctxconfig->forward)
    476     {
    477         if (!_glfw.glx.ARB_create_context)
    478         {
    479             _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    480                             "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
    481             return GLFW_FALSE;
    482         }
    483     }
    484 
    485     if (ctxconfig->profile)
    486     {
    487         if (!_glfw.glx.ARB_create_context ||
    488             !_glfw.glx.ARB_create_context_profile)
    489         {
    490             _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    491                             "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
    492             return GLFW_FALSE;
    493         }
    494     }
    495 
    496     _glfwGrabErrorHandlerX11();
    497 
    498     if (_glfw.glx.ARB_create_context)
    499     {
    500         int index = 0, mask = 0, flags = 0;
    501 
    502         if (ctxconfig->client == GLFW_OPENGL_API)
    503         {
    504             if (ctxconfig->forward)
    505                 flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
    506 
    507             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
    508                 mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
    509             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
    510                 mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
    511         }
    512         else
    513             mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
    514 
    515         if (ctxconfig->debug)
    516             flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
    517 
    518         if (ctxconfig->robustness)
    519         {
    520             if (_glfw.glx.ARB_create_context_robustness)
    521             {
    522                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
    523                 {
    524                     setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
    525                               GLX_NO_RESET_NOTIFICATION_ARB);
    526                 }
    527                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
    528                 {
    529                     setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
    530                               GLX_LOSE_CONTEXT_ON_RESET_ARB);
    531                 }
    532 
    533                 flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
    534             }
    535         }
    536 
    537         if (ctxconfig->release)
    538         {
    539             if (_glfw.glx.ARB_context_flush_control)
    540             {
    541                 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
    542                 {
    543                     setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
    544                               GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
    545                 }
    546                 else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
    547                 {
    548                     setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
    549                               GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
    550                 }
    551             }
    552         }
    553 
    554         if (ctxconfig->noerror)
    555         {
    556             if (_glfw.glx.ARB_create_context_no_error)
    557                 setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
    558         }
    559 
    560         // NOTE: Only request an explicitly versioned context when necessary, as
    561         //       explicitly requesting version 1.0 does not always return the
    562         //       highest version supported by the driver
    563         if (ctxconfig->major != 1 || ctxconfig->minor != 0)
    564         {
    565             setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
    566             setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
    567         }
    568 
    569         if (mask)
    570             setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
    571 
    572         if (flags)
    573             setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
    574 
    575         setAttrib(None, None);
    576 
    577         window->context.glx.handle =
    578             _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
    579                                               native,
    580                                               share,
    581                                               True,
    582                                               attribs);
    583 
    584         // HACK: This is a fallback for broken versions of the Mesa
    585         //       implementation of GLX_ARB_create_context_profile that fail
    586         //       default 1.0 context creation with a GLXBadProfileARB error in
    587         //       violation of the extension spec
    588         if (!window->context.glx.handle)
    589         {
    590             if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
    591                 ctxconfig->client == GLFW_OPENGL_API &&
    592                 ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
    593                 ctxconfig->forward == GLFW_FALSE)
    594             {
    595                 window->context.glx.handle =
    596                     createLegacyContextGLX(window, native, share);
    597             }
    598         }
    599     }
    600     else
    601     {
    602         window->context.glx.handle =
    603             createLegacyContextGLX(window, native, share);
    604     }
    605 
    606     _glfwReleaseErrorHandlerX11();
    607 
    608     if (!window->context.glx.handle)
    609     {
    610         _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
    611         return GLFW_FALSE;
    612     }
    613 
    614     window->context.glx.window =
    615         glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
    616     if (!window->context.glx.window)
    617     {
    618         _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
    619         return GLFW_FALSE;
    620     }
    621 
    622     window->context.makeCurrent = makeContextCurrentGLX;
    623     window->context.swapBuffers = swapBuffersGLX;
    624     window->context.swapInterval = swapIntervalGLX;
    625     window->context.extensionSupported = extensionSupportedGLX;
    626     window->context.getProcAddress = getProcAddressGLX;
    627     window->context.destroy = destroyContextGLX;
    628 
    629     return GLFW_TRUE;
    630 }
    631 
    632 #undef setAttrib
    633 
    634 // Returns the Visual and depth of the chosen GLXFBConfig
    635 //
    636 GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
    637                               const _GLFWctxconfig* ctxconfig,
    638                               const _GLFWfbconfig* fbconfig,
    639                               Visual** visual, int* depth)
    640 {
    641     GLXFBConfig native;
    642     XVisualInfo* result;
    643 
    644     if (!chooseGLXFBConfig(fbconfig, &native))
    645     {
    646         _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
    647                         "GLX: Failed to find a suitable GLXFBConfig");
    648         return GLFW_FALSE;
    649     }
    650 
    651     result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
    652     if (!result)
    653     {
    654         _glfwInputError(GLFW_PLATFORM_ERROR,
    655                         "GLX: Failed to retrieve Visual for GLXFBConfig");
    656         return GLFW_FALSE;
    657     }
    658 
    659     *visual = result->visual;
    660     *depth  = result->depth;
    661 
    662     XFree(result);
    663     return GLFW_TRUE;
    664 }
    665 
    666 
    667 //////////////////////////////////////////////////////////////////////////
    668 //////                        GLFW native API                       //////
    669 //////////////////////////////////////////////////////////////////////////
    670 
    671 GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
    672 {
    673     _GLFWwindow* window = (_GLFWwindow*) handle;
    674     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    675 
    676     if (window->context.client == GLFW_NO_API)
    677     {
    678         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
    679         return NULL;
    680     }
    681 
    682     return window->context.glx.handle;
    683 }
    684 
    685 GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
    686 {
    687     _GLFWwindow* window = (_GLFWwindow*) handle;
    688     _GLFW_REQUIRE_INIT_OR_RETURN(None);
    689 
    690     if (window->context.client == GLFW_NO_API)
    691     {
    692         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
    693         return None;
    694     }
    695 
    696     return window->context.glx.window;
    697 }
    698