Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <windows.h>
  27.  
  28. #define WGL_WGLEXT_PROTOTYPES
  29.  
  30. #include <GL/gl.h>
  31. #include <GL/wglext.h>
  32.  
  33. #include "stw_icd.h"
  34. #include "stw_context.h"
  35. #include "stw_device.h"
  36. #include "stw_ext_context.h"
  37.  
  38.  
  39. wglCreateContext_t wglCreateContext_func = 0;
  40. wglDeleteContext_t wglDeleteContext_func = 0;
  41.  
  42.  
  43. /**
  44.  * The implementation of this function is tricky.  The OPENGL32.DLL library
  45.  * remaps the context IDs returned by our stw_create_context_attribs()
  46.  * function to different values returned to the caller of wglCreateContext().
  47.  * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)
  48.  * handles.
  49.  *
  50.  * So we need to generate a new HGLRC ID here.  We do that by calling
  51.  * the regular wglCreateContext() function.  Then, we replace the newly-
  52.  * created stw_context with a new stw_context that reflects the arguments
  53.  * to this function.
  54.  */
  55. HGLRC WINAPI
  56. wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
  57. {
  58.    HGLRC context;
  59.  
  60.    int majorVersion = 1, minorVersion = 0, layerPlane = 0;
  61.    int contextFlags = 0x0;
  62.    int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
  63.    int i;
  64.    BOOL done = FALSE;
  65.    const int contextFlagsAll = (WGL_CONTEXT_DEBUG_BIT_ARB |
  66.                                 WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
  67.  
  68.    /* parse attrib_list */
  69.    if (attribList) {
  70.       for (i = 0; !done && attribList[i]; i++) {
  71.          switch (attribList[i]) {
  72.          case WGL_CONTEXT_MAJOR_VERSION_ARB:
  73.             majorVersion = attribList[++i];
  74.             break;
  75.          case WGL_CONTEXT_MINOR_VERSION_ARB:
  76.             minorVersion = attribList[++i];
  77.             break;
  78.          case WGL_CONTEXT_LAYER_PLANE_ARB:
  79.             layerPlane = attribList[++i];
  80.             break;
  81.          case WGL_CONTEXT_FLAGS_ARB:
  82.             contextFlags = attribList[++i];
  83.             break;
  84.          case WGL_CONTEXT_PROFILE_MASK_ARB:
  85.             profileMask = attribList[++i];
  86.             break;
  87.          case 0:
  88.             /* end of list */
  89.             done = TRUE;
  90.             break;
  91.          default:
  92.             /* bad attribute */
  93.             SetLastError(ERROR_INVALID_PARAMETER);
  94.             return 0;
  95.          }
  96.       }
  97.    }
  98.  
  99.    /* check contextFlags */
  100.    if (contextFlags & ~contextFlagsAll) {
  101.       SetLastError(ERROR_INVALID_PARAMETER);
  102.       return NULL;
  103.    }
  104.  
  105.    /* check profileMask */
  106.    if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&
  107.        profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
  108.        profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT) {
  109.       SetLastError(ERROR_INVALID_PROFILE_ARB);
  110.       return NULL;
  111.    }
  112.  
  113.    /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
  114.    if (majorVersion <= 0 ||
  115.        minorVersion < 0 ||
  116.        (profileMask != WGL_CONTEXT_ES_PROFILE_BIT_EXT &&
  117.         ((majorVersion == 1 && minorVersion > 5) ||
  118.          (majorVersion == 2 && minorVersion > 1) ||
  119.          (majorVersion == 3 && minorVersion > 3) ||
  120.          (majorVersion == 4 && minorVersion > 5) ||
  121.          majorVersion > 4)) ||
  122.        (profileMask == WGL_CONTEXT_ES_PROFILE_BIT_EXT &&
  123.         ((majorVersion == 1 && minorVersion > 1) ||
  124.          (majorVersion == 2 && minorVersion > 0) ||
  125.          (majorVersion == 3 && minorVersion > 1) ||
  126.          majorVersion > 3))) {
  127.       SetLastError(ERROR_INVALID_VERSION_ARB);
  128.       return NULL;
  129.    }
  130.  
  131.    if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
  132.        majorVersion < 3) {
  133.       SetLastError(ERROR_INVALID_VERSION_ARB);
  134.       return 0;
  135.    }
  136.  
  137.    /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */
  138.    if (!wglCreateContext_func || !wglDeleteContext_func) {
  139.       /* Get the OPENGL32.DLL library */
  140.       HMODULE opengl_lib = GetModuleHandleA("opengl32.dll");
  141.       if (!opengl_lib) {
  142.          _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n");
  143.          return 0;
  144.       }
  145.  
  146.       /* Get pointer to wglCreateContext() function */
  147.       wglCreateContext_func = (wglCreateContext_t)
  148.          GetProcAddress(opengl_lib, "wglCreateContext");
  149.       if (!wglCreateContext_func) {
  150.          _debug_printf("wgl: failed to get wglCreateContext()\n");
  151.          return 0;
  152.       }
  153.  
  154.       /* Get pointer to wglDeleteContext() function */
  155.       wglDeleteContext_func = (wglDeleteContext_t)
  156.          GetProcAddress(opengl_lib, "wglDeleteContext");
  157.       if (!wglDeleteContext_func) {
  158.          _debug_printf("wgl: failed to get wglDeleteContext()\n");
  159.          return 0;
  160.       }
  161.    }
  162.  
  163.    /* Call wglCreateContext to get a valid context ID */
  164.    context = wglCreateContext_func(hDC);
  165.  
  166.    if (context) {
  167.       /* Now replace the context we just created with a new one that reflects
  168.        * the attributes passed to this function.
  169.        */
  170.       DHGLRC dhglrc, c, share_dhglrc = 0;
  171.  
  172.       /* Convert public HGLRC to driver DHGLRC */
  173.       if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
  174.          dhglrc = stw_dev->callbacks.wglCbGetDhglrc(context);
  175.          if (hShareContext)
  176.             share_dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hShareContext);
  177.       }
  178.       else {
  179.          /* not using ICD */
  180.          dhglrc = (DHGLRC) context;
  181.          share_dhglrc = (DHGLRC) hShareContext;
  182.       }
  183.  
  184.       c = stw_create_context_attribs(hDC, layerPlane, share_dhglrc,
  185.                                      majorVersion, minorVersion,
  186.                                      contextFlags, profileMask,
  187.                                      dhglrc);
  188.       if (!c) {
  189.          wglDeleteContext_func(context);
  190.          context = 0;
  191.       }
  192.    }
  193.  
  194.    return context;
  195. }
  196.