src/video/windows/SDL_windowsopengl.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 31 Mar 2013 12:48:50 -0400
changeset 7037 3fedf1f25b94
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Make SDL_SetError and friends unconditionally return -1.

This lets us change things like this...

if (Failed) {
SDL_SetError("We failed");
return -1;
}

...into this...

if (Failed) {
return SDL_SetError("We failed");
}


Fixes Bugzilla #1778.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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 
    23 #if SDL_VIDEO_DRIVER_WINDOWS
    24 
    25 #include "SDL_windowsvideo.h"
    26 
    27 /* WGL implementation of SDL OpenGL support */
    28 
    29 #if SDL_VIDEO_OPENGL_WGL
    30 #include "SDL_opengl.h"
    31 
    32 #define DEFAULT_OPENGL "OPENGL32.DLL"
    33 
    34 #ifndef WGL_ARB_create_context
    35 #define WGL_ARB_create_context
    36 #define WGL_CONTEXT_MAJOR_VERSION_ARB   0x2091
    37 #define WGL_CONTEXT_MINOR_VERSION_ARB   0x2092
    38 #define WGL_CONTEXT_LAYER_PLANE_ARB     0x2093
    39 #define WGL_CONTEXT_FLAGS_ARB           0x2094
    40 #define WGL_CONTEXT_DEBUG_BIT_ARB       0x0001
    41 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
    42 
    43 #ifndef WGL_ARB_create_context_profile
    44 #define WGL_ARB_create_context_profile
    45 #define WGL_CONTEXT_PROFILE_MASK_ARB              0x9126
    46 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB          0x00000001
    47 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
    48 #endif
    49 
    50 #ifndef WGL_ARB_create_context_robustness
    51 #define WGL_ARB_create_context_robustness
    52 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB         0x00000004
    53 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB     0x8256
    54 #define WGL_NO_RESET_NOTIFICATION_ARB                   0x8261
    55 #define WGL_LOSE_CONTEXT_ON_RESET_ARB                   0x8252
    56 #endif
    57 #endif
    58 
    59 #ifndef WGL_EXT_create_context_es2_profile
    60 #define WGL_EXT_create_context_es2_profile
    61 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT           0x00000004
    62 #endif
    63 
    64 #ifndef WGL_EXT_create_context_es_profile
    65 #define WGL_EXT_create_context_es_profile
    66 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT            0x00000004
    67 #endif
    68 
    69 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
    70                                                             HGLRC
    71                                                             hShareContext,
    72                                                             const int
    73                                                             *attribList);
    74 
    75 int
    76 WIN_GL_LoadLibrary(_THIS, const char *path)
    77 {
    78     LPTSTR wpath;
    79     HANDLE handle;
    80 
    81     if (path == NULL) {
    82         path = SDL_getenv("SDL_OPENGL_LIBRARY");
    83     }
    84     if (path == NULL) {
    85         path = DEFAULT_OPENGL;
    86     }
    87     wpath = WIN_UTF8ToString(path);
    88     _this->gl_config.dll_handle = LoadLibrary(wpath);
    89     SDL_free(wpath);
    90     if (!_this->gl_config.dll_handle) {
    91         char message[1024];
    92         SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
    93                      path);
    94         return WIN_SetError(message);
    95     }
    96     SDL_strlcpy(_this->gl_config.driver_path, path,
    97                 SDL_arraysize(_this->gl_config.driver_path));
    98 
    99     /* Allocate OpenGL memory */
   100     _this->gl_data =
   101         (struct SDL_GLDriverData *) SDL_calloc(1,
   102                                                sizeof(struct
   103                                                       SDL_GLDriverData));
   104     if (!_this->gl_data) {
   105         return SDL_OutOfMemory();
   106     }
   107 
   108     /* Load function pointers */
   109     handle = _this->gl_config.dll_handle;
   110     _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
   111         GetProcAddress(handle, "wglGetProcAddress");
   112     _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
   113         GetProcAddress(handle, "wglCreateContext");
   114     _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
   115         GetProcAddress(handle, "wglDeleteContext");
   116     _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
   117         GetProcAddress(handle, "wglMakeCurrent");
   118     _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
   119         GetProcAddress(handle, "wglShareLists");
   120 
   121     if (!_this->gl_data->wglGetProcAddress ||
   122         !_this->gl_data->wglCreateContext ||
   123         !_this->gl_data->wglDeleteContext ||
   124         !_this->gl_data->wglMakeCurrent) {
   125         SDL_UnloadObject(handle);
   126         return SDL_SetError("Could not retrieve OpenGL functions");
   127     }
   128 
   129     return 0;
   130 }
   131 
   132 void *
   133 WIN_GL_GetProcAddress(_THIS, const char *proc)
   134 {
   135     void *func;
   136 
   137     /* This is to pick up extensions */
   138     func = _this->gl_data->wglGetProcAddress(proc);
   139     if (!func) {
   140         /* This is probably a normal GL function */
   141         func = GetProcAddress(_this->gl_config.dll_handle, proc);
   142     }
   143     return func;
   144 }
   145 
   146 void
   147 WIN_GL_UnloadLibrary(_THIS)
   148 {
   149     FreeLibrary((HMODULE) _this->gl_config.dll_handle);
   150     _this->gl_config.dll_handle = NULL;
   151 
   152     /* Free OpenGL memory */
   153     SDL_free(_this->gl_data);
   154     _this->gl_data = NULL;
   155 }
   156 
   157 static void
   158 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
   159 {
   160     SDL_zerop(pfd);
   161     pfd->nSize = sizeof(*pfd);
   162     pfd->nVersion = 1;
   163     pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
   164     if (_this->gl_config.double_buffer) {
   165         pfd->dwFlags |= PFD_DOUBLEBUFFER;
   166     }
   167     if (_this->gl_config.stereo) {
   168         pfd->dwFlags |= PFD_STEREO;
   169     }
   170     pfd->iLayerType = PFD_MAIN_PLANE;
   171     pfd->iPixelType = PFD_TYPE_RGBA;
   172     pfd->cRedBits = _this->gl_config.red_size;
   173     pfd->cGreenBits = _this->gl_config.green_size;
   174     pfd->cBlueBits = _this->gl_config.blue_size;
   175     pfd->cAlphaBits = _this->gl_config.alpha_size;
   176     if (_this->gl_config.buffer_size) {
   177         pfd->cColorBits =
   178             _this->gl_config.buffer_size - _this->gl_config.alpha_size;
   179     } else {
   180         pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
   181     }
   182     pfd->cAccumRedBits = _this->gl_config.accum_red_size;
   183     pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
   184     pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
   185     pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
   186     pfd->cAccumBits =
   187         (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
   188          pfd->cAccumAlphaBits);
   189     pfd->cDepthBits = _this->gl_config.depth_size;
   190     pfd->cStencilBits = _this->gl_config.stencil_size;
   191 }
   192 
   193 /* Choose the closest pixel format that meets or exceeds the target.
   194    FIXME: Should we weight any particular attribute over any other?
   195 */
   196 static int
   197 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
   198 {
   199     PIXELFORMATDESCRIPTOR pfd;
   200     int count, index, best = 0;
   201     unsigned int dist, best_dist = ~0U;
   202 
   203     count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
   204 
   205     for (index = 1; index <= count; index++) {
   206 
   207         if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
   208             continue;
   209         }
   210 
   211         if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
   212             continue;
   213         }
   214 
   215         if (pfd.iLayerType != target->iLayerType) {
   216             continue;
   217         }
   218         if (pfd.iPixelType != target->iPixelType) {
   219             continue;
   220         }
   221 
   222         dist = 0;
   223 
   224         if (pfd.cColorBits < target->cColorBits) {
   225             continue;
   226         } else {
   227             dist += (pfd.cColorBits - target->cColorBits);
   228         }
   229         if (pfd.cRedBits < target->cRedBits) {
   230             continue;
   231         } else {
   232             dist += (pfd.cRedBits - target->cRedBits);
   233         }
   234         if (pfd.cGreenBits < target->cGreenBits) {
   235             continue;
   236         } else {
   237             dist += (pfd.cGreenBits - target->cGreenBits);
   238         }
   239         if (pfd.cBlueBits < target->cBlueBits) {
   240             continue;
   241         } else {
   242             dist += (pfd.cBlueBits - target->cBlueBits);
   243         }
   244         if (pfd.cAlphaBits < target->cAlphaBits) {
   245             continue;
   246         } else {
   247             dist += (pfd.cAlphaBits - target->cAlphaBits);
   248         }
   249         if (pfd.cAccumBits < target->cAccumBits) {
   250             continue;
   251         } else {
   252             dist += (pfd.cAccumBits - target->cAccumBits);
   253         }
   254         if (pfd.cAccumRedBits < target->cAccumRedBits) {
   255             continue;
   256         } else {
   257             dist += (pfd.cAccumRedBits - target->cAccumRedBits);
   258         }
   259         if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
   260             continue;
   261         } else {
   262             dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
   263         }
   264         if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
   265             continue;
   266         } else {
   267             dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
   268         }
   269         if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
   270             continue;
   271         } else {
   272             dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
   273         }
   274         if (pfd.cDepthBits < target->cDepthBits) {
   275             continue;
   276         } else {
   277             dist += (pfd.cDepthBits - target->cDepthBits);
   278         }
   279         if (pfd.cStencilBits < target->cStencilBits) {
   280             continue;
   281         } else {
   282             dist += (pfd.cStencilBits - target->cStencilBits);
   283         }
   284 
   285         if (dist < best_dist) {
   286             best = index;
   287             best_dist = dist;
   288         }
   289     }
   290 
   291     return best;
   292 }
   293 
   294 static SDL_bool
   295 HasExtension(const char *extension, const char *extensions)
   296 {
   297     const char *start;
   298     const char *where, *terminator;
   299 
   300     /* Extension names should not have spaces. */
   301     where = SDL_strchr(extension, ' ');
   302     if (where || *extension == '\0')
   303         return SDL_FALSE;
   304 
   305     if (!extensions)
   306         return SDL_FALSE;
   307 
   308     /* It takes a bit of care to be fool-proof about parsing the
   309      * OpenGL extensions string. Don't be fooled by sub-strings,
   310      * etc. */
   311 
   312     start = extensions;
   313 
   314     for (;;) {
   315         where = SDL_strstr(start, extension);
   316         if (!where)
   317             break;
   318 
   319         terminator = where + SDL_strlen(extension);
   320         if (where == start || *(where - 1) == ' ')
   321             if (*terminator == ' ' || *terminator == '\0')
   322                 return SDL_TRUE;
   323 
   324         start = terminator;
   325     }
   326     return SDL_FALSE;
   327 }
   328 
   329 static void
   330 WIN_GL_InitExtensions(_THIS, HDC hdc)
   331 {
   332     const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
   333     const char *extensions;
   334 
   335     wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
   336         _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
   337     if (wglGetExtensionsStringARB) {
   338         extensions = wglGetExtensionsStringARB(hdc);
   339     } else {
   340         extensions = NULL;
   341     }
   342 
   343     /* Check for WGL_ARB_pixel_format */
   344     _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
   345     if (HasExtension("WGL_ARB_pixel_format", extensions)) {
   346         _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
   347                                                    (HDC, const int *,
   348                                                     const FLOAT *, UINT,
   349                                                     int *, UINT *))
   350             WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
   351         _this->gl_data->wglGetPixelFormatAttribivARB =
   352             (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
   353             WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
   354 
   355         if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
   356             (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
   357             _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
   358         }
   359     }
   360 
   361     /* Check for WGL_EXT_swap_control */
   362     _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
   363     if (HasExtension("WGL_EXT_swap_control", extensions)) {
   364         _this->gl_data->wglSwapIntervalEXT =
   365             WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
   366         _this->gl_data->wglGetSwapIntervalEXT =
   367             WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
   368         if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
   369             _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
   370         }
   371     } else {
   372         _this->gl_data->wglSwapIntervalEXT = NULL;
   373         _this->gl_data->wglGetSwapIntervalEXT = NULL;
   374     }
   375 }
   376 
   377 static int
   378 WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
   379 {
   380     HWND hwnd;
   381     HDC hdc;
   382     PIXELFORMATDESCRIPTOR pfd;
   383     HGLRC hglrc;
   384     int pixel_format = 0;
   385     unsigned int matching;
   386 
   387     hwnd =
   388         CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
   389                      10, 10, NULL, NULL, SDL_Instance, NULL);
   390     WIN_PumpEvents(_this);
   391 
   392     hdc = GetDC(hwnd);
   393 
   394     WIN_GL_SetupPixelFormat(_this, &pfd);
   395 
   396     SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
   397 
   398     hglrc = _this->gl_data->wglCreateContext(hdc);
   399     if (hglrc) {
   400         _this->gl_data->wglMakeCurrent(hdc, hglrc);
   401 
   402         WIN_GL_InitExtensions(_this, hdc);
   403 
   404         if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
   405             _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
   406                                                     1, &pixel_format,
   407                                                     &matching);
   408         }
   409 
   410         _this->gl_data->wglMakeCurrent(NULL, NULL);
   411         _this->gl_data->wglDeleteContext(hglrc);
   412     }
   413     ReleaseDC(hwnd, hdc);
   414     DestroyWindow(hwnd);
   415     WIN_PumpEvents(_this);
   416 
   417     return pixel_format;
   418 }
   419 
   420 int
   421 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
   422 {
   423     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   424     PIXELFORMATDESCRIPTOR pfd;
   425     int pixel_format = 0;
   426     int iAttribs[64];
   427     int *iAttr;
   428     float fAttribs[1] = { 0 };
   429 
   430     WIN_GL_SetupPixelFormat(_this, &pfd);
   431 
   432     /* setup WGL_ARB_pixel_format attribs */
   433     iAttr = &iAttribs[0];
   434 
   435     *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
   436     *iAttr++ = GL_TRUE;
   437     *iAttr++ = WGL_RED_BITS_ARB;
   438     *iAttr++ = _this->gl_config.red_size;
   439     *iAttr++ = WGL_GREEN_BITS_ARB;
   440     *iAttr++ = _this->gl_config.green_size;
   441     *iAttr++ = WGL_BLUE_BITS_ARB;
   442     *iAttr++ = _this->gl_config.blue_size;
   443 
   444     if (_this->gl_config.alpha_size) {
   445         *iAttr++ = WGL_ALPHA_BITS_ARB;
   446         *iAttr++ = _this->gl_config.alpha_size;
   447     }
   448 
   449     *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
   450     *iAttr++ = _this->gl_config.double_buffer;
   451 
   452     *iAttr++ = WGL_DEPTH_BITS_ARB;
   453     *iAttr++ = _this->gl_config.depth_size;
   454 
   455     if (_this->gl_config.stencil_size) {
   456         *iAttr++ = WGL_STENCIL_BITS_ARB;
   457         *iAttr++ = _this->gl_config.stencil_size;
   458     }
   459 
   460     if (_this->gl_config.accum_red_size) {
   461         *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
   462         *iAttr++ = _this->gl_config.accum_red_size;
   463     }
   464 
   465     if (_this->gl_config.accum_green_size) {
   466         *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
   467         *iAttr++ = _this->gl_config.accum_green_size;
   468     }
   469 
   470     if (_this->gl_config.accum_blue_size) {
   471         *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
   472         *iAttr++ = _this->gl_config.accum_blue_size;
   473     }
   474 
   475     if (_this->gl_config.accum_alpha_size) {
   476         *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
   477         *iAttr++ = _this->gl_config.accum_alpha_size;
   478     }
   479 
   480     if (_this->gl_config.stereo) {
   481         *iAttr++ = WGL_STEREO_ARB;
   482         *iAttr++ = GL_TRUE;
   483     }
   484 
   485     if (_this->gl_config.multisamplebuffers) {
   486         *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
   487         *iAttr++ = _this->gl_config.multisamplebuffers;
   488     }
   489 
   490     if (_this->gl_config.multisamplesamples) {
   491         *iAttr++ = WGL_SAMPLES_ARB;
   492         *iAttr++ = _this->gl_config.multisamplesamples;
   493     }
   494 
   495     *iAttr++ = WGL_ACCELERATION_ARB;
   496     *iAttr++ = WGL_FULL_ACCELERATION_ARB;
   497 
   498     *iAttr = 0;
   499 
   500     /* Choose and set the closest available pixel format */
   501     if (_this->gl_config.accelerated != 0) {
   502         pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
   503     }
   504     if (!pixel_format && _this->gl_config.accelerated != 1) {
   505         iAttr[-1] = WGL_NO_ACCELERATION_ARB;
   506 	pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
   507     }
   508     if (!pixel_format) {
   509         pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
   510     }
   511     if (!pixel_format) {
   512         return SDL_SetError("No matching GL pixel format available");
   513     }
   514     if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
   515         return WIN_SetError("SetPixelFormat()");
   516     }
   517     return 0;
   518 }
   519 
   520 SDL_GLContext
   521 WIN_GL_CreateContext(_THIS, SDL_Window * window)
   522 {
   523     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   524     HGLRC context, share_context;
   525 
   526     if (_this->gl_config.share_with_current_context) {
   527         share_context = (HGLRC)(_this->current_glctx);
   528     } else {
   529         share_context = 0;
   530     }
   531 
   532     if (_this->gl_config.major_version < 3 &&
   533 	_this->gl_config.profile_mask == 0 &&
   534 	_this->gl_config.flags == 0) {
   535         /* Create legacy context */
   536         context = _this->gl_data->wglCreateContext(hdc);
   537 	if( share_context != 0 ) {
   538             _this->gl_data->wglShareLists(share_context, context);
   539 	}
   540     } else {
   541         PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
   542         HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
   543         if (!temp_context) {
   544             SDL_SetError("Could not create GL context");
   545             return NULL;
   546         }
   547 
   548         /* Make the context current */
   549         if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
   550             WIN_GL_DeleteContext(_this, temp_context);
   551             return NULL;
   552         }
   553 
   554         wglCreateContextAttribsARB =
   555             (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
   556             wglGetProcAddress("wglCreateContextAttribsARB");
   557         if (!wglCreateContextAttribsARB) {
   558             SDL_SetError("GL 3.x is not supported");
   559             context = temp_context;
   560         } else {
   561 	    /* max 8 attributes plus terminator */
   562             int attribs[9] = {
   563                 WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
   564                 WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
   565                 0
   566             };
   567 	    int iattr = 4;
   568 
   569 	    /* SDL profile bits match WGL profile bits */
   570 	    if( _this->gl_config.profile_mask != 0 ) {
   571 	        attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
   572 		attribs[iattr++] = _this->gl_config.profile_mask;
   573 	    }
   574 
   575 	    /* SDL flags match WGL flags */
   576 	    if( _this->gl_config.flags != 0 ) {
   577 	        attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
   578 		attribs[iattr++] = _this->gl_config.flags;
   579 	    }
   580 
   581 	    attribs[iattr++] = 0;
   582 
   583             /* Create the GL 3.x context */
   584             context = wglCreateContextAttribsARB(hdc, share_context, attribs);
   585             /* Delete the GL 2.x context */
   586             _this->gl_data->wglDeleteContext(temp_context);
   587         }
   588     }
   589 
   590     if (!context) {
   591         WIN_SetError("Could not create GL context");
   592         return NULL;
   593     }
   594 
   595     if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
   596         WIN_GL_DeleteContext(_this, context);
   597         return NULL;
   598     }
   599 
   600     WIN_GL_InitExtensions(_this, hdc);
   601 
   602     return context;
   603 }
   604 
   605 int
   606 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   607 {
   608     HDC hdc;
   609 
   610     if (!_this->gl_data) {
   611         return SDL_SetError("OpenGL not initialized");
   612     }
   613 
   614     if (window) {
   615         hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   616     } else {
   617         hdc = NULL;
   618     }
   619     if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
   620         return WIN_SetError("wglMakeCurrent()");
   621     }
   622     return 0;
   623 }
   624 
   625 int
   626 WIN_GL_SetSwapInterval(_THIS, int interval)
   627 {
   628     if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
   629         return SDL_SetError("Negative swap interval unsupported in this GL");
   630     } else if (_this->gl_data->wglSwapIntervalEXT) {
   631         if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
   632             return WIN_SetError("wglSwapIntervalEXT()");
   633         }
   634     } else {
   635         return SDL_Unsupported();
   636     }
   637     return 0;
   638 }
   639 
   640 int
   641 WIN_GL_GetSwapInterval(_THIS)
   642 {
   643     int retval = 0;
   644     if (_this->gl_data->wglGetSwapIntervalEXT) {
   645         retval = _this->gl_data->wglGetSwapIntervalEXT();
   646     }
   647     return retval;
   648 }
   649 
   650 void
   651 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
   652 {
   653     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   654 
   655     SwapBuffers(hdc);
   656 }
   657 
   658 void
   659 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
   660 {
   661     if (!_this->gl_data) {
   662         return;
   663     }
   664     _this->gl_data->wglDeleteContext((HGLRC) context);
   665 }
   666 
   667 #endif /* SDL_VIDEO_OPENGL_WGL */
   668 
   669 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
   670 
   671 /* vi: set ts=4 sw=4 expandtab: */