Home | History | Annotate | Download | only in wgl
      1 /**************************************************************************
      2  *
      3  * Copyright 2008 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 #include <windows.h>
     29 
     30 #define WGL_WGLEXT_PROTOTYPES
     31 
     32 #include <GL/gl.h>
     33 #include <GL/wglext.h>
     34 
     35 #include "pipe/p_compiler.h"
     36 #include "pipe/p_context.h"
     37 #include "pipe/p_state.h"
     38 #include "util/u_memory.h"
     39 #include "util/u_atomic.h"
     40 #include "state_tracker/st_api.h"
     41 #include "hud/hud_context.h"
     42 
     43 #include "stw_icd.h"
     44 #include "stw_device.h"
     45 #include "stw_winsys.h"
     46 #include "stw_framebuffer.h"
     47 #include "stw_pixelformat.h"
     48 #include "stw_context.h"
     49 #include "stw_tls.h"
     50 
     51 
     52 struct stw_context *
     53 stw_current_context(void)
     54 {
     55    struct st_context_iface *st;
     56 
     57    st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
     58 
     59    return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
     60 }
     61 
     62 
     63 BOOL APIENTRY
     64 DrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask)
     65 {
     66    struct stw_context *src;
     67    struct stw_context *dst;
     68    BOOL ret = FALSE;
     69 
     70    if (!stw_dev)
     71       return FALSE;
     72 
     73    stw_lock_contexts(stw_dev);
     74 
     75    src = stw_lookup_context_locked( dhrcSource );
     76    dst = stw_lookup_context_locked( dhrcDest );
     77 
     78    if (src && dst) {
     79       /* FIXME */
     80       assert(0);
     81       (void) src;
     82       (void) dst;
     83       (void) fuMask;
     84    }
     85 
     86    stw_unlock_contexts(stw_dev);
     87 
     88    return ret;
     89 }
     90 
     91 
     92 BOOL APIENTRY
     93 DrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2)
     94 {
     95    struct stw_context *ctx1;
     96    struct stw_context *ctx2;
     97    BOOL ret = FALSE;
     98 
     99    if (!stw_dev)
    100       return FALSE;
    101 
    102    stw_lock_contexts(stw_dev);
    103 
    104    ctx1 = stw_lookup_context_locked( dhglrc1 );
    105    ctx2 = stw_lookup_context_locked( dhglrc2 );
    106 
    107    if (ctx1 && ctx2 && ctx2->st->share)
    108       ret = ctx2->st->share(ctx2->st, ctx1->st);
    109 
    110    stw_unlock_contexts(stw_dev);
    111 
    112    return ret;
    113 }
    114 
    115 
    116 DHGLRC APIENTRY
    117 DrvCreateContext(HDC hdc)
    118 {
    119    return DrvCreateLayerContext( hdc, 0 );
    120 }
    121 
    122 
    123 DHGLRC APIENTRY
    124 DrvCreateLayerContext(HDC hdc, INT iLayerPlane)
    125 {
    126    return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
    127                                      WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
    128                                      0);
    129 }
    130 
    131 
    132 /**
    133  * Called via DrvCreateContext(), DrvCreateLayerContext() and
    134  * wglCreateContextAttribsARB() to actually create a rendering context.
    135  * \param handle  the desired DHGLRC handle to use for the context, or zero
    136  *                if a new handle should be allocated.
    137  * \return the handle for the new context or zero if there was a problem.
    138  */
    139 DHGLRC
    140 stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
    141                            int majorVersion, int minorVersion,
    142                            int contextFlags, int profileMask,
    143                            DHGLRC handle)
    144 {
    145    int iPixelFormat;
    146    struct stw_framebuffer *fb;
    147    const struct stw_pixelformat_info *pfi;
    148    struct st_context_attribs attribs;
    149    struct stw_context *ctx = NULL;
    150    struct stw_context *shareCtx = NULL;
    151    enum st_context_error ctx_err = 0;
    152 
    153    if (!stw_dev)
    154       return 0;
    155 
    156    if (iLayerPlane != 0)
    157       return 0;
    158 
    159    /*
    160     * GDI only knows about displayable pixel formats, so determine the pixel
    161     * format from the framebuffer.
    162     *
    163     * This also allows to use a OpenGL DLL / ICD without installing.
    164     */
    165    fb = stw_framebuffer_from_hdc( hdc );
    166    if (fb) {
    167       iPixelFormat = fb->iPixelFormat;
    168       stw_framebuffer_unlock(fb);
    169    } else {
    170       return 0;
    171    }
    172 
    173    pfi = stw_pixelformat_get_info( iPixelFormat );
    174 
    175    if (hShareContext != 0) {
    176       stw_lock_contexts(stw_dev);
    177       shareCtx = stw_lookup_context_locked( hShareContext );
    178       stw_unlock_contexts(stw_dev);
    179    }
    180 
    181    ctx = CALLOC_STRUCT( stw_context );
    182    if (ctx == NULL)
    183       goto no_ctx;
    184 
    185    ctx->hdc = hdc;
    186    ctx->iPixelFormat = iPixelFormat;
    187 
    188    memset(&attribs, 0, sizeof(attribs));
    189    attribs.visual = pfi->stvis;
    190    attribs.major = majorVersion;
    191    attribs.minor = minorVersion;
    192    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
    193       attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
    194    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
    195       attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
    196 
    197    switch (profileMask) {
    198    case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
    199       /* There are no profiles before OpenGL 3.2.  The
    200        * WGL_ARB_create_context_profile spec says:
    201        *
    202        *     "If the requested OpenGL version is less than 3.2,
    203        *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
    204        *     of the context is determined solely by the requested version."
    205        */
    206       if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
    207          attribs.profile = ST_PROFILE_OPENGL_CORE;
    208          break;
    209       }
    210       /* fall-through */
    211    case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
    212       /*
    213        * The spec also says:
    214        *
    215        *     "If version 3.1 is requested, the context returned may implement
    216        *     any of the following versions:
    217        *
    218        *       * Version 3.1. The GL_ARB_compatibility extension may or may not
    219        *         be implemented, as determined by the implementation.
    220        *       * The core profile of version 3.2 or greater."
    221        *
    222        * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
    223        * Windows OpenGL implementations do, and unfortunately many Windows
    224        * applications don't check whether they receive or not a context with
    225        * GL_ARB_compatibility, so returning a core profile here does more harm
    226        * than good.
    227        */
    228       attribs.profile = ST_PROFILE_DEFAULT;
    229       break;
    230    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
    231       if (majorVersion >= 2) {
    232          attribs.profile = ST_PROFILE_OPENGL_ES2;
    233       } else {
    234          attribs.profile = ST_PROFILE_OPENGL_ES1;
    235       }
    236       break;
    237    default:
    238       assert(0);
    239       goto no_st_ctx;
    240    }
    241 
    242    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
    243          stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
    244    if (ctx->st == NULL)
    245       goto no_st_ctx;
    246 
    247    ctx->st->st_manager_private = (void *) ctx;
    248 
    249    if (ctx->st->cso_context) {
    250       ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
    251    }
    252 
    253    stw_lock_contexts(stw_dev);
    254    if (handle) {
    255       /* We're replacing the context data for this handle. See the
    256        * wglCreateContextAttribsARB() function.
    257        */
    258       struct stw_context *old_ctx =
    259          stw_lookup_context_locked((unsigned) handle);
    260       if (old_ctx) {
    261          /* free the old context data associated with this handle */
    262          if (old_ctx->hud) {
    263             hud_destroy(old_ctx->hud);
    264          }
    265          ctx->st->destroy(old_ctx->st);
    266          FREE(old_ctx);
    267       }
    268 
    269       /* replace table entry */
    270       handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
    271    }
    272    else {
    273       /* create new table entry */
    274       handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
    275    }
    276 
    277    ctx->dhglrc = handle;
    278 
    279    stw_unlock_contexts(stw_dev);
    280 
    281    if (!ctx->dhglrc)
    282       goto no_hglrc;
    283 
    284    return ctx->dhglrc;
    285 
    286 no_hglrc:
    287    if (ctx->hud) {
    288       hud_destroy(ctx->hud);
    289    }
    290    ctx->st->destroy(ctx->st);
    291 no_st_ctx:
    292    FREE(ctx);
    293 no_ctx:
    294    return 0;
    295 }
    296 
    297 
    298 BOOL APIENTRY
    299 DrvDeleteContext(DHGLRC dhglrc)
    300 {
    301    struct stw_context *ctx ;
    302    BOOL ret = FALSE;
    303 
    304    if (!stw_dev)
    305       return FALSE;
    306 
    307    stw_lock_contexts(stw_dev);
    308    ctx = stw_lookup_context_locked(dhglrc);
    309    handle_table_remove(stw_dev->ctx_table, dhglrc);
    310    stw_unlock_contexts(stw_dev);
    311 
    312    if (ctx) {
    313       struct stw_context *curctx = stw_current_context();
    314 
    315       /* Unbind current if deleting current context. */
    316       if (curctx == ctx)
    317          stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    318 
    319       if (ctx->hud) {
    320          hud_destroy(ctx->hud);
    321       }
    322 
    323       ctx->st->destroy(ctx->st);
    324       FREE(ctx);
    325 
    326       ret = TRUE;
    327    }
    328 
    329    return ret;
    330 }
    331 
    332 
    333 BOOL APIENTRY
    334 DrvReleaseContext(DHGLRC dhglrc)
    335 {
    336    struct stw_context *ctx;
    337 
    338    if (!stw_dev)
    339       return FALSE;
    340 
    341    stw_lock_contexts(stw_dev);
    342    ctx = stw_lookup_context_locked( dhglrc );
    343    stw_unlock_contexts(stw_dev);
    344 
    345    if (!ctx)
    346       return FALSE;
    347 
    348    /* The expectation is that ctx is the same context which is
    349     * current for this thread.  We should check that and return False
    350     * if not the case.
    351     */
    352    if (ctx != stw_current_context())
    353       return FALSE;
    354 
    355    if (stw_make_current( NULL, 0 ) == FALSE)
    356       return FALSE;
    357 
    358    return TRUE;
    359 }
    360 
    361 
    362 DHGLRC
    363 stw_get_current_context( void )
    364 {
    365    struct stw_context *ctx;
    366 
    367    ctx = stw_current_context();
    368    if (!ctx)
    369       return 0;
    370 
    371    return ctx->dhglrc;
    372 }
    373 
    374 
    375 HDC
    376 stw_get_current_dc( void )
    377 {
    378    struct stw_context *ctx;
    379 
    380    ctx = stw_current_context();
    381    if (!ctx)
    382       return NULL;
    383 
    384    return ctx->hdc;
    385 }
    386 
    387 
    388 BOOL
    389 stw_make_current(HDC hdc, DHGLRC dhglrc)
    390 {
    391    struct stw_context *old_ctx = NULL;
    392    struct stw_context *ctx = NULL;
    393    BOOL ret = FALSE;
    394 
    395    if (!stw_dev)
    396       return FALSE;
    397 
    398    old_ctx = stw_current_context();
    399    if (old_ctx != NULL) {
    400       if (old_ctx->dhglrc == dhglrc) {
    401          if (old_ctx->hdc == hdc) {
    402             /* Return if already current. */
    403             return TRUE;
    404          }
    405       } else {
    406          old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL);
    407       }
    408    }
    409 
    410    if (dhglrc) {
    411       struct stw_framebuffer *fb = NULL;
    412       stw_lock_contexts(stw_dev);
    413       ctx = stw_lookup_context_locked( dhglrc );
    414       stw_unlock_contexts(stw_dev);
    415       if (!ctx) {
    416          goto fail;
    417       }
    418 
    419       /* This call locks fb's mutex */
    420       fb = stw_framebuffer_from_hdc( hdc );
    421       if (fb) {
    422          stw_framebuffer_update(fb);
    423       }
    424       else {
    425          /* Applications should call SetPixelFormat before creating a context,
    426           * but not all do, and the opengl32 runtime seems to use a default
    427           * pixel format in some cases, so we must create a framebuffer for
    428           * those here.
    429           */
    430          int iPixelFormat = GetPixelFormat(hdc);
    431          if (iPixelFormat)
    432             fb = stw_framebuffer_create( hdc, iPixelFormat );
    433          if (!fb)
    434             goto fail;
    435       }
    436 
    437       if (fb->iPixelFormat != ctx->iPixelFormat) {
    438          stw_framebuffer_unlock(fb);
    439          SetLastError(ERROR_INVALID_PIXEL_FORMAT);
    440          goto fail;
    441       }
    442 
    443       /* Bind the new framebuffer */
    444       ctx->hdc = hdc;
    445 
    446       struct stw_framebuffer *old_fb = ctx->current_framebuffer;
    447       if (old_fb != fb) {
    448          stw_framebuffer_reference_locked(fb);
    449          ctx->current_framebuffer = fb;
    450       }
    451       stw_framebuffer_unlock(fb);
    452 
    453       /* Note: when we call this function we will wind up in the
    454        * stw_st_framebuffer_validate_locked() function which will incur
    455        * a recursive fb->mutex lock.
    456        */
    457       ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
    458                                          fb->stfb, fb->stfb);
    459 
    460       if (old_fb && old_fb != fb) {
    461          stw_lock_framebuffers(stw_dev);
    462          stw_framebuffer_lock(old_fb);
    463          stw_framebuffer_release_locked(old_fb);
    464          stw_unlock_framebuffers(stw_dev);
    465       }
    466 
    467 fail:
    468       /* fb must be unlocked at this point. */
    469       assert(!stw_own_mutex(&fb->mutex));
    470 
    471       /* On failure, make the thread's current rendering context not current
    472        * before returning.
    473        */
    474       if (!ret) {
    475          stw_make_current(NULL, 0);
    476       }
    477    } else {
    478       ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    479    }
    480 
    481    /* Unreference the previous framebuffer if any. It must be done after
    482     * make_current, as it can be referenced inside.
    483     */
    484    if (old_ctx && old_ctx != ctx) {
    485       struct stw_framebuffer *old_fb = old_ctx->current_framebuffer;
    486       if (old_fb) {
    487          old_ctx->current_framebuffer = NULL;
    488          stw_lock_framebuffers(stw_dev);
    489          stw_framebuffer_lock(old_fb);
    490          stw_framebuffer_release_locked(old_fb);
    491          stw_unlock_framebuffers(stw_dev);
    492       }
    493    }
    494 
    495    return ret;
    496 }
    497 
    498 
    499 /**
    500  * Notify the current context that the framebuffer has become invalid.
    501  */
    502 void
    503 stw_notify_current_locked( struct stw_framebuffer *fb )
    504 {
    505    p_atomic_inc(&fb->stfb->stamp);
    506 }
    507 
    508 
    509 /**
    510  * Although WGL allows different dispatch entrypoints per context
    511  */
    512 static const GLCLTPROCTABLE cpt =
    513 {
    514    OPENGL_VERSION_110_ENTRIES,
    515    {
    516       &glNewList,
    517       &glEndList,
    518       &glCallList,
    519       &glCallLists,
    520       &glDeleteLists,
    521       &glGenLists,
    522       &glListBase,
    523       &glBegin,
    524       &glBitmap,
    525       &glColor3b,
    526       &glColor3bv,
    527       &glColor3d,
    528       &glColor3dv,
    529       &glColor3f,
    530       &glColor3fv,
    531       &glColor3i,
    532       &glColor3iv,
    533       &glColor3s,
    534       &glColor3sv,
    535       &glColor3ub,
    536       &glColor3ubv,
    537       &glColor3ui,
    538       &glColor3uiv,
    539       &glColor3us,
    540       &glColor3usv,
    541       &glColor4b,
    542       &glColor4bv,
    543       &glColor4d,
    544       &glColor4dv,
    545       &glColor4f,
    546       &glColor4fv,
    547       &glColor4i,
    548       &glColor4iv,
    549       &glColor4s,
    550       &glColor4sv,
    551       &glColor4ub,
    552       &glColor4ubv,
    553       &glColor4ui,
    554       &glColor4uiv,
    555       &glColor4us,
    556       &glColor4usv,
    557       &glEdgeFlag,
    558       &glEdgeFlagv,
    559       &glEnd,
    560       &glIndexd,
    561       &glIndexdv,
    562       &glIndexf,
    563       &glIndexfv,
    564       &glIndexi,
    565       &glIndexiv,
    566       &glIndexs,
    567       &glIndexsv,
    568       &glNormal3b,
    569       &glNormal3bv,
    570       &glNormal3d,
    571       &glNormal3dv,
    572       &glNormal3f,
    573       &glNormal3fv,
    574       &glNormal3i,
    575       &glNormal3iv,
    576       &glNormal3s,
    577       &glNormal3sv,
    578       &glRasterPos2d,
    579       &glRasterPos2dv,
    580       &glRasterPos2f,
    581       &glRasterPos2fv,
    582       &glRasterPos2i,
    583       &glRasterPos2iv,
    584       &glRasterPos2s,
    585       &glRasterPos2sv,
    586       &glRasterPos3d,
    587       &glRasterPos3dv,
    588       &glRasterPos3f,
    589       &glRasterPos3fv,
    590       &glRasterPos3i,
    591       &glRasterPos3iv,
    592       &glRasterPos3s,
    593       &glRasterPos3sv,
    594       &glRasterPos4d,
    595       &glRasterPos4dv,
    596       &glRasterPos4f,
    597       &glRasterPos4fv,
    598       &glRasterPos4i,
    599       &glRasterPos4iv,
    600       &glRasterPos4s,
    601       &glRasterPos4sv,
    602       &glRectd,
    603       &glRectdv,
    604       &glRectf,
    605       &glRectfv,
    606       &glRecti,
    607       &glRectiv,
    608       &glRects,
    609       &glRectsv,
    610       &glTexCoord1d,
    611       &glTexCoord1dv,
    612       &glTexCoord1f,
    613       &glTexCoord1fv,
    614       &glTexCoord1i,
    615       &glTexCoord1iv,
    616       &glTexCoord1s,
    617       &glTexCoord1sv,
    618       &glTexCoord2d,
    619       &glTexCoord2dv,
    620       &glTexCoord2f,
    621       &glTexCoord2fv,
    622       &glTexCoord2i,
    623       &glTexCoord2iv,
    624       &glTexCoord2s,
    625       &glTexCoord2sv,
    626       &glTexCoord3d,
    627       &glTexCoord3dv,
    628       &glTexCoord3f,
    629       &glTexCoord3fv,
    630       &glTexCoord3i,
    631       &glTexCoord3iv,
    632       &glTexCoord3s,
    633       &glTexCoord3sv,
    634       &glTexCoord4d,
    635       &glTexCoord4dv,
    636       &glTexCoord4f,
    637       &glTexCoord4fv,
    638       &glTexCoord4i,
    639       &glTexCoord4iv,
    640       &glTexCoord4s,
    641       &glTexCoord4sv,
    642       &glVertex2d,
    643       &glVertex2dv,
    644       &glVertex2f,
    645       &glVertex2fv,
    646       &glVertex2i,
    647       &glVertex2iv,
    648       &glVertex2s,
    649       &glVertex2sv,
    650       &glVertex3d,
    651       &glVertex3dv,
    652       &glVertex3f,
    653       &glVertex3fv,
    654       &glVertex3i,
    655       &glVertex3iv,
    656       &glVertex3s,
    657       &glVertex3sv,
    658       &glVertex4d,
    659       &glVertex4dv,
    660       &glVertex4f,
    661       &glVertex4fv,
    662       &glVertex4i,
    663       &glVertex4iv,
    664       &glVertex4s,
    665       &glVertex4sv,
    666       &glClipPlane,
    667       &glColorMaterial,
    668       &glCullFace,
    669       &glFogf,
    670       &glFogfv,
    671       &glFogi,
    672       &glFogiv,
    673       &glFrontFace,
    674       &glHint,
    675       &glLightf,
    676       &glLightfv,
    677       &glLighti,
    678       &glLightiv,
    679       &glLightModelf,
    680       &glLightModelfv,
    681       &glLightModeli,
    682       &glLightModeliv,
    683       &glLineStipple,
    684       &glLineWidth,
    685       &glMaterialf,
    686       &glMaterialfv,
    687       &glMateriali,
    688       &glMaterialiv,
    689       &glPointSize,
    690       &glPolygonMode,
    691       &glPolygonStipple,
    692       &glScissor,
    693       &glShadeModel,
    694       &glTexParameterf,
    695       &glTexParameterfv,
    696       &glTexParameteri,
    697       &glTexParameteriv,
    698       &glTexImage1D,
    699       &glTexImage2D,
    700       &glTexEnvf,
    701       &glTexEnvfv,
    702       &glTexEnvi,
    703       &glTexEnviv,
    704       &glTexGend,
    705       &glTexGendv,
    706       &glTexGenf,
    707       &glTexGenfv,
    708       &glTexGeni,
    709       &glTexGeniv,
    710       &glFeedbackBuffer,
    711       &glSelectBuffer,
    712       &glRenderMode,
    713       &glInitNames,
    714       &glLoadName,
    715       &glPassThrough,
    716       &glPopName,
    717       &glPushName,
    718       &glDrawBuffer,
    719       &glClear,
    720       &glClearAccum,
    721       &glClearIndex,
    722       &glClearColor,
    723       &glClearStencil,
    724       &glClearDepth,
    725       &glStencilMask,
    726       &glColorMask,
    727       &glDepthMask,
    728       &glIndexMask,
    729       &glAccum,
    730       &glDisable,
    731       &glEnable,
    732       &glFinish,
    733       &glFlush,
    734       &glPopAttrib,
    735       &glPushAttrib,
    736       &glMap1d,
    737       &glMap1f,
    738       &glMap2d,
    739       &glMap2f,
    740       &glMapGrid1d,
    741       &glMapGrid1f,
    742       &glMapGrid2d,
    743       &glMapGrid2f,
    744       &glEvalCoord1d,
    745       &glEvalCoord1dv,
    746       &glEvalCoord1f,
    747       &glEvalCoord1fv,
    748       &glEvalCoord2d,
    749       &glEvalCoord2dv,
    750       &glEvalCoord2f,
    751       &glEvalCoord2fv,
    752       &glEvalMesh1,
    753       &glEvalPoint1,
    754       &glEvalMesh2,
    755       &glEvalPoint2,
    756       &glAlphaFunc,
    757       &glBlendFunc,
    758       &glLogicOp,
    759       &glStencilFunc,
    760       &glStencilOp,
    761       &glDepthFunc,
    762       &glPixelZoom,
    763       &glPixelTransferf,
    764       &glPixelTransferi,
    765       &glPixelStoref,
    766       &glPixelStorei,
    767       &glPixelMapfv,
    768       &glPixelMapuiv,
    769       &glPixelMapusv,
    770       &glReadBuffer,
    771       &glCopyPixels,
    772       &glReadPixels,
    773       &glDrawPixels,
    774       &glGetBooleanv,
    775       &glGetClipPlane,
    776       &glGetDoublev,
    777       &glGetError,
    778       &glGetFloatv,
    779       &glGetIntegerv,
    780       &glGetLightfv,
    781       &glGetLightiv,
    782       &glGetMapdv,
    783       &glGetMapfv,
    784       &glGetMapiv,
    785       &glGetMaterialfv,
    786       &glGetMaterialiv,
    787       &glGetPixelMapfv,
    788       &glGetPixelMapuiv,
    789       &glGetPixelMapusv,
    790       &glGetPolygonStipple,
    791       &glGetString,
    792       &glGetTexEnvfv,
    793       &glGetTexEnviv,
    794       &glGetTexGendv,
    795       &glGetTexGenfv,
    796       &glGetTexGeniv,
    797       &glGetTexImage,
    798       &glGetTexParameterfv,
    799       &glGetTexParameteriv,
    800       &glGetTexLevelParameterfv,
    801       &glGetTexLevelParameteriv,
    802       &glIsEnabled,
    803       &glIsList,
    804       &glDepthRange,
    805       &glFrustum,
    806       &glLoadIdentity,
    807       &glLoadMatrixf,
    808       &glLoadMatrixd,
    809       &glMatrixMode,
    810       &glMultMatrixf,
    811       &glMultMatrixd,
    812       &glOrtho,
    813       &glPopMatrix,
    814       &glPushMatrix,
    815       &glRotated,
    816       &glRotatef,
    817       &glScaled,
    818       &glScalef,
    819       &glTranslated,
    820       &glTranslatef,
    821       &glViewport,
    822       &glArrayElement,
    823       &glBindTexture,
    824       &glColorPointer,
    825       &glDisableClientState,
    826       &glDrawArrays,
    827       &glDrawElements,
    828       &glEdgeFlagPointer,
    829       &glEnableClientState,
    830       &glIndexPointer,
    831       &glIndexub,
    832       &glIndexubv,
    833       &glInterleavedArrays,
    834       &glNormalPointer,
    835       &glPolygonOffset,
    836       &glTexCoordPointer,
    837       &glVertexPointer,
    838       &glAreTexturesResident,
    839       &glCopyTexImage1D,
    840       &glCopyTexImage2D,
    841       &glCopyTexSubImage1D,
    842       &glCopyTexSubImage2D,
    843       &glDeleteTextures,
    844       &glGenTextures,
    845       &glGetPointerv,
    846       &glIsTexture,
    847       &glPrioritizeTextures,
    848       &glTexSubImage1D,
    849       &glTexSubImage2D,
    850       &glPopClientAttrib,
    851       &glPushClientAttrib
    852    }
    853 };
    854 
    855 
    856 PGLCLTPROCTABLE APIENTRY
    857 DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
    858 {
    859    PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
    860 
    861    if (!stw_make_current(hdc, dhglrc))
    862       r = NULL;
    863 
    864    return r;
    865 }
    866