Exemple #1
0
DHGLRC APIENTRY
DrvCreateLayerContext(
   HDC hdc,
   INT iLayerPlane )
{
   return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
}
HGLRC WINAPI
wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
{
   int majorVersion = 1, minorVersion = 0, layerPlane = 0;
   int contextFlags = 0x0;
   int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
   int i;
   BOOL done = FALSE;

   /* parse attrib_list */
   if (attribList) {
      for (i = 0; !done && attribList[i]; i++) {
         switch (attribList[i]) {
         case WGL_CONTEXT_MAJOR_VERSION_ARB:
            majorVersion = attribList[++i];
            break;
         case WGL_CONTEXT_MINOR_VERSION_ARB:
            minorVersion = attribList[++i];
            break;
         case WGL_CONTEXT_LAYER_PLANE_ARB:
            layerPlane = attribList[++i];
            break;
         case WGL_CONTEXT_FLAGS_ARB:
            contextFlags = attribList[++i];
            break;
         case WGL_CONTEXT_PROFILE_MASK_ARB:
            profileMask = attribList[++i];
            break;
         case 0:
            /* end of list */
            done = TRUE;
            break;
         default:
            /* bad attribute */
            SetLastError(ERROR_INVALID_PARAMETER);
            return NULL;
         }
      }
   }

   /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
   switch (majorVersion) {
   case 1:
      if (minorVersion < 0 || minorVersion > 5) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return NULL;
      }
      break;
   case 2:
      if (minorVersion < 0 || minorVersion > 1) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return NULL;
      }
      break;
   case 3:
      if (minorVersion < 0 || minorVersion > 3) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return NULL;
      }
      break;
   case 4:
      if (minorVersion < 0 || minorVersion > 2) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return NULL;
      }
      break;
   default:
      return NULL;
   }

   if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
       majorVersion < 3) {
      SetLastError(ERROR_INVALID_VERSION_ARB);
      return NULL;
   }

   /* check profileMask */
   if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&
       profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
      SetLastError(ERROR_INVALID_PROFILE_ARB);
      return NULL;
   }

   return (HGLRC) stw_create_context_attribs(hDC, layerPlane,
                                             (DHGLRC) (UINT_PTR) hShareContext,
                                             majorVersion, minorVersion,
                                             contextFlags, profileMask);
}
Exemple #3
0
/**
 * The implementation of this function is tricky.  The OPENGL32.DLL library
 * remaps the context IDs returned by our stw_create_context_attribs()
 * function to different values returned to the caller of wglCreateContext().
 * That is, DHGLRC (driver) handles are not equivalent to HGLRC (public)
 * handles.
 *
 * So we need to generate a new HGLRC ID here.  We do that by calling
 * the regular wglCreateContext() function.  Then, we replace the newly-
 * created stw_context with a new stw_context that reflects the arguments
 * to this function.
 */
HGLRC WINAPI
wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
{
   typedef HGLRC (*wglCreateContext_t)(HDC hdc);
   typedef BOOL (*wglDeleteContext_t)(HGLRC hglrc);
   HGLRC context;
   static HMODULE opengl_lib = 0;
   static wglCreateContext_t wglCreateContext_func = 0;
   static wglDeleteContext_t wglDeleteContext_func = 0;

   int majorVersion = 1, minorVersion = 0, layerPlane = 0;
   int contextFlags = 0x0;
   int profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
   int i;
   BOOL done = FALSE;

   /* parse attrib_list */
   if (attribList) {
      for (i = 0; !done && attribList[i]; i++) {
         switch (attribList[i]) {
         case WGL_CONTEXT_MAJOR_VERSION_ARB:
            majorVersion = attribList[++i];
            break;
         case WGL_CONTEXT_MINOR_VERSION_ARB:
            minorVersion = attribList[++i];
            break;
         case WGL_CONTEXT_LAYER_PLANE_ARB:
            layerPlane = attribList[++i];
            break;
         case WGL_CONTEXT_FLAGS_ARB:
            contextFlags = attribList[++i];
            break;
         case WGL_CONTEXT_PROFILE_MASK_ARB:
            profileMask = attribList[++i];
            break;
         case 0:
            /* end of list */
            done = TRUE;
            break;
         default:
            /* bad attribute */
            SetLastError(ERROR_INVALID_PARAMETER);
            return 0;
         }
      }
   }

   /* check version (generate ERROR_INVALID_VERSION_ARB if bad) */
   switch (majorVersion) {
   case 1:
      if (minorVersion < 0 || minorVersion > 5) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return 0;
      }
      break;
   case 2:
      if (minorVersion < 0 || minorVersion > 1) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return 0;
      }
      break;
   case 3:
      if (minorVersion < 0 || minorVersion > 3) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return 0;
      }
      break;
   case 4:
      if (minorVersion < 0 || minorVersion > 2) {
         SetLastError(ERROR_INVALID_VERSION_ARB);
         return 0;
      }
      break;
   default:
      return 0;
   }

   if ((contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
       majorVersion < 3) {
      SetLastError(ERROR_INVALID_VERSION_ARB);
      return 0;
   }

   /* check profileMask */
   if (profileMask != WGL_CONTEXT_CORE_PROFILE_BIT_ARB &&
       profileMask != WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
      SetLastError(ERROR_INVALID_PROFILE_ARB);
      return 0;
   }

   /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */
   if (opengl_lib == 0) {
      /* Open the OPENGL32.DLL library */
      opengl_lib = LoadLibraryA("OPENGL32.DLL");
      if (!opengl_lib) {
         _debug_printf("wgl: LoadLibrary(OPENGL32.DLL) failed\n");
         return 0;
      }

      /* Get pointer to wglCreateContext() function */
      wglCreateContext_func = (wglCreateContext_t)
         GetProcAddress(opengl_lib, "wglCreateContext");
      if (!wglCreateContext_func) {
         _debug_printf("wgl: failed to get wglCreateContext()\n");
         return 0;
      }

      /* Get pointer to wglDeleteContext() function */
      wglDeleteContext_func = (wglDeleteContext_t)
         GetProcAddress(opengl_lib, "wglDeleteContext");
      if (!wglDeleteContext_func) {
         _debug_printf("wgl: failed to get wglDeleteContext()\n");
         return 0;
      }
   }

   /* Call wglCreateContext to get a valid context ID */
   context = wglCreateContext_func(hDC);

   if (context) {
      /* Now replace the context we just created with a new one that reflects
       * the attributes passed to this function.
       */
      DHGLRC dhglrc, c, share_dhglrc = 0;

      /* Convert public HGLRC to driver DHGLRC */
      if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
         dhglrc = stw_dev->callbacks.wglCbGetDhglrc(context);
         if (hShareContext)
            share_dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hShareContext);
      }
      else {
         /* not using ICD */
         dhglrc = (DHGLRC) context;
         share_dhglrc = (DHGLRC) hShareContext;
      }

      c = stw_create_context_attribs(hDC, layerPlane, share_dhglrc,
                                     majorVersion, minorVersion,
                                     contextFlags, profileMask,
                                     dhglrc);
      if (!c) {
         wglDeleteContext_func(context);
         context = 0;
      }
   }

   return context;
}