twitchapon-anim

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

wgl_context.c (26927B)


      1 //========================================================================
      2 // GLFW 3.3 WGL - 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 // Please use C89 style variable declarations in this file because VS 2010
     28 //========================================================================
     29 
     30 #include "internal.h"
     31 
     32 #include <stdlib.h>
     33 #include <malloc.h>
     34 #include <assert.h>
     35 
     36 // Return the value corresponding to the specified attribute
     37 //
     38 static int findPixelFormatAttribValue(const int* attribs,
     39                                       int attribCount,
     40                                       const int* values,
     41                                       int attrib)
     42 {
     43     int i;
     44 
     45     for (i = 0;  i < attribCount;  i++)
     46     {
     47         if (attribs[i] == attrib)
     48             return values[i];
     49     }
     50 
     51     _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
     52                          "WGL: Unknown pixel format attribute requested");
     53     return 0;
     54 }
     55 
     56 #define addAttrib(a) \
     57 { \
     58     assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
     59     attribs[attribCount++] = a; \
     60 }
     61 #define findAttribValue(a) \
     62     findPixelFormatAttribValue(attribs, attribCount, values, a)
     63 
     64 // Return a list of available and usable framebuffer configs
     65 //
     66 static int choosePixelFormat(_GLFWwindow* window,
     67                              const _GLFWctxconfig* ctxconfig,
     68                              const _GLFWfbconfig* fbconfig)
     69 {
     70     _GLFWfbconfig* usableConfigs;
     71     const _GLFWfbconfig* closest;
     72     int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0;
     73     int attribs[40];
     74     int values[sizeof(attribs) / sizeof(attribs[0])];
     75 
     76     if (_glfw.wgl.ARB_pixel_format)
     77     {
     78         const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
     79 
     80         if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
     81                                           1, 0, 1, &attrib, &nativeCount))
     82         {
     83             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
     84                                  "WGL: Failed to retrieve pixel format attribute");
     85             return 0;
     86         }
     87 
     88         addAttrib(WGL_SUPPORT_OPENGL_ARB);
     89         addAttrib(WGL_DRAW_TO_WINDOW_ARB);
     90         addAttrib(WGL_PIXEL_TYPE_ARB);
     91         addAttrib(WGL_ACCELERATION_ARB);
     92         addAttrib(WGL_RED_BITS_ARB);
     93         addAttrib(WGL_RED_SHIFT_ARB);
     94         addAttrib(WGL_GREEN_BITS_ARB);
     95         addAttrib(WGL_GREEN_SHIFT_ARB);
     96         addAttrib(WGL_BLUE_BITS_ARB);
     97         addAttrib(WGL_BLUE_SHIFT_ARB);
     98         addAttrib(WGL_ALPHA_BITS_ARB);
     99         addAttrib(WGL_ALPHA_SHIFT_ARB);
    100         addAttrib(WGL_DEPTH_BITS_ARB);
    101         addAttrib(WGL_STENCIL_BITS_ARB);
    102         addAttrib(WGL_ACCUM_BITS_ARB);
    103         addAttrib(WGL_ACCUM_RED_BITS_ARB);
    104         addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
    105         addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
    106         addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
    107         addAttrib(WGL_AUX_BUFFERS_ARB);
    108         addAttrib(WGL_STEREO_ARB);
    109         addAttrib(WGL_DOUBLE_BUFFER_ARB);
    110 
    111         if (_glfw.wgl.ARB_multisample)
    112             addAttrib(WGL_SAMPLES_ARB);
    113 
    114         if (ctxconfig->client == GLFW_OPENGL_API)
    115         {
    116             if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
    117                 addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
    118         }
    119         else
    120         {
    121             if (_glfw.wgl.EXT_colorspace)
    122                 addAttrib(WGL_COLORSPACE_EXT);
    123         }
    124     }
    125     else
    126     {
    127         nativeCount = DescribePixelFormat(window->context.wgl.dc,
    128                                           1,
    129                                           sizeof(PIXELFORMATDESCRIPTOR),
    130                                           NULL);
    131     }
    132 
    133     usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
    134 
    135     for (i = 0;  i < nativeCount;  i++)
    136     {
    137         _GLFWfbconfig* u = usableConfigs + usableCount;
    138         pixelFormat = i + 1;
    139 
    140         if (_glfw.wgl.ARB_pixel_format)
    141         {
    142             // Get pixel format attributes through "modern" extension
    143 
    144             if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
    145                                               pixelFormat, 0,
    146                                               attribCount,
    147                                               attribs, values))
    148             {
    149                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    150                                     "WGL: Failed to retrieve pixel format attributes");
    151 
    152                 free(usableConfigs);
    153                 return 0;
    154             }
    155 
    156             if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) ||
    157                 !findAttribValue(WGL_DRAW_TO_WINDOW_ARB))
    158             {
    159                 continue;
    160             }
    161 
    162             if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
    163                 continue;
    164 
    165             if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
    166                 continue;
    167 
    168             u->redBits = findAttribValue(WGL_RED_BITS_ARB);
    169             u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB);
    170             u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB);
    171             u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB);
    172 
    173             u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB);
    174             u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB);
    175 
    176             u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB);
    177             u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB);
    178             u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB);
    179             u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB);
    180 
    181             u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB);
    182 
    183             if (findAttribValue(WGL_STEREO_ARB))
    184                 u->stereo = GLFW_TRUE;
    185             if (findAttribValue(WGL_DOUBLE_BUFFER_ARB))
    186                 u->doublebuffer = GLFW_TRUE;
    187 
    188             if (_glfw.wgl.ARB_multisample)
    189                 u->samples = findAttribValue(WGL_SAMPLES_ARB);
    190 
    191             if (ctxconfig->client == GLFW_OPENGL_API)
    192             {
    193                 if (_glfw.wgl.ARB_framebuffer_sRGB ||
    194                     _glfw.wgl.EXT_framebuffer_sRGB)
    195                 {
    196                     if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
    197                         u->sRGB = GLFW_TRUE;
    198                 }
    199             }
    200             else
    201             {
    202                 if (_glfw.wgl.EXT_colorspace)
    203                 {
    204                     if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
    205                         u->sRGB = GLFW_TRUE;
    206                 }
    207             }
    208         }
    209         else
    210         {
    211             // Get pixel format attributes through legacy PFDs
    212 
    213             PIXELFORMATDESCRIPTOR pfd;
    214 
    215             if (!DescribePixelFormat(window->context.wgl.dc,
    216                                      pixelFormat,
    217                                      sizeof(PIXELFORMATDESCRIPTOR),
    218                                      &pfd))
    219             {
    220                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    221                                     "WGL: Failed to describe pixel format");
    222 
    223                 free(usableConfigs);
    224                 return 0;
    225             }
    226 
    227             if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
    228                 !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
    229             {
    230                 continue;
    231             }
    232 
    233             if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
    234                 (pfd.dwFlags & PFD_GENERIC_FORMAT))
    235             {
    236                 continue;
    237             }
    238 
    239             if (pfd.iPixelType != PFD_TYPE_RGBA)
    240                 continue;
    241 
    242             u->redBits = pfd.cRedBits;
    243             u->greenBits = pfd.cGreenBits;
    244             u->blueBits = pfd.cBlueBits;
    245             u->alphaBits = pfd.cAlphaBits;
    246 
    247             u->depthBits = pfd.cDepthBits;
    248             u->stencilBits = pfd.cStencilBits;
    249 
    250             u->accumRedBits = pfd.cAccumRedBits;
    251             u->accumGreenBits = pfd.cAccumGreenBits;
    252             u->accumBlueBits = pfd.cAccumBlueBits;
    253             u->accumAlphaBits = pfd.cAccumAlphaBits;
    254 
    255             u->auxBuffers = pfd.cAuxBuffers;
    256 
    257             if (pfd.dwFlags & PFD_STEREO)
    258                 u->stereo = GLFW_TRUE;
    259             if (pfd.dwFlags & PFD_DOUBLEBUFFER)
    260                 u->doublebuffer = GLFW_TRUE;
    261         }
    262 
    263         u->handle = pixelFormat;
    264         usableCount++;
    265     }
    266 
    267     if (!usableCount)
    268     {
    269         _glfwInputError(GLFW_API_UNAVAILABLE,
    270                         "WGL: The driver does not appear to support OpenGL");
    271 
    272         free(usableConfigs);
    273         return 0;
    274     }
    275 
    276     closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
    277     if (!closest)
    278     {
    279         _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
    280                         "WGL: Failed to find a suitable pixel format");
    281 
    282         free(usableConfigs);
    283         return 0;
    284     }
    285 
    286     pixelFormat = (int) closest->handle;
    287     free(usableConfigs);
    288 
    289     return pixelFormat;
    290 }
    291 
    292 #undef addAttrib
    293 #undef findAttribValue
    294 
    295 static void makeContextCurrentWGL(_GLFWwindow* window)
    296 {
    297     if (window)
    298     {
    299         if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
    300             _glfwPlatformSetTls(&_glfw.contextSlot, window);
    301         else
    302         {
    303             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    304                                  "WGL: Failed to make context current");
    305             _glfwPlatformSetTls(&_glfw.contextSlot, NULL);
    306         }
    307     }
    308     else
    309     {
    310         if (!wglMakeCurrent(NULL, NULL))
    311         {
    312             _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    313                                  "WGL: Failed to clear current context");
    314         }
    315 
    316         _glfwPlatformSetTls(&_glfw.contextSlot, NULL);
    317     }
    318 }
    319 
    320 static void swapBuffersWGL(_GLFWwindow* window)
    321 {
    322     if (!window->monitor)
    323     {
    324         if (IsWindowsVistaOrGreater())
    325         {
    326             // DWM Composition is always enabled on Win8+
    327             BOOL enabled = IsWindows8OrGreater();
    328 
    329             // HACK: Use DwmFlush when desktop composition is enabled
    330             if (enabled ||
    331                 (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
    332             {
    333                 int count = abs(window->context.wgl.interval);
    334                 while (count--)
    335                     DwmFlush();
    336             }
    337         }
    338     }
    339 
    340     SwapBuffers(window->context.wgl.dc);
    341 }
    342 
    343 static void swapIntervalWGL(int interval)
    344 {
    345     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
    346 
    347     window->context.wgl.interval = interval;
    348 
    349     if (!window->monitor)
    350     {
    351         if (IsWindowsVistaOrGreater())
    352         {
    353             // DWM Composition is always enabled on Win8+
    354             BOOL enabled = IsWindows8OrGreater();
    355 
    356             // HACK: Disable WGL swap interval when desktop composition is enabled to
    357             //       avoid interfering with DWM vsync
    358             if (enabled ||
    359                 (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
    360                 interval = 0;
    361         }
    362     }
    363 
    364     if (_glfw.wgl.EXT_swap_control)
    365         wglSwapIntervalEXT(interval);
    366 }
    367 
    368 static int extensionSupportedWGL(const char* extension)
    369 {
    370     const char* extensions = NULL;
    371 
    372     if (_glfw.wgl.GetExtensionsStringARB)
    373         extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
    374     else if (_glfw.wgl.GetExtensionsStringEXT)
    375         extensions = wglGetExtensionsStringEXT();
    376 
    377     if (!extensions)
    378         return GLFW_FALSE;
    379 
    380     return _glfwStringInExtensionString(extension, extensions);
    381 }
    382 
    383 static GLFWglproc getProcAddressWGL(const char* procname)
    384 {
    385     const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
    386     if (proc)
    387         return proc;
    388 
    389     return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
    390 }
    391 
    392 static void destroyContextWGL(_GLFWwindow* window)
    393 {
    394     if (window->context.wgl.handle)
    395     {
    396         wglDeleteContext(window->context.wgl.handle);
    397         window->context.wgl.handle = NULL;
    398     }
    399 }
    400 
    401 
    402 //////////////////////////////////////////////////////////////////////////
    403 //////                       GLFW internal API                      //////
    404 //////////////////////////////////////////////////////////////////////////
    405 
    406 // Initialize WGL
    407 //
    408 GLFWbool _glfwInitWGL(void)
    409 {
    410     PIXELFORMATDESCRIPTOR pfd;
    411     HGLRC prc, rc;
    412     HDC pdc, dc;
    413 
    414     if (_glfw.wgl.instance)
    415         return GLFW_TRUE;
    416 
    417     _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
    418     if (!_glfw.wgl.instance)
    419     {
    420         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    421                              "WGL: Failed to load opengl32.dll");
    422         return GLFW_FALSE;
    423     }
    424 
    425     _glfw.wgl.CreateContext = (PFN_wglCreateContext)
    426         GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
    427     _glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
    428         GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
    429     _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
    430         GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
    431     _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
    432         GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
    433     _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
    434         GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
    435     _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
    436         GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
    437     _glfw.wgl.ShareLists = (PFN_wglShareLists)
    438         GetProcAddress(_glfw.wgl.instance, "wglShareLists");
    439 
    440     // NOTE: A dummy context has to be created for opengl32.dll to load the
    441     //       OpenGL ICD, from which we can then query WGL extensions
    442     // NOTE: This code will accept the Microsoft GDI ICD; accelerated context
    443     //       creation failure occurs during manual pixel format enumeration
    444 
    445     dc = GetDC(_glfw.win32.helperWindowHandle);
    446 
    447     ZeroMemory(&pfd, sizeof(pfd));
    448     pfd.nSize = sizeof(pfd);
    449     pfd.nVersion = 1;
    450     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    451     pfd.iPixelType = PFD_TYPE_RGBA;
    452     pfd.cColorBits = 24;
    453 
    454     if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
    455     {
    456         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    457                              "WGL: Failed to set pixel format for dummy context");
    458         return GLFW_FALSE;
    459     }
    460 
    461     rc = wglCreateContext(dc);
    462     if (!rc)
    463     {
    464         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    465                              "WGL: Failed to create dummy context");
    466         return GLFW_FALSE;
    467     }
    468 
    469     pdc = wglGetCurrentDC();
    470     prc = wglGetCurrentContext();
    471 
    472     if (!wglMakeCurrent(dc, rc))
    473     {
    474         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    475                              "WGL: Failed to make dummy context current");
    476         wglMakeCurrent(pdc, prc);
    477         wglDeleteContext(rc);
    478         return GLFW_FALSE;
    479     }
    480 
    481     // NOTE: Functions must be loaded first as they're needed to retrieve the
    482     //       extension string that tells us whether the functions are supported
    483     _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
    484         wglGetProcAddress("wglGetExtensionsStringEXT");
    485     _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
    486         wglGetProcAddress("wglGetExtensionsStringARB");
    487     _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
    488         wglGetProcAddress("wglCreateContextAttribsARB");
    489     _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
    490         wglGetProcAddress("wglSwapIntervalEXT");
    491     _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
    492         wglGetProcAddress("wglGetPixelFormatAttribivARB");
    493 
    494     // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
    495     //       checked below as we are already using them
    496     _glfw.wgl.ARB_multisample =
    497         extensionSupportedWGL("WGL_ARB_multisample");
    498     _glfw.wgl.ARB_framebuffer_sRGB =
    499         extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
    500     _glfw.wgl.EXT_framebuffer_sRGB =
    501         extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
    502     _glfw.wgl.ARB_create_context =
    503         extensionSupportedWGL("WGL_ARB_create_context");
    504     _glfw.wgl.ARB_create_context_profile =
    505         extensionSupportedWGL("WGL_ARB_create_context_profile");
    506     _glfw.wgl.EXT_create_context_es2_profile =
    507         extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
    508     _glfw.wgl.ARB_create_context_robustness =
    509         extensionSupportedWGL("WGL_ARB_create_context_robustness");
    510     _glfw.wgl.ARB_create_context_no_error =
    511         extensionSupportedWGL("WGL_ARB_create_context_no_error");
    512     _glfw.wgl.EXT_swap_control =
    513         extensionSupportedWGL("WGL_EXT_swap_control");
    514     _glfw.wgl.EXT_colorspace =
    515         extensionSupportedWGL("WGL_EXT_colorspace");
    516     _glfw.wgl.ARB_pixel_format =
    517         extensionSupportedWGL("WGL_ARB_pixel_format");
    518     _glfw.wgl.ARB_context_flush_control =
    519         extensionSupportedWGL("WGL_ARB_context_flush_control");
    520 
    521     wglMakeCurrent(pdc, prc);
    522     wglDeleteContext(rc);
    523     return GLFW_TRUE;
    524 }
    525 
    526 // Terminate WGL
    527 //
    528 void _glfwTerminateWGL(void)
    529 {
    530     if (_glfw.wgl.instance)
    531         FreeLibrary(_glfw.wgl.instance);
    532 }
    533 
    534 #define setAttrib(a, v) \
    535 { \
    536     assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
    537     attribs[index++] = a; \
    538     attribs[index++] = v; \
    539 }
    540 
    541 // Create the OpenGL or OpenGL ES context
    542 //
    543 GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
    544                                const _GLFWctxconfig* ctxconfig,
    545                                const _GLFWfbconfig* fbconfig)
    546 {
    547     int attribs[40];
    548     int pixelFormat;
    549     PIXELFORMATDESCRIPTOR pfd;
    550     HGLRC share = NULL;
    551 
    552     if (ctxconfig->share)
    553         share = ctxconfig->share->context.wgl.handle;
    554 
    555     window->context.wgl.dc = GetDC(window->win32.handle);
    556     if (!window->context.wgl.dc)
    557     {
    558         _glfwInputError(GLFW_PLATFORM_ERROR,
    559                         "WGL: Failed to retrieve DC for window");
    560         return GLFW_FALSE;
    561     }
    562 
    563     pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
    564     if (!pixelFormat)
    565         return GLFW_FALSE;
    566 
    567     if (!DescribePixelFormat(window->context.wgl.dc,
    568                              pixelFormat, sizeof(pfd), &pfd))
    569     {
    570         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    571                              "WGL: Failed to retrieve PFD for selected pixel format");
    572         return GLFW_FALSE;
    573     }
    574 
    575     if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
    576     {
    577         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    578                              "WGL: Failed to set selected pixel format");
    579         return GLFW_FALSE;
    580     }
    581 
    582     if (ctxconfig->client == GLFW_OPENGL_API)
    583     {
    584         if (ctxconfig->forward)
    585         {
    586             if (!_glfw.wgl.ARB_create_context)
    587             {
    588                 _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    589                                 "WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
    590                 return GLFW_FALSE;
    591             }
    592         }
    593 
    594         if (ctxconfig->profile)
    595         {
    596             if (!_glfw.wgl.ARB_create_context_profile)
    597             {
    598                 _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    599                                 "WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
    600                 return GLFW_FALSE;
    601             }
    602         }
    603     }
    604     else
    605     {
    606         if (!_glfw.wgl.ARB_create_context ||
    607             !_glfw.wgl.ARB_create_context_profile ||
    608             !_glfw.wgl.EXT_create_context_es2_profile)
    609         {
    610             _glfwInputError(GLFW_API_UNAVAILABLE,
    611                             "WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
    612             return GLFW_FALSE;
    613         }
    614     }
    615 
    616     if (_glfw.wgl.ARB_create_context)
    617     {
    618         int index = 0, mask = 0, flags = 0;
    619 
    620         if (ctxconfig->client == GLFW_OPENGL_API)
    621         {
    622             if (ctxconfig->forward)
    623                 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
    624 
    625             if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
    626                 mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
    627             else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
    628                 mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
    629         }
    630         else
    631             mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
    632 
    633         if (ctxconfig->debug)
    634             flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
    635 
    636         if (ctxconfig->robustness)
    637         {
    638             if (_glfw.wgl.ARB_create_context_robustness)
    639             {
    640                 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
    641                 {
    642                     setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
    643                               WGL_NO_RESET_NOTIFICATION_ARB);
    644                 }
    645                 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
    646                 {
    647                     setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
    648                               WGL_LOSE_CONTEXT_ON_RESET_ARB);
    649                 }
    650 
    651                 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
    652             }
    653         }
    654 
    655         if (ctxconfig->release)
    656         {
    657             if (_glfw.wgl.ARB_context_flush_control)
    658             {
    659                 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
    660                 {
    661                     setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
    662                               WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
    663                 }
    664                 else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
    665                 {
    666                     setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
    667                               WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
    668                 }
    669             }
    670         }
    671 
    672         if (ctxconfig->noerror)
    673         {
    674             if (_glfw.wgl.ARB_create_context_no_error)
    675                 setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
    676         }
    677 
    678         // NOTE: Only request an explicitly versioned context when necessary, as
    679         //       explicitly requesting version 1.0 does not always return the
    680         //       highest version supported by the driver
    681         if (ctxconfig->major != 1 || ctxconfig->minor != 0)
    682         {
    683             setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
    684             setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
    685         }
    686 
    687         if (flags)
    688             setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
    689 
    690         if (mask)
    691             setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
    692 
    693         setAttrib(0, 0);
    694 
    695         window->context.wgl.handle =
    696             wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
    697         if (!window->context.wgl.handle)
    698         {
    699             const DWORD error = GetLastError();
    700 
    701             if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
    702             {
    703                 if (ctxconfig->client == GLFW_OPENGL_API)
    704                 {
    705                     _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    706                                     "WGL: Driver does not support OpenGL version %i.%i",
    707                                     ctxconfig->major,
    708                                     ctxconfig->minor);
    709                 }
    710                 else
    711                 {
    712                     _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    713                                     "WGL: Driver does not support OpenGL ES version %i.%i",
    714                                     ctxconfig->major,
    715                                     ctxconfig->minor);
    716                 }
    717             }
    718             else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
    719             {
    720                 _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    721                                 "WGL: Driver does not support the requested OpenGL profile");
    722             }
    723             else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
    724             {
    725                 _glfwInputError(GLFW_INVALID_VALUE,
    726                                 "WGL: The share context is not compatible with the requested context");
    727             }
    728             else
    729             {
    730                 if (ctxconfig->client == GLFW_OPENGL_API)
    731                 {
    732                     _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    733                                     "WGL: Failed to create OpenGL context");
    734                 }
    735                 else
    736                 {
    737                     _glfwInputError(GLFW_VERSION_UNAVAILABLE,
    738                                     "WGL: Failed to create OpenGL ES context");
    739                 }
    740             }
    741 
    742             return GLFW_FALSE;
    743         }
    744     }
    745     else
    746     {
    747         window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
    748         if (!window->context.wgl.handle)
    749         {
    750             _glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
    751                                  "WGL: Failed to create OpenGL context");
    752             return GLFW_FALSE;
    753         }
    754 
    755         if (share)
    756         {
    757             if (!wglShareLists(share, window->context.wgl.handle))
    758             {
    759                 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
    760                                      "WGL: Failed to enable sharing with specified OpenGL context");
    761                 return GLFW_FALSE;
    762             }
    763         }
    764     }
    765 
    766     window->context.makeCurrent = makeContextCurrentWGL;
    767     window->context.swapBuffers = swapBuffersWGL;
    768     window->context.swapInterval = swapIntervalWGL;
    769     window->context.extensionSupported = extensionSupportedWGL;
    770     window->context.getProcAddress = getProcAddressWGL;
    771     window->context.destroy = destroyContextWGL;
    772 
    773     return GLFW_TRUE;
    774 }
    775 
    776 #undef setAttrib
    777 
    778 
    779 //////////////////////////////////////////////////////////////////////////
    780 //////                        GLFW native API                       //////
    781 //////////////////////////////////////////////////////////////////////////
    782 
    783 GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
    784 {
    785     _GLFWwindow* window = (_GLFWwindow*) handle;
    786     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    787 
    788     if (window->context.client == GLFW_NO_API)
    789     {
    790         _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
    791         return NULL;
    792     }
    793 
    794     return window->context.wgl.handle;
    795 }
    796