• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
stw_current_context(void)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
DrvCopyContext(DHGLRC dhrcSource,DHGLRC dhrcDest,UINT fuMask)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
DrvShareLists(DHGLRC dhglrc1,DHGLRC dhglrc2)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
DrvCreateContext(HDC hdc)117 DrvCreateContext(HDC hdc)
118 {
119    return DrvCreateLayerContext( hdc, 0 );
120 }
121 
122 
123 DHGLRC APIENTRY
DrvCreateLayerContext(HDC hdc,INT iLayerPlane)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
stw_create_context_attribs(HDC hdc,INT iLayerPlane,DHGLRC hShareContext,int majorVersion,int minorVersion,int contextFlags,int profileMask,DHGLRC handle)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
DrvDeleteContext(DHGLRC dhglrc)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
DrvReleaseContext(DHGLRC dhglrc)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
stw_get_current_context(void)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
stw_get_current_dc(void)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
stw_make_current(HDC hdc,DHGLRC dhglrc)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
stw_notify_current_locked(struct stw_framebuffer * fb)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
DrvSetContext(HDC hdc,DHGLRC dhglrc,PFN_SETPROCTABLE pfnSetProcTable)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