Home | History | Annotate | Download | only in wgl
      1 /**************************************************************************
      2  *
      3  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
      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 TUNGSTEN GRAPHICS 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 
     42 #include "stw_icd.h"
     43 #include "stw_device.h"
     44 #include "stw_winsys.h"
     45 #include "stw_framebuffer.h"
     46 #include "stw_pixelformat.h"
     47 #include "stw_context.h"
     48 #include "stw_tls.h"
     49 
     50 
     51 static INLINE struct stw_context *
     52 stw_current_context(void)
     53 {
     54    struct st_context_iface *st;
     55 
     56    st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
     57 
     58    return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
     59 }
     60 
     61 BOOL APIENTRY
     62 DrvCopyContext(
     63    DHGLRC dhrcSource,
     64    DHGLRC dhrcDest,
     65    UINT fuMask )
     66 {
     67    struct stw_context *src;
     68    struct stw_context *dst;
     69    BOOL ret = FALSE;
     70 
     71    if (!stw_dev)
     72       return FALSE;
     73 
     74    pipe_mutex_lock( stw_dev->ctx_mutex );
     75 
     76    src = stw_lookup_context_locked( dhrcSource );
     77    dst = stw_lookup_context_locked( dhrcDest );
     78 
     79    if (src && dst) {
     80       /* FIXME */
     81       assert(0);
     82       (void) src;
     83       (void) dst;
     84       (void) fuMask;
     85    }
     86 
     87    pipe_mutex_unlock( stw_dev->ctx_mutex );
     88 
     89    return ret;
     90 }
     91 
     92 BOOL APIENTRY
     93 DrvShareLists(
     94    DHGLRC dhglrc1,
     95    DHGLRC dhglrc2 )
     96 {
     97    struct stw_context *ctx1;
     98    struct stw_context *ctx2;
     99    BOOL ret = FALSE;
    100 
    101    if (!stw_dev)
    102       return FALSE;
    103 
    104    pipe_mutex_lock( stw_dev->ctx_mutex );
    105 
    106    ctx1 = stw_lookup_context_locked( dhglrc1 );
    107    ctx2 = stw_lookup_context_locked( dhglrc2 );
    108 
    109    if (ctx1 && ctx2 && ctx2->st->share)
    110       ret = ctx2->st->share(ctx2->st, ctx1->st);
    111 
    112    pipe_mutex_unlock( stw_dev->ctx_mutex );
    113 
    114    return ret;
    115 }
    116 
    117 DHGLRC APIENTRY
    118 DrvCreateContext(
    119    HDC hdc )
    120 {
    121    return DrvCreateLayerContext( hdc, 0 );
    122 }
    123 
    124 DHGLRC APIENTRY
    125 DrvCreateLayerContext(
    126    HDC hdc,
    127    INT iLayerPlane )
    128 {
    129    return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
    130                                      WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
    131 }
    132 
    133 DHGLRC
    134 stw_create_context_attribs(
    135    HDC hdc,
    136    INT iLayerPlane,
    137    DHGLRC hShareContext,
    138    int majorVersion, int minorVersion,
    139    int contextFlags, int profileMask)
    140 {
    141    int iPixelFormat;
    142    struct stw_framebuffer *fb;
    143    const struct stw_pixelformat_info *pfi;
    144    struct st_context_attribs attribs;
    145    struct stw_context *ctx = NULL;
    146    struct stw_context *shareCtx = NULL;
    147    enum st_context_error ctx_err = 0;
    148 
    149    if (!stw_dev)
    150       return 0;
    151 
    152    if (iLayerPlane != 0)
    153       return 0;
    154 
    155    iPixelFormat = GetPixelFormat(hdc);
    156    if(!iPixelFormat)
    157       return 0;
    158 
    159    /*
    160     * GDI only knows about displayable pixel formats, so determine the pixel
    161     * format from the framebuffer.
    162     *
    163     * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
    164     */
    165    fb = stw_framebuffer_from_hdc( hdc );
    166    if (fb) {
    167       assert(iPixelFormat == fb->iDisplayablePixelFormat);
    168       iPixelFormat = fb->iPixelFormat;
    169       stw_framebuffer_release(fb);
    170    }
    171 
    172    pfi = stw_pixelformat_get_info( iPixelFormat );
    173 
    174    if (hShareContext != 0) {
    175       pipe_mutex_lock( stw_dev->ctx_mutex );
    176       shareCtx = stw_lookup_context_locked( hShareContext );
    177       pipe_mutex_unlock( stw_dev->ctx_mutex );
    178    }
    179 
    180    ctx = CALLOC_STRUCT( stw_context );
    181    if (ctx == NULL)
    182       goto no_ctx;
    183 
    184    ctx->hdc = hdc;
    185    ctx->iPixelFormat = iPixelFormat;
    186 
    187    memset(&attribs, 0, sizeof(attribs));
    188    attribs.visual = pfi->stvis;
    189    attribs.major = majorVersion;
    190    attribs.minor = minorVersion;
    191    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
    192       attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
    193    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
    194       attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
    195 
    196    /* There are no profiles before OpenGL 3.2.  The
    197     * WGL_ARB_create_context_profile spec says:
    198     *
    199     *     "If the requested OpenGL version is less than 3.2,
    200     *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
    201     *     context is determined solely by the requested version."
    202     *
    203     * The spec also says:
    204     *
    205     *     "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is
    206     *     WGL_CONTEXT_CORE_PROFILE_BIT_ARB."
    207     */
    208    attribs.profile = ST_PROFILE_DEFAULT;
    209    if ((majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2))
    210        && ((profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0))
    211       attribs.profile = ST_PROFILE_OPENGL_CORE;
    212 
    213    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
    214          stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
    215    if (ctx->st == NULL)
    216       goto no_st_ctx;
    217 
    218    ctx->st->st_manager_private = (void *) ctx;
    219 
    220    pipe_mutex_lock( stw_dev->ctx_mutex );
    221    ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
    222    pipe_mutex_unlock( stw_dev->ctx_mutex );
    223    if (!ctx->dhglrc)
    224       goto no_hglrc;
    225 
    226    return ctx->dhglrc;
    227 
    228 no_hglrc:
    229    ctx->st->destroy(ctx->st);
    230 no_st_ctx:
    231    FREE(ctx);
    232 no_ctx:
    233    return 0;
    234 }
    235 
    236 BOOL APIENTRY
    237 DrvDeleteContext(
    238    DHGLRC dhglrc )
    239 {
    240    struct stw_context *ctx ;
    241    BOOL ret = FALSE;
    242 
    243    if (!stw_dev)
    244       return FALSE;
    245 
    246    pipe_mutex_lock( stw_dev->ctx_mutex );
    247    ctx = stw_lookup_context_locked(dhglrc);
    248    handle_table_remove(stw_dev->ctx_table, dhglrc);
    249    pipe_mutex_unlock( stw_dev->ctx_mutex );
    250 
    251    if (ctx) {
    252       struct stw_context *curctx = stw_current_context();
    253 
    254       /* Unbind current if deleting current context. */
    255       if (curctx == ctx)
    256          stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    257 
    258       ctx->st->destroy(ctx->st);
    259       FREE(ctx);
    260 
    261       ret = TRUE;
    262    }
    263 
    264    return ret;
    265 }
    266 
    267 BOOL APIENTRY
    268 DrvReleaseContext(
    269    DHGLRC dhglrc )
    270 {
    271    struct stw_context *ctx;
    272 
    273    if (!stw_dev)
    274       return FALSE;
    275 
    276    pipe_mutex_lock( stw_dev->ctx_mutex );
    277    ctx = stw_lookup_context_locked( dhglrc );
    278    pipe_mutex_unlock( stw_dev->ctx_mutex );
    279 
    280    if (!ctx)
    281       return FALSE;
    282 
    283    /* The expectation is that ctx is the same context which is
    284     * current for this thread.  We should check that and return False
    285     * if not the case.
    286     */
    287    if (ctx != stw_current_context())
    288       return FALSE;
    289 
    290    if (stw_make_current( NULL, 0 ) == FALSE)
    291       return FALSE;
    292 
    293    return TRUE;
    294 }
    295 
    296 
    297 DHGLRC
    298 stw_get_current_context( void )
    299 {
    300    struct stw_context *ctx;
    301 
    302    ctx = stw_current_context();
    303    if(!ctx)
    304       return 0;
    305 
    306    return ctx->dhglrc;
    307 }
    308 
    309 HDC
    310 stw_get_current_dc( void )
    311 {
    312    struct stw_context *ctx;
    313 
    314    ctx = stw_current_context();
    315    if(!ctx)
    316       return NULL;
    317 
    318    return ctx->hdc;
    319 }
    320 
    321 BOOL
    322 stw_make_current(
    323    HDC hdc,
    324    DHGLRC dhglrc )
    325 {
    326    struct stw_context *curctx = NULL;
    327    struct stw_context *ctx = NULL;
    328    struct stw_framebuffer *fb = NULL;
    329    BOOL ret = FALSE;
    330 
    331    if (!stw_dev)
    332       return FALSE;
    333 
    334    curctx = stw_current_context();
    335    if (curctx != NULL) {
    336       if (curctx->dhglrc == dhglrc) {
    337          if (curctx->hdc == hdc) {
    338             /* Return if already current. */
    339             return TRUE;
    340          }
    341       } else {
    342          curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
    343       }
    344    }
    345 
    346    if (dhglrc) {
    347       pipe_mutex_lock( stw_dev->ctx_mutex );
    348       ctx = stw_lookup_context_locked( dhglrc );
    349       pipe_mutex_unlock( stw_dev->ctx_mutex );
    350       if (!ctx) {
    351          goto fail;
    352       }
    353 
    354       fb = stw_framebuffer_from_hdc( hdc );
    355       if (fb) {
    356          stw_framebuffer_update(fb);
    357       }
    358       else {
    359          /* Applications should call SetPixelFormat before creating a context,
    360           * but not all do, and the opengl32 runtime seems to use a default pixel
    361           * format in some cases, so we must create a framebuffer for those here
    362           */
    363          int iPixelFormat = GetPixelFormat(hdc);
    364          if (iPixelFormat)
    365             fb = stw_framebuffer_create( hdc, iPixelFormat );
    366          if (!fb)
    367             goto fail;
    368       }
    369 
    370       if (fb->iPixelFormat != ctx->iPixelFormat) {
    371          SetLastError(ERROR_INVALID_PIXEL_FORMAT);
    372          goto fail;
    373       }
    374 
    375       /* Bind the new framebuffer */
    376       ctx->hdc = hdc;
    377 
    378       ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
    379                                          fb->stfb, fb->stfb);
    380       stw_framebuffer_reference(&ctx->current_framebuffer, fb);
    381    } else {
    382       ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    383    }
    384 
    385 fail:
    386 
    387    if (fb) {
    388       stw_framebuffer_release(fb);
    389    }
    390 
    391    /* On failure, make the thread's current rendering context not current
    392     * before returning */
    393    if (!ret) {
    394       stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    395       ctx = NULL;
    396    }
    397 
    398    /* Unreference the previous framebuffer if any. It must be done after
    399     * make_current, as it can be referenced inside.
    400     */
    401    if (curctx && curctx != ctx) {
    402       stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
    403    }
    404 
    405    return ret;
    406 }
    407 
    408 /**
    409  * Flush the current context if it is bound to the framebuffer.
    410  */
    411 void
    412 stw_flush_current_locked( struct stw_framebuffer *fb )
    413 {
    414    struct stw_context *ctx = stw_current_context();
    415 
    416    if (ctx && ctx->current_framebuffer == fb) {
    417       ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
    418    }
    419 }
    420 
    421 /**
    422  * Notify the current context that the framebuffer has become invalid.
    423  */
    424 void
    425 stw_notify_current_locked( struct stw_framebuffer *fb )
    426 {
    427    p_atomic_inc(&fb->stfb->stamp);
    428 }
    429 
    430 /**
    431  * Although WGL allows different dispatch entrypoints per context
    432  */
    433 static const GLCLTPROCTABLE cpt =
    434 {
    435    OPENGL_VERSION_110_ENTRIES,
    436    {
    437       &glNewList,
    438       &glEndList,
    439       &glCallList,
    440       &glCallLists,
    441       &glDeleteLists,
    442       &glGenLists,
    443       &glListBase,
    444       &glBegin,
    445       &glBitmap,
    446       &glColor3b,
    447       &glColor3bv,
    448       &glColor3d,
    449       &glColor3dv,
    450       &glColor3f,
    451       &glColor3fv,
    452       &glColor3i,
    453       &glColor3iv,
    454       &glColor3s,
    455       &glColor3sv,
    456       &glColor3ub,
    457       &glColor3ubv,
    458       &glColor3ui,
    459       &glColor3uiv,
    460       &glColor3us,
    461       &glColor3usv,
    462       &glColor4b,
    463       &glColor4bv,
    464       &glColor4d,
    465       &glColor4dv,
    466       &glColor4f,
    467       &glColor4fv,
    468       &glColor4i,
    469       &glColor4iv,
    470       &glColor4s,
    471       &glColor4sv,
    472       &glColor4ub,
    473       &glColor4ubv,
    474       &glColor4ui,
    475       &glColor4uiv,
    476       &glColor4us,
    477       &glColor4usv,
    478       &glEdgeFlag,
    479       &glEdgeFlagv,
    480       &glEnd,
    481       &glIndexd,
    482       &glIndexdv,
    483       &glIndexf,
    484       &glIndexfv,
    485       &glIndexi,
    486       &glIndexiv,
    487       &glIndexs,
    488       &glIndexsv,
    489       &glNormal3b,
    490       &glNormal3bv,
    491       &glNormal3d,
    492       &glNormal3dv,
    493       &glNormal3f,
    494       &glNormal3fv,
    495       &glNormal3i,
    496       &glNormal3iv,
    497       &glNormal3s,
    498       &glNormal3sv,
    499       &glRasterPos2d,
    500       &glRasterPos2dv,
    501       &glRasterPos2f,
    502       &glRasterPos2fv,
    503       &glRasterPos2i,
    504       &glRasterPos2iv,
    505       &glRasterPos2s,
    506       &glRasterPos2sv,
    507       &glRasterPos3d,
    508       &glRasterPos3dv,
    509       &glRasterPos3f,
    510       &glRasterPos3fv,
    511       &glRasterPos3i,
    512       &glRasterPos3iv,
    513       &glRasterPos3s,
    514       &glRasterPos3sv,
    515       &glRasterPos4d,
    516       &glRasterPos4dv,
    517       &glRasterPos4f,
    518       &glRasterPos4fv,
    519       &glRasterPos4i,
    520       &glRasterPos4iv,
    521       &glRasterPos4s,
    522       &glRasterPos4sv,
    523       &glRectd,
    524       &glRectdv,
    525       &glRectf,
    526       &glRectfv,
    527       &glRecti,
    528       &glRectiv,
    529       &glRects,
    530       &glRectsv,
    531       &glTexCoord1d,
    532       &glTexCoord1dv,
    533       &glTexCoord1f,
    534       &glTexCoord1fv,
    535       &glTexCoord1i,
    536       &glTexCoord1iv,
    537       &glTexCoord1s,
    538       &glTexCoord1sv,
    539       &glTexCoord2d,
    540       &glTexCoord2dv,
    541       &glTexCoord2f,
    542       &glTexCoord2fv,
    543       &glTexCoord2i,
    544       &glTexCoord2iv,
    545       &glTexCoord2s,
    546       &glTexCoord2sv,
    547       &glTexCoord3d,
    548       &glTexCoord3dv,
    549       &glTexCoord3f,
    550       &glTexCoord3fv,
    551       &glTexCoord3i,
    552       &glTexCoord3iv,
    553       &glTexCoord3s,
    554       &glTexCoord3sv,
    555       &glTexCoord4d,
    556       &glTexCoord4dv,
    557       &glTexCoord4f,
    558       &glTexCoord4fv,
    559       &glTexCoord4i,
    560       &glTexCoord4iv,
    561       &glTexCoord4s,
    562       &glTexCoord4sv,
    563       &glVertex2d,
    564       &glVertex2dv,
    565       &glVertex2f,
    566       &glVertex2fv,
    567       &glVertex2i,
    568       &glVertex2iv,
    569       &glVertex2s,
    570       &glVertex2sv,
    571       &glVertex3d,
    572       &glVertex3dv,
    573       &glVertex3f,
    574       &glVertex3fv,
    575       &glVertex3i,
    576       &glVertex3iv,
    577       &glVertex3s,
    578       &glVertex3sv,
    579       &glVertex4d,
    580       &glVertex4dv,
    581       &glVertex4f,
    582       &glVertex4fv,
    583       &glVertex4i,
    584       &glVertex4iv,
    585       &glVertex4s,
    586       &glVertex4sv,
    587       &glClipPlane,
    588       &glColorMaterial,
    589       &glCullFace,
    590       &glFogf,
    591       &glFogfv,
    592       &glFogi,
    593       &glFogiv,
    594       &glFrontFace,
    595       &glHint,
    596       &glLightf,
    597       &glLightfv,
    598       &glLighti,
    599       &glLightiv,
    600       &glLightModelf,
    601       &glLightModelfv,
    602       &glLightModeli,
    603       &glLightModeliv,
    604       &glLineStipple,
    605       &glLineWidth,
    606       &glMaterialf,
    607       &glMaterialfv,
    608       &glMateriali,
    609       &glMaterialiv,
    610       &glPointSize,
    611       &glPolygonMode,
    612       &glPolygonStipple,
    613       &glScissor,
    614       &glShadeModel,
    615       &glTexParameterf,
    616       &glTexParameterfv,
    617       &glTexParameteri,
    618       &glTexParameteriv,
    619       &glTexImage1D,
    620       &glTexImage2D,
    621       &glTexEnvf,
    622       &glTexEnvfv,
    623       &glTexEnvi,
    624       &glTexEnviv,
    625       &glTexGend,
    626       &glTexGendv,
    627       &glTexGenf,
    628       &glTexGenfv,
    629       &glTexGeni,
    630       &glTexGeniv,
    631       &glFeedbackBuffer,
    632       &glSelectBuffer,
    633       &glRenderMode,
    634       &glInitNames,
    635       &glLoadName,
    636       &glPassThrough,
    637       &glPopName,
    638       &glPushName,
    639       &glDrawBuffer,
    640       &glClear,
    641       &glClearAccum,
    642       &glClearIndex,
    643       &glClearColor,
    644       &glClearStencil,
    645       &glClearDepth,
    646       &glStencilMask,
    647       &glColorMask,
    648       &glDepthMask,
    649       &glIndexMask,
    650       &glAccum,
    651       &glDisable,
    652       &glEnable,
    653       &glFinish,
    654       &glFlush,
    655       &glPopAttrib,
    656       &glPushAttrib,
    657       &glMap1d,
    658       &glMap1f,
    659       &glMap2d,
    660       &glMap2f,
    661       &glMapGrid1d,
    662       &glMapGrid1f,
    663       &glMapGrid2d,
    664       &glMapGrid2f,
    665       &glEvalCoord1d,
    666       &glEvalCoord1dv,
    667       &glEvalCoord1f,
    668       &glEvalCoord1fv,
    669       &glEvalCoord2d,
    670       &glEvalCoord2dv,
    671       &glEvalCoord2f,
    672       &glEvalCoord2fv,
    673       &glEvalMesh1,
    674       &glEvalPoint1,
    675       &glEvalMesh2,
    676       &glEvalPoint2,
    677       &glAlphaFunc,
    678       &glBlendFunc,
    679       &glLogicOp,
    680       &glStencilFunc,
    681       &glStencilOp,
    682       &glDepthFunc,
    683       &glPixelZoom,
    684       &glPixelTransferf,
    685       &glPixelTransferi,
    686       &glPixelStoref,
    687       &glPixelStorei,
    688       &glPixelMapfv,
    689       &glPixelMapuiv,
    690       &glPixelMapusv,
    691       &glReadBuffer,
    692       &glCopyPixels,
    693       &glReadPixels,
    694       &glDrawPixels,
    695       &glGetBooleanv,
    696       &glGetClipPlane,
    697       &glGetDoublev,
    698       &glGetError,
    699       &glGetFloatv,
    700       &glGetIntegerv,
    701       &glGetLightfv,
    702       &glGetLightiv,
    703       &glGetMapdv,
    704       &glGetMapfv,
    705       &glGetMapiv,
    706       &glGetMaterialfv,
    707       &glGetMaterialiv,
    708       &glGetPixelMapfv,
    709       &glGetPixelMapuiv,
    710       &glGetPixelMapusv,
    711       &glGetPolygonStipple,
    712       &glGetString,
    713       &glGetTexEnvfv,
    714       &glGetTexEnviv,
    715       &glGetTexGendv,
    716       &glGetTexGenfv,
    717       &glGetTexGeniv,
    718       &glGetTexImage,
    719       &glGetTexParameterfv,
    720       &glGetTexParameteriv,
    721       &glGetTexLevelParameterfv,
    722       &glGetTexLevelParameteriv,
    723       &glIsEnabled,
    724       &glIsList,
    725       &glDepthRange,
    726       &glFrustum,
    727       &glLoadIdentity,
    728       &glLoadMatrixf,
    729       &glLoadMatrixd,
    730       &glMatrixMode,
    731       &glMultMatrixf,
    732       &glMultMatrixd,
    733       &glOrtho,
    734       &glPopMatrix,
    735       &glPushMatrix,
    736       &glRotated,
    737       &glRotatef,
    738       &glScaled,
    739       &glScalef,
    740       &glTranslated,
    741       &glTranslatef,
    742       &glViewport,
    743       &glArrayElement,
    744       &glBindTexture,
    745       &glColorPointer,
    746       &glDisableClientState,
    747       &glDrawArrays,
    748       &glDrawElements,
    749       &glEdgeFlagPointer,
    750       &glEnableClientState,
    751       &glIndexPointer,
    752       &glIndexub,
    753       &glIndexubv,
    754       &glInterleavedArrays,
    755       &glNormalPointer,
    756       &glPolygonOffset,
    757       &glTexCoordPointer,
    758       &glVertexPointer,
    759       &glAreTexturesResident,
    760       &glCopyTexImage1D,
    761       &glCopyTexImage2D,
    762       &glCopyTexSubImage1D,
    763       &glCopyTexSubImage2D,
    764       &glDeleteTextures,
    765       &glGenTextures,
    766       &glGetPointerv,
    767       &glIsTexture,
    768       &glPrioritizeTextures,
    769       &glTexSubImage1D,
    770       &glTexSubImage2D,
    771       &glPopClientAttrib,
    772       &glPushClientAttrib
    773    }
    774 };
    775 
    776 PGLCLTPROCTABLE APIENTRY
    777 DrvSetContext(
    778    HDC hdc,
    779    DHGLRC dhglrc,
    780    PFN_SETPROCTABLE pfnSetProcTable )
    781 {
    782    PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
    783 
    784    if (!stw_make_current( hdc, dhglrc ))
    785       r = NULL;
    786 
    787    return r;
    788 }
    789