17ec681f3Smrg/**************************************************************************
27ec681f3Smrg *
37ec681f3Smrg * Copyright 2008 VMware, Inc.
47ec681f3Smrg * All Rights Reserved.
57ec681f3Smrg *
67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77ec681f3Smrg * copy of this software and associated documentation files (the
87ec681f3Smrg * "Software"), to deal in the Software without restriction, including
97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish,
107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to
117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to
127ec681f3Smrg * the following conditions:
137ec681f3Smrg *
147ec681f3Smrg * The above copyright notice and this permission notice (including the
157ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions
167ec681f3Smrg * of the Software.
177ec681f3Smrg *
187ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
217ec681f3Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
227ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
237ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
247ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257ec681f3Smrg *
267ec681f3Smrg **************************************************************************/
277ec681f3Smrg
287ec681f3Smrg#include <windows.h>
297ec681f3Smrg
307ec681f3Smrg#define WGL_WGLEXT_PROTOTYPES
317ec681f3Smrg
327ec681f3Smrg#include <GL/gl.h>
337ec681f3Smrg#include <GL/wglext.h>
347ec681f3Smrg
357ec681f3Smrg#include "pipe/p_compiler.h"
367ec681f3Smrg#include "pipe/p_context.h"
377ec681f3Smrg#include "pipe/p_state.h"
387ec681f3Smrg#include "util/compiler.h"
397ec681f3Smrg#include "util/u_memory.h"
407ec681f3Smrg#include "util/u_atomic.h"
417ec681f3Smrg#include "hud/hud_context.h"
427ec681f3Smrg
437ec681f3Smrg#include "gldrv.h"
447ec681f3Smrg#include "stw_device.h"
457ec681f3Smrg#include "stw_winsys.h"
467ec681f3Smrg#include "stw_framebuffer.h"
477ec681f3Smrg#include "stw_pixelformat.h"
487ec681f3Smrg#include "stw_context.h"
497ec681f3Smrg#include "stw_tls.h"
507ec681f3Smrg
517ec681f3Smrg
527ec681f3Smrgstruct stw_context *
537ec681f3Smrgstw_current_context(void)
547ec681f3Smrg{
557ec681f3Smrg   struct st_context_iface *st;
567ec681f3Smrg
577ec681f3Smrg   st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
587ec681f3Smrg
597ec681f3Smrg   return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
607ec681f3Smrg}
617ec681f3Smrg
627ec681f3Smrg
637ec681f3SmrgBOOL APIENTRY
647ec681f3SmrgDrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask)
657ec681f3Smrg{
667ec681f3Smrg   struct stw_context *src;
677ec681f3Smrg   struct stw_context *dst;
687ec681f3Smrg   BOOL ret = FALSE;
697ec681f3Smrg
707ec681f3Smrg   if (!stw_dev)
717ec681f3Smrg      return FALSE;
727ec681f3Smrg
737ec681f3Smrg   stw_lock_contexts(stw_dev);
747ec681f3Smrg
757ec681f3Smrg   src = stw_lookup_context_locked( dhrcSource );
767ec681f3Smrg   dst = stw_lookup_context_locked( dhrcDest );
777ec681f3Smrg
787ec681f3Smrg   if (src && dst) {
797ec681f3Smrg      /* FIXME */
807ec681f3Smrg      assert(0);
817ec681f3Smrg      (void) src;
827ec681f3Smrg      (void) dst;
837ec681f3Smrg      (void) fuMask;
847ec681f3Smrg   }
857ec681f3Smrg
867ec681f3Smrg   stw_unlock_contexts(stw_dev);
877ec681f3Smrg
887ec681f3Smrg   return ret;
897ec681f3Smrg}
907ec681f3Smrg
917ec681f3Smrg
927ec681f3SmrgBOOL APIENTRY
937ec681f3SmrgDrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2)
947ec681f3Smrg{
957ec681f3Smrg   struct stw_context *ctx1;
967ec681f3Smrg   struct stw_context *ctx2;
977ec681f3Smrg   BOOL ret = FALSE;
987ec681f3Smrg
997ec681f3Smrg   if (!stw_dev)
1007ec681f3Smrg      return FALSE;
1017ec681f3Smrg
1027ec681f3Smrg   stw_lock_contexts(stw_dev);
1037ec681f3Smrg
1047ec681f3Smrg   ctx1 = stw_lookup_context_locked( dhglrc1 );
1057ec681f3Smrg   ctx2 = stw_lookup_context_locked( dhglrc2 );
1067ec681f3Smrg
1077ec681f3Smrg   if (ctx1 && ctx2 && ctx2->st->share) {
1087ec681f3Smrg      ret = ctx2->st->share(ctx2->st, ctx1->st);
1097ec681f3Smrg      ctx1->shared = TRUE;
1107ec681f3Smrg      ctx2->shared = TRUE;
1117ec681f3Smrg   }
1127ec681f3Smrg
1137ec681f3Smrg   stw_unlock_contexts(stw_dev);
1147ec681f3Smrg
1157ec681f3Smrg   return ret;
1167ec681f3Smrg}
1177ec681f3Smrg
1187ec681f3Smrg
1197ec681f3SmrgDHGLRC APIENTRY
1207ec681f3SmrgDrvCreateContext(HDC hdc)
1217ec681f3Smrg{
1227ec681f3Smrg   return DrvCreateLayerContext( hdc, 0 );
1237ec681f3Smrg}
1247ec681f3Smrg
1257ec681f3Smrg
1267ec681f3SmrgDHGLRC APIENTRY
1277ec681f3SmrgDrvCreateLayerContext(HDC hdc, INT iLayerPlane)
1287ec681f3Smrg{
1297ec681f3Smrg   struct stw_context *ctx = stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
1307ec681f3Smrg                                                        WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
1317ec681f3Smrg                                                        0);
1327ec681f3Smrg   if (!ctx)
1337ec681f3Smrg      return 0;
1347ec681f3Smrg
1357ec681f3Smrg   DHGLRC ret = stw_create_context_handle(ctx, 0);
1367ec681f3Smrg   if (!ret)
1377ec681f3Smrg      stw_destroy_context(ctx);
1387ec681f3Smrg
1397ec681f3Smrg   return ret;
1407ec681f3Smrg}
1417ec681f3Smrg
1427ec681f3Smrg
1437ec681f3Smrg/**
1447ec681f3Smrg * Return the stw pixel format that most closely matches the pixel format
1457ec681f3Smrg * on HDC.
1467ec681f3Smrg * Used to get a pixel format when SetPixelFormat() hasn't been called before.
1477ec681f3Smrg */
1487ec681f3Smrgstatic int
1497ec681f3Smrgget_matching_pixel_format(HDC hdc)
1507ec681f3Smrg{
1517ec681f3Smrg   int iPixelFormat = GetPixelFormat(hdc);
1527ec681f3Smrg   PIXELFORMATDESCRIPTOR pfd;
1537ec681f3Smrg
1547ec681f3Smrg   if (!iPixelFormat)
1557ec681f3Smrg      return 0;
1567ec681f3Smrg   if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd))
1577ec681f3Smrg      return 0;
1587ec681f3Smrg   return stw_pixelformat_choose(hdc, &pfd);
1597ec681f3Smrg}
1607ec681f3Smrg
1617ec681f3Smrg
1627ec681f3Smrg/**
1637ec681f3Smrg * Called via DrvCreateContext(), DrvCreateLayerContext() and
1647ec681f3Smrg * wglCreateContextAttribsARB() to actually create a rendering context.
1657ec681f3Smrg */
1667ec681f3Smrgstruct stw_context *
1677ec681f3Smrgstw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCtx,
1687ec681f3Smrg                           int majorVersion, int minorVersion,
1697ec681f3Smrg                           int contextFlags, int profileMask,
1707ec681f3Smrg                           int iPixelFormat)
1717ec681f3Smrg{
1727ec681f3Smrg   const struct stw_pixelformat_info *pfi;
1737ec681f3Smrg   struct st_context_attribs attribs;
1747ec681f3Smrg   struct stw_context *ctx = NULL;
1757ec681f3Smrg   enum st_context_error ctx_err = 0;
1767ec681f3Smrg
1777ec681f3Smrg   if (!stw_dev)
1787ec681f3Smrg      return 0;
1797ec681f3Smrg
1807ec681f3Smrg   if (iLayerPlane != 0)
1817ec681f3Smrg      return 0;
1827ec681f3Smrg
1837ec681f3Smrg   if (!iPixelFormat) {
1847ec681f3Smrg      /*
1857ec681f3Smrg       * GDI only knows about displayable pixel formats, so determine the pixel
1867ec681f3Smrg       * format from the framebuffer.
1877ec681f3Smrg       *
1887ec681f3Smrg       * This also allows to use a OpenGL DLL / ICD without installing.
1897ec681f3Smrg       */
1907ec681f3Smrg      struct stw_framebuffer *fb;
1917ec681f3Smrg      fb = stw_framebuffer_from_hdc(hdc);
1927ec681f3Smrg      if (fb) {
1937ec681f3Smrg         iPixelFormat = fb->iPixelFormat;
1947ec681f3Smrg         stw_framebuffer_unlock(fb);
1957ec681f3Smrg      }
1967ec681f3Smrg      else {
1977ec681f3Smrg         /* Applications should call SetPixelFormat before creating a context,
1987ec681f3Smrg          * but not all do, and the opengl32 runtime seems to use a default
1997ec681f3Smrg          * pixel format in some cases, so use that.
2007ec681f3Smrg          */
2017ec681f3Smrg         iPixelFormat = get_matching_pixel_format(hdc);
2027ec681f3Smrg         if (!iPixelFormat)
2037ec681f3Smrg            return 0;
2047ec681f3Smrg      }
2057ec681f3Smrg   }
2067ec681f3Smrg
2077ec681f3Smrg   pfi = stw_pixelformat_get_info( iPixelFormat );
2087ec681f3Smrg
2097ec681f3Smrg   if (shareCtx != NULL)
2107ec681f3Smrg      shareCtx->shared = TRUE;
2117ec681f3Smrg
2127ec681f3Smrg   ctx = CALLOC_STRUCT( stw_context );
2137ec681f3Smrg   if (ctx == NULL)
2147ec681f3Smrg      goto no_ctx;
2157ec681f3Smrg
2167ec681f3Smrg   ctx->hDrawDC = hdc;
2177ec681f3Smrg   ctx->hReadDC = hdc;
2187ec681f3Smrg   ctx->iPixelFormat = iPixelFormat;
2197ec681f3Smrg   ctx->shared = shareCtx != NULL;
2207ec681f3Smrg
2217ec681f3Smrg   memset(&attribs, 0, sizeof(attribs));
2227ec681f3Smrg   attribs.visual = pfi->stvis;
2237ec681f3Smrg   attribs.major = majorVersion;
2247ec681f3Smrg   attribs.minor = minorVersion;
2257ec681f3Smrg   if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
2267ec681f3Smrg      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
2277ec681f3Smrg   if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
2287ec681f3Smrg      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
2297ec681f3Smrg
2307ec681f3Smrg   switch (profileMask) {
2317ec681f3Smrg   case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
2327ec681f3Smrg      /* There are no profiles before OpenGL 3.2.  The
2337ec681f3Smrg       * WGL_ARB_create_context_profile spec says:
2347ec681f3Smrg       *
2357ec681f3Smrg       *     "If the requested OpenGL version is less than 3.2,
2367ec681f3Smrg       *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
2377ec681f3Smrg       *     of the context is determined solely by the requested version."
2387ec681f3Smrg       */
2397ec681f3Smrg      if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
2407ec681f3Smrg         attribs.profile = ST_PROFILE_OPENGL_CORE;
2417ec681f3Smrg         break;
2427ec681f3Smrg      }
2437ec681f3Smrg      FALLTHROUGH;
2447ec681f3Smrg   case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
2457ec681f3Smrg      /*
2467ec681f3Smrg       * The spec also says:
2477ec681f3Smrg       *
2487ec681f3Smrg       *     "If version 3.1 is requested, the context returned may implement
2497ec681f3Smrg       *     any of the following versions:
2507ec681f3Smrg       *
2517ec681f3Smrg       *       * Version 3.1. The GL_ARB_compatibility extension may or may not
2527ec681f3Smrg       *         be implemented, as determined by the implementation.
2537ec681f3Smrg       *       * The core profile of version 3.2 or greater."
2547ec681f3Smrg       *
2557ec681f3Smrg       * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
2567ec681f3Smrg       * Windows OpenGL implementations do, and unfortunately many Windows
2577ec681f3Smrg       * applications don't check whether they receive or not a context with
2587ec681f3Smrg       * GL_ARB_compatibility, so returning a core profile here does more harm
2597ec681f3Smrg       * than good.
2607ec681f3Smrg       */
2617ec681f3Smrg      attribs.profile = ST_PROFILE_DEFAULT;
2627ec681f3Smrg      break;
2637ec681f3Smrg   case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
2647ec681f3Smrg      if (majorVersion >= 2) {
2657ec681f3Smrg         attribs.profile = ST_PROFILE_OPENGL_ES2;
2667ec681f3Smrg      } else {
2677ec681f3Smrg         attribs.profile = ST_PROFILE_OPENGL_ES1;
2687ec681f3Smrg      }
2697ec681f3Smrg      break;
2707ec681f3Smrg   default:
2717ec681f3Smrg      assert(0);
2727ec681f3Smrg      goto no_st_ctx;
2737ec681f3Smrg   }
2747ec681f3Smrg
2757ec681f3Smrg   attribs.options = stw_dev->st_options;
2767ec681f3Smrg
2777ec681f3Smrg   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
2787ec681f3Smrg         stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
2797ec681f3Smrg   if (ctx->st == NULL)
2807ec681f3Smrg      goto no_st_ctx;
2817ec681f3Smrg
2827ec681f3Smrg   ctx->st->st_manager_private = (void *) ctx;
2837ec681f3Smrg
2847ec681f3Smrg   if (ctx->st->cso_context) {
2857ec681f3Smrg      ctx->hud = hud_create(ctx->st->cso_context, ctx->st, NULL);
2867ec681f3Smrg   }
2877ec681f3Smrg
2887ec681f3Smrg   return ctx;
2897ec681f3Smrg
2907ec681f3Smrgno_st_ctx:
2917ec681f3Smrg   FREE(ctx);
2927ec681f3Smrgno_ctx:
2937ec681f3Smrg   return NULL;
2947ec681f3Smrg}
2957ec681f3Smrg
2967ec681f3SmrgDHGLRC
2977ec681f3Smrgstw_create_context_handle(struct stw_context *ctx, DHGLRC handle)
2987ec681f3Smrg{
2997ec681f3Smrg   assert(ctx->dhglrc == 0);
3007ec681f3Smrg
3017ec681f3Smrg   stw_lock_contexts(stw_dev);
3027ec681f3Smrg   if (handle) {
3037ec681f3Smrg      /* We're replacing the context data for this handle. See the
3047ec681f3Smrg       * wglCreateContextAttribsARB() function.
3057ec681f3Smrg       */
3067ec681f3Smrg      struct stw_context *old_ctx =
3077ec681f3Smrg         stw_lookup_context_locked((unsigned) handle);
3087ec681f3Smrg      if (old_ctx) {
3097ec681f3Smrg         stw_destroy_context(old_ctx);
3107ec681f3Smrg      }
3117ec681f3Smrg
3127ec681f3Smrg      /* replace table entry */
3137ec681f3Smrg      handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
3147ec681f3Smrg   }
3157ec681f3Smrg   else {
3167ec681f3Smrg      /* create new table entry */
3177ec681f3Smrg      handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
3187ec681f3Smrg   }
3197ec681f3Smrg
3207ec681f3Smrg   ctx->dhglrc = handle;
3217ec681f3Smrg
3227ec681f3Smrg   stw_unlock_contexts(stw_dev);
3237ec681f3Smrg
3247ec681f3Smrg   return ctx->dhglrc;
3257ec681f3Smrg}
3267ec681f3Smrg
3277ec681f3Smrgvoid
3287ec681f3Smrgstw_destroy_context(struct stw_context *ctx)
3297ec681f3Smrg{
3307ec681f3Smrg   if (ctx->hud) {
3317ec681f3Smrg      hud_destroy(ctx->hud, NULL);
3327ec681f3Smrg   }
3337ec681f3Smrg
3347ec681f3Smrg   ctx->st->destroy(ctx->st);
3357ec681f3Smrg   FREE(ctx);
3367ec681f3Smrg}
3377ec681f3Smrg
3387ec681f3Smrg
3397ec681f3SmrgBOOL APIENTRY
3407ec681f3SmrgDrvDeleteContext(DHGLRC dhglrc)
3417ec681f3Smrg{
3427ec681f3Smrg   struct stw_context *ctx ;
3437ec681f3Smrg   BOOL ret = FALSE;
3447ec681f3Smrg
3457ec681f3Smrg   if (!stw_dev)
3467ec681f3Smrg      return FALSE;
3477ec681f3Smrg
3487ec681f3Smrg   stw_lock_contexts(stw_dev);
3497ec681f3Smrg   ctx = stw_lookup_context_locked(dhglrc);
3507ec681f3Smrg   handle_table_remove(stw_dev->ctx_table, dhglrc);
3517ec681f3Smrg   stw_unlock_contexts(stw_dev);
3527ec681f3Smrg
3537ec681f3Smrg   if (ctx) {
3547ec681f3Smrg      struct stw_context *curctx = stw_current_context();
3557ec681f3Smrg
3567ec681f3Smrg      /* Unbind current if deleting current context. */
3577ec681f3Smrg      if (curctx == ctx)
3587ec681f3Smrg         stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
3597ec681f3Smrg
3607ec681f3Smrg      stw_destroy_context(ctx);
3617ec681f3Smrg      ret = TRUE;
3627ec681f3Smrg   }
3637ec681f3Smrg
3647ec681f3Smrg   return ret;
3657ec681f3Smrg}
3667ec681f3Smrg
3677ec681f3SmrgBOOL
3687ec681f3Smrgstw_unbind_context(struct stw_context *ctx)
3697ec681f3Smrg{
3707ec681f3Smrg   if (!ctx)
3717ec681f3Smrg      return FALSE;
3727ec681f3Smrg
3737ec681f3Smrg   /* The expectation is that ctx is the same context which is
3747ec681f3Smrg    * current for this thread.  We should check that and return False
3757ec681f3Smrg    * if not the case.
3767ec681f3Smrg    */
3777ec681f3Smrg   if (ctx != stw_current_context())
3787ec681f3Smrg      return FALSE;
3797ec681f3Smrg
3807ec681f3Smrg   if (stw_make_current( NULL, NULL, NULL ) == FALSE)
3817ec681f3Smrg      return FALSE;
3827ec681f3Smrg
3837ec681f3Smrg   return TRUE;
3847ec681f3Smrg}
3857ec681f3Smrg
3867ec681f3SmrgBOOL APIENTRY
3877ec681f3SmrgDrvReleaseContext(DHGLRC dhglrc)
3887ec681f3Smrg{
3897ec681f3Smrg   struct stw_context *ctx;
3907ec681f3Smrg
3917ec681f3Smrg   if (!stw_dev)
3927ec681f3Smrg      return FALSE;
3937ec681f3Smrg
3947ec681f3Smrg   stw_lock_contexts(stw_dev);
3957ec681f3Smrg   ctx = stw_lookup_context_locked( dhglrc );
3967ec681f3Smrg   stw_unlock_contexts(stw_dev);
3977ec681f3Smrg
3987ec681f3Smrg   return stw_unbind_context(ctx);
3997ec681f3Smrg}
4007ec681f3Smrg
4017ec681f3Smrg
4027ec681f3SmrgDHGLRC
4037ec681f3Smrgstw_get_current_context( void )
4047ec681f3Smrg{
4057ec681f3Smrg   struct stw_context *ctx;
4067ec681f3Smrg
4077ec681f3Smrg   ctx = stw_current_context();
4087ec681f3Smrg   if (!ctx)
4097ec681f3Smrg      return 0;
4107ec681f3Smrg
4117ec681f3Smrg   return ctx->dhglrc;
4127ec681f3Smrg}
4137ec681f3Smrg
4147ec681f3Smrg
4157ec681f3SmrgHDC
4167ec681f3Smrgstw_get_current_dc( void )
4177ec681f3Smrg{
4187ec681f3Smrg   struct stw_context *ctx;
4197ec681f3Smrg
4207ec681f3Smrg   ctx = stw_current_context();
4217ec681f3Smrg   if (!ctx)
4227ec681f3Smrg      return NULL;
4237ec681f3Smrg
4247ec681f3Smrg   return ctx->hDrawDC;
4257ec681f3Smrg}
4267ec681f3Smrg
4277ec681f3SmrgHDC
4287ec681f3Smrgstw_get_current_read_dc( void )
4297ec681f3Smrg{
4307ec681f3Smrg   struct stw_context *ctx;
4317ec681f3Smrg
4327ec681f3Smrg   ctx = stw_current_context();
4337ec681f3Smrg   if (!ctx)
4347ec681f3Smrg      return NULL;
4357ec681f3Smrg
4367ec681f3Smrg   return ctx->hReadDC;
4377ec681f3Smrg}
4387ec681f3Smrg
4397ec681f3Smrgstatic void
4407ec681f3Smrgrelease_old_framebuffers(struct stw_framebuffer *old_fb, struct stw_framebuffer *old_fbRead,
4417ec681f3Smrg                         struct stw_context *old_ctx)
4427ec681f3Smrg{
4437ec681f3Smrg   if (old_fb || old_fbRead) {
4447ec681f3Smrg      stw_lock_framebuffers(stw_dev);
4457ec681f3Smrg      if (old_fb) {
4467ec681f3Smrg         stw_framebuffer_lock(old_fb);
4477ec681f3Smrg         stw_framebuffer_release_locked(old_fb, old_ctx->st);
4487ec681f3Smrg      }
4497ec681f3Smrg      if (old_fbRead) {
4507ec681f3Smrg         stw_framebuffer_lock(old_fbRead);
4517ec681f3Smrg         stw_framebuffer_release_locked(old_fbRead, old_ctx->st);
4527ec681f3Smrg      }
4537ec681f3Smrg      stw_unlock_framebuffers(stw_dev);
4547ec681f3Smrg   }
4557ec681f3Smrg}
4567ec681f3Smrg
4577ec681f3SmrgBOOL
4587ec681f3Smrgstw_make_current(struct stw_framebuffer *fb, struct stw_framebuffer *fbRead, struct stw_context *ctx)
4597ec681f3Smrg{
4607ec681f3Smrg   struct stw_context *old_ctx = NULL;
4617ec681f3Smrg   BOOL ret = FALSE;
4627ec681f3Smrg
4637ec681f3Smrg   if (!stw_dev)
4647ec681f3Smrg      return FALSE;
4657ec681f3Smrg
4667ec681f3Smrg   old_ctx = stw_current_context();
4677ec681f3Smrg   if (old_ctx != NULL) {
4687ec681f3Smrg      if (old_ctx == ctx) {
4697ec681f3Smrg         if (old_ctx->current_framebuffer == fb && old_ctx->current_read_framebuffer == fbRead) {
4707ec681f3Smrg            /* Return if already current. */
4717ec681f3Smrg            return TRUE;
4727ec681f3Smrg         }
4737ec681f3Smrg      } else {
4747ec681f3Smrg         if (old_ctx->shared) {
4757ec681f3Smrg            if (old_ctx->current_framebuffer) {
4767ec681f3Smrg               stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,
4777ec681f3Smrg                            ST_FLUSH_FRONT | ST_FLUSH_WAIT);
4787ec681f3Smrg            } else {
4797ec681f3Smrg               struct pipe_fence_handle *fence = NULL;
4807ec681f3Smrg               old_ctx->st->flush(old_ctx->st,
4817ec681f3Smrg                                  ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence,
4827ec681f3Smrg                                  NULL, NULL);
4837ec681f3Smrg            }
4847ec681f3Smrg         } else {
4857ec681f3Smrg            if (old_ctx->current_framebuffer)
4867ec681f3Smrg               stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,
4877ec681f3Smrg                            ST_FLUSH_FRONT);
4887ec681f3Smrg            else
4897ec681f3Smrg               old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
4907ec681f3Smrg         }
4917ec681f3Smrg      }
4927ec681f3Smrg   }
4937ec681f3Smrg
4947ec681f3Smrg   if (ctx) {
4957ec681f3Smrg      if (!fb || !fbRead)
4967ec681f3Smrg         goto fail;
4977ec681f3Smrg
4987ec681f3Smrg      if (fb->iPixelFormat != ctx->iPixelFormat) {
4997ec681f3Smrg         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
5007ec681f3Smrg         goto fail;
5017ec681f3Smrg      }
5027ec681f3Smrg      if (fbRead->iPixelFormat != ctx->iPixelFormat) {
5037ec681f3Smrg         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
5047ec681f3Smrg         goto fail;
5057ec681f3Smrg      }
5067ec681f3Smrg
5077ec681f3Smrg      stw_framebuffer_lock(fb);
5087ec681f3Smrg      stw_framebuffer_update(fb);
5097ec681f3Smrg      stw_framebuffer_reference_locked(fb);
5107ec681f3Smrg      stw_framebuffer_unlock(fb);
5117ec681f3Smrg
5127ec681f3Smrg      stw_framebuffer_lock(fbRead);
5137ec681f3Smrg      if (fbRead != fb)
5147ec681f3Smrg         stw_framebuffer_update(fbRead);
5157ec681f3Smrg      stw_framebuffer_reference_locked(fbRead);
5167ec681f3Smrg      stw_framebuffer_unlock(fbRead);
5177ec681f3Smrg
5187ec681f3Smrg      struct stw_framebuffer *old_fb = ctx->current_framebuffer;
5197ec681f3Smrg      struct stw_framebuffer *old_fbRead = ctx->current_read_framebuffer;
5207ec681f3Smrg      ctx->current_framebuffer = fb;
5217ec681f3Smrg      ctx->current_read_framebuffer = fbRead;
5227ec681f3Smrg
5237ec681f3Smrg      ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
5247ec681f3Smrg                                          fb->stfb, fbRead->stfb);
5257ec681f3Smrg
5267ec681f3Smrg      /* Release the old framebuffers from this context. */
5277ec681f3Smrg      release_old_framebuffers(old_fb, old_fbRead, ctx);
5287ec681f3Smrg
5297ec681f3Smrgfail:
5307ec681f3Smrg      /* fb and fbRead must be unlocked at this point. */
5317ec681f3Smrg      if (fb)
5327ec681f3Smrg         assert(!stw_own_mutex(&fb->mutex));
5337ec681f3Smrg      if (fbRead)
5347ec681f3Smrg         assert(!stw_own_mutex(&fbRead->mutex));
5357ec681f3Smrg
5367ec681f3Smrg      /* On failure, make the thread's current rendering context not current
5377ec681f3Smrg       * before returning.
5387ec681f3Smrg       */
5397ec681f3Smrg      if (!ret) {
5407ec681f3Smrg         stw_make_current(NULL, NULL, NULL);
5417ec681f3Smrg      }
5427ec681f3Smrg   } else {
5437ec681f3Smrg      ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
5447ec681f3Smrg   }
5457ec681f3Smrg
5467ec681f3Smrg   /* Unreference the previous framebuffer if any. It must be done after
5477ec681f3Smrg    * make_current, as it can be referenced inside.
5487ec681f3Smrg    */
5497ec681f3Smrg   if (old_ctx && old_ctx != ctx) {
5507ec681f3Smrg      release_old_framebuffers(old_ctx->current_framebuffer, old_ctx->current_read_framebuffer, old_ctx);
5517ec681f3Smrg      old_ctx->current_framebuffer = NULL;
5527ec681f3Smrg      old_ctx->current_read_framebuffer = NULL;
5537ec681f3Smrg   }
5547ec681f3Smrg
5557ec681f3Smrg   return ret;
5567ec681f3Smrg}
5577ec681f3Smrg
5587ec681f3Smrgstatic struct stw_framebuffer *
5597ec681f3Smrgget_unlocked_refd_framebuffer_from_dc(HDC hDC)
5607ec681f3Smrg{
5617ec681f3Smrg   if (!hDC)
5627ec681f3Smrg      return NULL;
5637ec681f3Smrg
5647ec681f3Smrg   /* This call locks fb's mutex */
5657ec681f3Smrg   struct stw_framebuffer *fb = stw_framebuffer_from_hdc(hDC);
5667ec681f3Smrg   if (!fb) {
5677ec681f3Smrg      /* Applications should call SetPixelFormat before creating a context,
5687ec681f3Smrg       * but not all do, and the opengl32 runtime seems to use a default
5697ec681f3Smrg       * pixel format in some cases, so we must create a framebuffer for
5707ec681f3Smrg       * those here.
5717ec681f3Smrg       */
5727ec681f3Smrg      int iPixelFormat = get_matching_pixel_format(hDC);
5737ec681f3Smrg      if (iPixelFormat)
5747ec681f3Smrg         fb = stw_framebuffer_create(WindowFromDC(hDC), iPixelFormat, STW_FRAMEBUFFER_WGL_WINDOW);
5757ec681f3Smrg      if (!fb)
5767ec681f3Smrg         return NULL;
5777ec681f3Smrg   }
5787ec681f3Smrg   stw_framebuffer_reference_locked(fb);
5797ec681f3Smrg   stw_framebuffer_unlock(fb);
5807ec681f3Smrg   return fb;
5817ec681f3Smrg}
5827ec681f3Smrg
5837ec681f3SmrgBOOL
5847ec681f3Smrgstw_make_current_by_handles(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc)
5857ec681f3Smrg{
5867ec681f3Smrg   struct stw_context *ctx = stw_lookup_context(dhglrc);
5877ec681f3Smrg   if (dhglrc && !ctx) {
5887ec681f3Smrg      stw_make_current_by_handles(NULL, NULL, 0);
5897ec681f3Smrg      return FALSE;
5907ec681f3Smrg   }
5917ec681f3Smrg
5927ec681f3Smrg   struct stw_framebuffer *fb = get_unlocked_refd_framebuffer_from_dc(hDrawDC);
5937ec681f3Smrg   if (ctx && !fb) {
5947ec681f3Smrg      stw_make_current_by_handles(NULL, NULL, 0);
5957ec681f3Smrg      return FALSE;
5967ec681f3Smrg   }
5977ec681f3Smrg
5987ec681f3Smrg   struct stw_framebuffer *fbRead = (hDrawDC == hReadDC || hReadDC == NULL) ?
5997ec681f3Smrg      fb : get_unlocked_refd_framebuffer_from_dc(hReadDC);
6007ec681f3Smrg   if (ctx && !fbRead) {
6017ec681f3Smrg      release_old_framebuffers(fb, NULL, ctx);
6027ec681f3Smrg      stw_make_current_by_handles(NULL, NULL, 0);
6037ec681f3Smrg      return FALSE;
6047ec681f3Smrg   }
6057ec681f3Smrg
6067ec681f3Smrg   BOOL success = stw_make_current(fb, fbRead, ctx);
6077ec681f3Smrg
6087ec681f3Smrg   if (ctx) {
6097ec681f3Smrg      if (success) {
6107ec681f3Smrg         ctx->hDrawDC = hDrawDC;
6117ec681f3Smrg         ctx->hReadDC = hReadDC;
6127ec681f3Smrg      } else {
6137ec681f3Smrg         ctx->hDrawDC = NULL;
6147ec681f3Smrg         ctx->hReadDC = NULL;
6157ec681f3Smrg      }
6167ec681f3Smrg
6177ec681f3Smrg      assert(fb && fbRead);
6187ec681f3Smrg      /* In the success case, the context took extra references on these framebuffers,
6197ec681f3Smrg       * so release our local references.
6207ec681f3Smrg       */
6217ec681f3Smrg      stw_lock_framebuffers(stw_dev);
6227ec681f3Smrg      stw_framebuffer_lock(fb);
6237ec681f3Smrg      stw_framebuffer_release_locked(fb, ctx->st);
6247ec681f3Smrg      if (fb != fbRead) {
6257ec681f3Smrg         stw_framebuffer_lock(fbRead);
6267ec681f3Smrg         stw_framebuffer_release_locked(fbRead, ctx->st);
6277ec681f3Smrg      }
6287ec681f3Smrg      stw_unlock_framebuffers(stw_dev);
6297ec681f3Smrg   }
6307ec681f3Smrg   return success;
6317ec681f3Smrg}
6327ec681f3Smrg
6337ec681f3Smrg
6347ec681f3Smrg/**
6357ec681f3Smrg * Notify the current context that the framebuffer has become invalid.
6367ec681f3Smrg */
6377ec681f3Smrgvoid
6387ec681f3Smrgstw_notify_current_locked( struct stw_framebuffer *fb )
6397ec681f3Smrg{
6407ec681f3Smrg   p_atomic_inc(&fb->stfb->stamp);
6417ec681f3Smrg}
6427ec681f3Smrg
6437ec681f3Smrg
6447ec681f3Smrg/**
6457ec681f3Smrg * Although WGL allows different dispatch entrypoints per context
6467ec681f3Smrg */
6477ec681f3Smrgstatic const GLCLTPROCTABLE cpt =
6487ec681f3Smrg{
6497ec681f3Smrg   OPENGL_VERSION_110_ENTRIES,
6507ec681f3Smrg   {
6517ec681f3Smrg      &glNewList,
6527ec681f3Smrg      &glEndList,
6537ec681f3Smrg      &glCallList,
6547ec681f3Smrg      &glCallLists,
6557ec681f3Smrg      &glDeleteLists,
6567ec681f3Smrg      &glGenLists,
6577ec681f3Smrg      &glListBase,
6587ec681f3Smrg      &glBegin,
6597ec681f3Smrg      &glBitmap,
6607ec681f3Smrg      &glColor3b,
6617ec681f3Smrg      &glColor3bv,
6627ec681f3Smrg      &glColor3d,
6637ec681f3Smrg      &glColor3dv,
6647ec681f3Smrg      &glColor3f,
6657ec681f3Smrg      &glColor3fv,
6667ec681f3Smrg      &glColor3i,
6677ec681f3Smrg      &glColor3iv,
6687ec681f3Smrg      &glColor3s,
6697ec681f3Smrg      &glColor3sv,
6707ec681f3Smrg      &glColor3ub,
6717ec681f3Smrg      &glColor3ubv,
6727ec681f3Smrg      &glColor3ui,
6737ec681f3Smrg      &glColor3uiv,
6747ec681f3Smrg      &glColor3us,
6757ec681f3Smrg      &glColor3usv,
6767ec681f3Smrg      &glColor4b,
6777ec681f3Smrg      &glColor4bv,
6787ec681f3Smrg      &glColor4d,
6797ec681f3Smrg      &glColor4dv,
6807ec681f3Smrg      &glColor4f,
6817ec681f3Smrg      &glColor4fv,
6827ec681f3Smrg      &glColor4i,
6837ec681f3Smrg      &glColor4iv,
6847ec681f3Smrg      &glColor4s,
6857ec681f3Smrg      &glColor4sv,
6867ec681f3Smrg      &glColor4ub,
6877ec681f3Smrg      &glColor4ubv,
6887ec681f3Smrg      &glColor4ui,
6897ec681f3Smrg      &glColor4uiv,
6907ec681f3Smrg      &glColor4us,
6917ec681f3Smrg      &glColor4usv,
6927ec681f3Smrg      &glEdgeFlag,
6937ec681f3Smrg      &glEdgeFlagv,
6947ec681f3Smrg      &glEnd,
6957ec681f3Smrg      &glIndexd,
6967ec681f3Smrg      &glIndexdv,
6977ec681f3Smrg      &glIndexf,
6987ec681f3Smrg      &glIndexfv,
6997ec681f3Smrg      &glIndexi,
7007ec681f3Smrg      &glIndexiv,
7017ec681f3Smrg      &glIndexs,
7027ec681f3Smrg      &glIndexsv,
7037ec681f3Smrg      &glNormal3b,
7047ec681f3Smrg      &glNormal3bv,
7057ec681f3Smrg      &glNormal3d,
7067ec681f3Smrg      &glNormal3dv,
7077ec681f3Smrg      &glNormal3f,
7087ec681f3Smrg      &glNormal3fv,
7097ec681f3Smrg      &glNormal3i,
7107ec681f3Smrg      &glNormal3iv,
7117ec681f3Smrg      &glNormal3s,
7127ec681f3Smrg      &glNormal3sv,
7137ec681f3Smrg      &glRasterPos2d,
7147ec681f3Smrg      &glRasterPos2dv,
7157ec681f3Smrg      &glRasterPos2f,
7167ec681f3Smrg      &glRasterPos2fv,
7177ec681f3Smrg      &glRasterPos2i,
7187ec681f3Smrg      &glRasterPos2iv,
7197ec681f3Smrg      &glRasterPos2s,
7207ec681f3Smrg      &glRasterPos2sv,
7217ec681f3Smrg      &glRasterPos3d,
7227ec681f3Smrg      &glRasterPos3dv,
7237ec681f3Smrg      &glRasterPos3f,
7247ec681f3Smrg      &glRasterPos3fv,
7257ec681f3Smrg      &glRasterPos3i,
7267ec681f3Smrg      &glRasterPos3iv,
7277ec681f3Smrg      &glRasterPos3s,
7287ec681f3Smrg      &glRasterPos3sv,
7297ec681f3Smrg      &glRasterPos4d,
7307ec681f3Smrg      &glRasterPos4dv,
7317ec681f3Smrg      &glRasterPos4f,
7327ec681f3Smrg      &glRasterPos4fv,
7337ec681f3Smrg      &glRasterPos4i,
7347ec681f3Smrg      &glRasterPos4iv,
7357ec681f3Smrg      &glRasterPos4s,
7367ec681f3Smrg      &glRasterPos4sv,
7377ec681f3Smrg      &glRectd,
7387ec681f3Smrg      &glRectdv,
7397ec681f3Smrg      &glRectf,
7407ec681f3Smrg      &glRectfv,
7417ec681f3Smrg      &glRecti,
7427ec681f3Smrg      &glRectiv,
7437ec681f3Smrg      &glRects,
7447ec681f3Smrg      &glRectsv,
7457ec681f3Smrg      &glTexCoord1d,
7467ec681f3Smrg      &glTexCoord1dv,
7477ec681f3Smrg      &glTexCoord1f,
7487ec681f3Smrg      &glTexCoord1fv,
7497ec681f3Smrg      &glTexCoord1i,
7507ec681f3Smrg      &glTexCoord1iv,
7517ec681f3Smrg      &glTexCoord1s,
7527ec681f3Smrg      &glTexCoord1sv,
7537ec681f3Smrg      &glTexCoord2d,
7547ec681f3Smrg      &glTexCoord2dv,
7557ec681f3Smrg      &glTexCoord2f,
7567ec681f3Smrg      &glTexCoord2fv,
7577ec681f3Smrg      &glTexCoord2i,
7587ec681f3Smrg      &glTexCoord2iv,
7597ec681f3Smrg      &glTexCoord2s,
7607ec681f3Smrg      &glTexCoord2sv,
7617ec681f3Smrg      &glTexCoord3d,
7627ec681f3Smrg      &glTexCoord3dv,
7637ec681f3Smrg      &glTexCoord3f,
7647ec681f3Smrg      &glTexCoord3fv,
7657ec681f3Smrg      &glTexCoord3i,
7667ec681f3Smrg      &glTexCoord3iv,
7677ec681f3Smrg      &glTexCoord3s,
7687ec681f3Smrg      &glTexCoord3sv,
7697ec681f3Smrg      &glTexCoord4d,
7707ec681f3Smrg      &glTexCoord4dv,
7717ec681f3Smrg      &glTexCoord4f,
7727ec681f3Smrg      &glTexCoord4fv,
7737ec681f3Smrg      &glTexCoord4i,
7747ec681f3Smrg      &glTexCoord4iv,
7757ec681f3Smrg      &glTexCoord4s,
7767ec681f3Smrg      &glTexCoord4sv,
7777ec681f3Smrg      &glVertex2d,
7787ec681f3Smrg      &glVertex2dv,
7797ec681f3Smrg      &glVertex2f,
7807ec681f3Smrg      &glVertex2fv,
7817ec681f3Smrg      &glVertex2i,
7827ec681f3Smrg      &glVertex2iv,
7837ec681f3Smrg      &glVertex2s,
7847ec681f3Smrg      &glVertex2sv,
7857ec681f3Smrg      &glVertex3d,
7867ec681f3Smrg      &glVertex3dv,
7877ec681f3Smrg      &glVertex3f,
7887ec681f3Smrg      &glVertex3fv,
7897ec681f3Smrg      &glVertex3i,
7907ec681f3Smrg      &glVertex3iv,
7917ec681f3Smrg      &glVertex3s,
7927ec681f3Smrg      &glVertex3sv,
7937ec681f3Smrg      &glVertex4d,
7947ec681f3Smrg      &glVertex4dv,
7957ec681f3Smrg      &glVertex4f,
7967ec681f3Smrg      &glVertex4fv,
7977ec681f3Smrg      &glVertex4i,
7987ec681f3Smrg      &glVertex4iv,
7997ec681f3Smrg      &glVertex4s,
8007ec681f3Smrg      &glVertex4sv,
8017ec681f3Smrg      &glClipPlane,
8027ec681f3Smrg      &glColorMaterial,
8037ec681f3Smrg      &glCullFace,
8047ec681f3Smrg      &glFogf,
8057ec681f3Smrg      &glFogfv,
8067ec681f3Smrg      &glFogi,
8077ec681f3Smrg      &glFogiv,
8087ec681f3Smrg      &glFrontFace,
8097ec681f3Smrg      &glHint,
8107ec681f3Smrg      &glLightf,
8117ec681f3Smrg      &glLightfv,
8127ec681f3Smrg      &glLighti,
8137ec681f3Smrg      &glLightiv,
8147ec681f3Smrg      &glLightModelf,
8157ec681f3Smrg      &glLightModelfv,
8167ec681f3Smrg      &glLightModeli,
8177ec681f3Smrg      &glLightModeliv,
8187ec681f3Smrg      &glLineStipple,
8197ec681f3Smrg      &glLineWidth,
8207ec681f3Smrg      &glMaterialf,
8217ec681f3Smrg      &glMaterialfv,
8227ec681f3Smrg      &glMateriali,
8237ec681f3Smrg      &glMaterialiv,
8247ec681f3Smrg      &glPointSize,
8257ec681f3Smrg      &glPolygonMode,
8267ec681f3Smrg      &glPolygonStipple,
8277ec681f3Smrg      &glScissor,
8287ec681f3Smrg      &glShadeModel,
8297ec681f3Smrg      &glTexParameterf,
8307ec681f3Smrg      &glTexParameterfv,
8317ec681f3Smrg      &glTexParameteri,
8327ec681f3Smrg      &glTexParameteriv,
8337ec681f3Smrg      &glTexImage1D,
8347ec681f3Smrg      &glTexImage2D,
8357ec681f3Smrg      &glTexEnvf,
8367ec681f3Smrg      &glTexEnvfv,
8377ec681f3Smrg      &glTexEnvi,
8387ec681f3Smrg      &glTexEnviv,
8397ec681f3Smrg      &glTexGend,
8407ec681f3Smrg      &glTexGendv,
8417ec681f3Smrg      &glTexGenf,
8427ec681f3Smrg      &glTexGenfv,
8437ec681f3Smrg      &glTexGeni,
8447ec681f3Smrg      &glTexGeniv,
8457ec681f3Smrg      &glFeedbackBuffer,
8467ec681f3Smrg      &glSelectBuffer,
8477ec681f3Smrg      &glRenderMode,
8487ec681f3Smrg      &glInitNames,
8497ec681f3Smrg      &glLoadName,
8507ec681f3Smrg      &glPassThrough,
8517ec681f3Smrg      &glPopName,
8527ec681f3Smrg      &glPushName,
8537ec681f3Smrg      &glDrawBuffer,
8547ec681f3Smrg      &glClear,
8557ec681f3Smrg      &glClearAccum,
8567ec681f3Smrg      &glClearIndex,
8577ec681f3Smrg      &glClearColor,
8587ec681f3Smrg      &glClearStencil,
8597ec681f3Smrg      &glClearDepth,
8607ec681f3Smrg      &glStencilMask,
8617ec681f3Smrg      &glColorMask,
8627ec681f3Smrg      &glDepthMask,
8637ec681f3Smrg      &glIndexMask,
8647ec681f3Smrg      &glAccum,
8657ec681f3Smrg      &glDisable,
8667ec681f3Smrg      &glEnable,
8677ec681f3Smrg      &glFinish,
8687ec681f3Smrg      &glFlush,
8697ec681f3Smrg      &glPopAttrib,
8707ec681f3Smrg      &glPushAttrib,
8717ec681f3Smrg      &glMap1d,
8727ec681f3Smrg      &glMap1f,
8737ec681f3Smrg      &glMap2d,
8747ec681f3Smrg      &glMap2f,
8757ec681f3Smrg      &glMapGrid1d,
8767ec681f3Smrg      &glMapGrid1f,
8777ec681f3Smrg      &glMapGrid2d,
8787ec681f3Smrg      &glMapGrid2f,
8797ec681f3Smrg      &glEvalCoord1d,
8807ec681f3Smrg      &glEvalCoord1dv,
8817ec681f3Smrg      &glEvalCoord1f,
8827ec681f3Smrg      &glEvalCoord1fv,
8837ec681f3Smrg      &glEvalCoord2d,
8847ec681f3Smrg      &glEvalCoord2dv,
8857ec681f3Smrg      &glEvalCoord2f,
8867ec681f3Smrg      &glEvalCoord2fv,
8877ec681f3Smrg      &glEvalMesh1,
8887ec681f3Smrg      &glEvalPoint1,
8897ec681f3Smrg      &glEvalMesh2,
8907ec681f3Smrg      &glEvalPoint2,
8917ec681f3Smrg      &glAlphaFunc,
8927ec681f3Smrg      &glBlendFunc,
8937ec681f3Smrg      &glLogicOp,
8947ec681f3Smrg      &glStencilFunc,
8957ec681f3Smrg      &glStencilOp,
8967ec681f3Smrg      &glDepthFunc,
8977ec681f3Smrg      &glPixelZoom,
8987ec681f3Smrg      &glPixelTransferf,
8997ec681f3Smrg      &glPixelTransferi,
9007ec681f3Smrg      &glPixelStoref,
9017ec681f3Smrg      &glPixelStorei,
9027ec681f3Smrg      &glPixelMapfv,
9037ec681f3Smrg      &glPixelMapuiv,
9047ec681f3Smrg      &glPixelMapusv,
9057ec681f3Smrg      &glReadBuffer,
9067ec681f3Smrg      &glCopyPixels,
9077ec681f3Smrg      &glReadPixels,
9087ec681f3Smrg      &glDrawPixels,
9097ec681f3Smrg      &glGetBooleanv,
9107ec681f3Smrg      &glGetClipPlane,
9117ec681f3Smrg      &glGetDoublev,
9127ec681f3Smrg      &glGetError,
9137ec681f3Smrg      &glGetFloatv,
9147ec681f3Smrg      &glGetIntegerv,
9157ec681f3Smrg      &glGetLightfv,
9167ec681f3Smrg      &glGetLightiv,
9177ec681f3Smrg      &glGetMapdv,
9187ec681f3Smrg      &glGetMapfv,
9197ec681f3Smrg      &glGetMapiv,
9207ec681f3Smrg      &glGetMaterialfv,
9217ec681f3Smrg      &glGetMaterialiv,
9227ec681f3Smrg      &glGetPixelMapfv,
9237ec681f3Smrg      &glGetPixelMapuiv,
9247ec681f3Smrg      &glGetPixelMapusv,
9257ec681f3Smrg      &glGetPolygonStipple,
9267ec681f3Smrg      &glGetString,
9277ec681f3Smrg      &glGetTexEnvfv,
9287ec681f3Smrg      &glGetTexEnviv,
9297ec681f3Smrg      &glGetTexGendv,
9307ec681f3Smrg      &glGetTexGenfv,
9317ec681f3Smrg      &glGetTexGeniv,
9327ec681f3Smrg      &glGetTexImage,
9337ec681f3Smrg      &glGetTexParameterfv,
9347ec681f3Smrg      &glGetTexParameteriv,
9357ec681f3Smrg      &glGetTexLevelParameterfv,
9367ec681f3Smrg      &glGetTexLevelParameteriv,
9377ec681f3Smrg      &glIsEnabled,
9387ec681f3Smrg      &glIsList,
9397ec681f3Smrg      &glDepthRange,
9407ec681f3Smrg      &glFrustum,
9417ec681f3Smrg      &glLoadIdentity,
9427ec681f3Smrg      &glLoadMatrixf,
9437ec681f3Smrg      &glLoadMatrixd,
9447ec681f3Smrg      &glMatrixMode,
9457ec681f3Smrg      &glMultMatrixf,
9467ec681f3Smrg      &glMultMatrixd,
9477ec681f3Smrg      &glOrtho,
9487ec681f3Smrg      &glPopMatrix,
9497ec681f3Smrg      &glPushMatrix,
9507ec681f3Smrg      &glRotated,
9517ec681f3Smrg      &glRotatef,
9527ec681f3Smrg      &glScaled,
9537ec681f3Smrg      &glScalef,
9547ec681f3Smrg      &glTranslated,
9557ec681f3Smrg      &glTranslatef,
9567ec681f3Smrg      &glViewport,
9577ec681f3Smrg      &glArrayElement,
9587ec681f3Smrg      &glBindTexture,
9597ec681f3Smrg      &glColorPointer,
9607ec681f3Smrg      &glDisableClientState,
9617ec681f3Smrg      &glDrawArrays,
9627ec681f3Smrg      &glDrawElements,
9637ec681f3Smrg      &glEdgeFlagPointer,
9647ec681f3Smrg      &glEnableClientState,
9657ec681f3Smrg      &glIndexPointer,
9667ec681f3Smrg      &glIndexub,
9677ec681f3Smrg      &glIndexubv,
9687ec681f3Smrg      &glInterleavedArrays,
9697ec681f3Smrg      &glNormalPointer,
9707ec681f3Smrg      &glPolygonOffset,
9717ec681f3Smrg      &glTexCoordPointer,
9727ec681f3Smrg      &glVertexPointer,
9737ec681f3Smrg      &glAreTexturesResident,
9747ec681f3Smrg      &glCopyTexImage1D,
9757ec681f3Smrg      &glCopyTexImage2D,
9767ec681f3Smrg      &glCopyTexSubImage1D,
9777ec681f3Smrg      &glCopyTexSubImage2D,
9787ec681f3Smrg      &glDeleteTextures,
9797ec681f3Smrg      &glGenTextures,
9807ec681f3Smrg      &glGetPointerv,
9817ec681f3Smrg      &glIsTexture,
9827ec681f3Smrg      &glPrioritizeTextures,
9837ec681f3Smrg      &glTexSubImage1D,
9847ec681f3Smrg      &glTexSubImage2D,
9857ec681f3Smrg      &glPopClientAttrib,
9867ec681f3Smrg      &glPushClientAttrib
9877ec681f3Smrg   }
9887ec681f3Smrg};
9897ec681f3Smrg
9907ec681f3Smrg
9917ec681f3SmrgPGLCLTPROCTABLE APIENTRY
9927ec681f3SmrgDrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
9937ec681f3Smrg{
9947ec681f3Smrg   PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
9957ec681f3Smrg
9967ec681f3Smrg   if (!stw_make_current_by_handles(hdc, hdc, dhglrc))
9977ec681f3Smrg      r = NULL;
9987ec681f3Smrg
9997ec681f3Smrg   return r;
10007ec681f3Smrg}
1001