• 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       ctx1->shared = TRUE;
110       ctx2->shared = TRUE;
111    }
112 
113    stw_unlock_contexts(stw_dev);
114 
115    return ret;
116 }
117 
118 
119 DHGLRC APIENTRY
DrvCreateContext(HDC hdc)120 DrvCreateContext(HDC hdc)
121 {
122    return DrvCreateLayerContext( hdc, 0 );
123 }
124 
125 
126 DHGLRC APIENTRY
DrvCreateLayerContext(HDC hdc,INT iLayerPlane)127 DrvCreateLayerContext(HDC hdc, INT iLayerPlane)
128 {
129    return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
130                                      WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
131                                      0);
132 }
133 
134 
135 /**
136  * Return the stw pixel format that most closely matches the pixel format
137  * on HDC.
138  * Used to get a pixel format when SetPixelFormat() hasn't been called before.
139  */
140 static int
get_matching_pixel_format(HDC hdc)141 get_matching_pixel_format(HDC hdc)
142 {
143    int iPixelFormat = GetPixelFormat(hdc);
144    PIXELFORMATDESCRIPTOR pfd;
145 
146    if (!iPixelFormat)
147       return 0;
148    if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd))
149       return 0;
150    return stw_pixelformat_choose(hdc, &pfd);
151 }
152 
153 
154 /**
155  * Called via DrvCreateContext(), DrvCreateLayerContext() and
156  * wglCreateContextAttribsARB() to actually create a rendering context.
157  * \param handle  the desired DHGLRC handle to use for the context, or zero
158  *                if a new handle should be allocated.
159  * \return the handle for the new context or zero if there was a problem.
160  */
161 DHGLRC
stw_create_context_attribs(HDC hdc,INT iLayerPlane,DHGLRC hShareContext,int majorVersion,int minorVersion,int contextFlags,int profileMask,DHGLRC handle)162 stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
163                            int majorVersion, int minorVersion,
164                            int contextFlags, int profileMask,
165                            DHGLRC handle)
166 {
167    int iPixelFormat;
168    struct stw_framebuffer *fb;
169    const struct stw_pixelformat_info *pfi;
170    struct st_context_attribs attribs;
171    struct stw_context *ctx = NULL;
172    struct stw_context *shareCtx = NULL;
173    enum st_context_error ctx_err = 0;
174 
175    if (!stw_dev)
176       return 0;
177 
178    if (iLayerPlane != 0)
179       return 0;
180 
181    /*
182     * GDI only knows about displayable pixel formats, so determine the pixel
183     * format from the framebuffer.
184     *
185     * This also allows to use a OpenGL DLL / ICD without installing.
186     */
187    fb = stw_framebuffer_from_hdc( hdc );
188    if (fb) {
189       iPixelFormat = fb->iPixelFormat;
190       stw_framebuffer_unlock(fb);
191    } else {
192       /* Applications should call SetPixelFormat before creating a context,
193        * but not all do, and the opengl32 runtime seems to use a default
194        * pixel format in some cases, so use that.
195        */
196       iPixelFormat = get_matching_pixel_format(hdc);
197       if (!iPixelFormat)
198          return 0;
199    }
200 
201    pfi = stw_pixelformat_get_info( iPixelFormat );
202 
203    if (hShareContext != 0) {
204       stw_lock_contexts(stw_dev);
205       shareCtx = stw_lookup_context_locked( hShareContext );
206       shareCtx->shared = TRUE;
207       stw_unlock_contexts(stw_dev);
208    }
209 
210    ctx = CALLOC_STRUCT( stw_context );
211    if (ctx == NULL)
212       goto no_ctx;
213 
214    ctx->hDrawDC = hdc;
215    ctx->hReadDC = hdc;
216    ctx->iPixelFormat = iPixelFormat;
217    ctx->shared = shareCtx != NULL;
218 
219    memset(&attribs, 0, sizeof(attribs));
220    attribs.visual = pfi->stvis;
221    attribs.major = majorVersion;
222    attribs.minor = minorVersion;
223    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
224       attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
225    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
226       attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
227 
228    switch (profileMask) {
229    case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
230       /* There are no profiles before OpenGL 3.2.  The
231        * WGL_ARB_create_context_profile spec says:
232        *
233        *     "If the requested OpenGL version is less than 3.2,
234        *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
235        *     of the context is determined solely by the requested version."
236        */
237       if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
238          attribs.profile = ST_PROFILE_OPENGL_CORE;
239          break;
240       }
241       /* fall-through */
242    case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
243       /*
244        * The spec also says:
245        *
246        *     "If version 3.1 is requested, the context returned may implement
247        *     any of the following versions:
248        *
249        *       * Version 3.1. The GL_ARB_compatibility extension may or may not
250        *         be implemented, as determined by the implementation.
251        *       * The core profile of version 3.2 or greater."
252        *
253        * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
254        * Windows OpenGL implementations do, and unfortunately many Windows
255        * applications don't check whether they receive or not a context with
256        * GL_ARB_compatibility, so returning a core profile here does more harm
257        * than good.
258        */
259       attribs.profile = ST_PROFILE_DEFAULT;
260       break;
261    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
262       if (majorVersion >= 2) {
263          attribs.profile = ST_PROFILE_OPENGL_ES2;
264       } else {
265          attribs.profile = ST_PROFILE_OPENGL_ES1;
266       }
267       break;
268    default:
269       assert(0);
270       goto no_st_ctx;
271    }
272 
273    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
274          stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
275    if (ctx->st == NULL)
276       goto no_st_ctx;
277 
278    ctx->st->st_manager_private = (void *) ctx;
279 
280    if (ctx->st->cso_context) {
281       ctx->hud = hud_create(ctx->st->cso_context, NULL);
282    }
283 
284    stw_lock_contexts(stw_dev);
285    if (handle) {
286       /* We're replacing the context data for this handle. See the
287        * wglCreateContextAttribsARB() function.
288        */
289       struct stw_context *old_ctx =
290          stw_lookup_context_locked((unsigned) handle);
291       if (old_ctx) {
292          /* free the old context data associated with this handle */
293          if (old_ctx->hud) {
294             hud_destroy(old_ctx->hud, NULL);
295          }
296          ctx->st->destroy(old_ctx->st);
297          FREE(old_ctx);
298       }
299 
300       /* replace table entry */
301       handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
302    }
303    else {
304       /* create new table entry */
305       handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
306    }
307 
308    ctx->dhglrc = handle;
309 
310    stw_unlock_contexts(stw_dev);
311 
312    if (!ctx->dhglrc)
313       goto no_hglrc;
314 
315    return ctx->dhglrc;
316 
317 no_hglrc:
318    if (ctx->hud) {
319       hud_destroy(ctx->hud, NULL);
320    }
321    ctx->st->destroy(ctx->st);
322 no_st_ctx:
323    FREE(ctx);
324 no_ctx:
325    return 0;
326 }
327 
328 
329 BOOL APIENTRY
DrvDeleteContext(DHGLRC dhglrc)330 DrvDeleteContext(DHGLRC dhglrc)
331 {
332    struct stw_context *ctx ;
333    BOOL ret = FALSE;
334 
335    if (!stw_dev)
336       return FALSE;
337 
338    stw_lock_contexts(stw_dev);
339    ctx = stw_lookup_context_locked(dhglrc);
340    handle_table_remove(stw_dev->ctx_table, dhglrc);
341    stw_unlock_contexts(stw_dev);
342 
343    if (ctx) {
344       struct stw_context *curctx = stw_current_context();
345 
346       /* Unbind current if deleting current context. */
347       if (curctx == ctx)
348          stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
349 
350       if (ctx->hud) {
351          hud_destroy(ctx->hud, NULL);
352       }
353 
354       ctx->st->destroy(ctx->st);
355       FREE(ctx);
356 
357       ret = TRUE;
358    }
359 
360    return ret;
361 }
362 
363 
364 BOOL APIENTRY
DrvReleaseContext(DHGLRC dhglrc)365 DrvReleaseContext(DHGLRC dhglrc)
366 {
367    struct stw_context *ctx;
368 
369    if (!stw_dev)
370       return FALSE;
371 
372    stw_lock_contexts(stw_dev);
373    ctx = stw_lookup_context_locked( dhglrc );
374    stw_unlock_contexts(stw_dev);
375 
376    if (!ctx)
377       return FALSE;
378 
379    /* The expectation is that ctx is the same context which is
380     * current for this thread.  We should check that and return False
381     * if not the case.
382     */
383    if (ctx != stw_current_context())
384       return FALSE;
385 
386    if (stw_make_current( NULL, NULL, 0 ) == FALSE)
387       return FALSE;
388 
389    return TRUE;
390 }
391 
392 
393 DHGLRC
stw_get_current_context(void)394 stw_get_current_context( void )
395 {
396    struct stw_context *ctx;
397 
398    ctx = stw_current_context();
399    if (!ctx)
400       return 0;
401 
402    return ctx->dhglrc;
403 }
404 
405 
406 HDC
stw_get_current_dc(void)407 stw_get_current_dc( void )
408 {
409    struct stw_context *ctx;
410 
411    ctx = stw_current_context();
412    if (!ctx)
413       return NULL;
414 
415    return ctx->hDrawDC;
416 }
417 
418 HDC
stw_get_current_read_dc(void)419 stw_get_current_read_dc( void )
420 {
421    struct stw_context *ctx;
422 
423    ctx = stw_current_context();
424    if (!ctx)
425       return NULL;
426 
427    return ctx->hReadDC;
428 }
429 
430 BOOL
stw_make_current(HDC hDrawDC,HDC hReadDC,DHGLRC dhglrc)431 stw_make_current(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc)
432 {
433    struct stw_context *old_ctx = NULL;
434    struct stw_context *ctx = NULL;
435    BOOL ret = FALSE;
436 
437    if (!stw_dev)
438       return FALSE;
439 
440    old_ctx = stw_current_context();
441    if (old_ctx != NULL) {
442       if (old_ctx->dhglrc == dhglrc) {
443          if (old_ctx->hDrawDC == hDrawDC && old_ctx->hReadDC == hReadDC) {
444             /* Return if already current. */
445             return TRUE;
446          }
447       } else {
448          if (old_ctx->shared) {
449             struct pipe_fence_handle *fence = NULL;
450             old_ctx->st->flush(old_ctx->st,
451                                ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence);
452          }
453          else {
454             old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL);
455          }
456       }
457    }
458 
459    if (dhglrc) {
460       struct stw_framebuffer *fb = NULL;
461       struct stw_framebuffer *fbRead = NULL;
462       stw_lock_contexts(stw_dev);
463       ctx = stw_lookup_context_locked( dhglrc );
464       stw_unlock_contexts(stw_dev);
465       if (!ctx) {
466          goto fail;
467       }
468 
469       /* This call locks fb's mutex */
470       fb = stw_framebuffer_from_hdc( hDrawDC );
471       if (fb) {
472          stw_framebuffer_update(fb);
473       }
474       else {
475          /* Applications should call SetPixelFormat before creating a context,
476           * but not all do, and the opengl32 runtime seems to use a default
477           * pixel format in some cases, so we must create a framebuffer for
478           * those here.
479           */
480          int iPixelFormat = get_matching_pixel_format(hDrawDC);
481          if (iPixelFormat)
482             fb = stw_framebuffer_create( hDrawDC, iPixelFormat );
483          if (!fb)
484             goto fail;
485       }
486 
487       if (fb->iPixelFormat != ctx->iPixelFormat) {
488          stw_framebuffer_unlock(fb);
489          SetLastError(ERROR_INVALID_PIXEL_FORMAT);
490          goto fail;
491       }
492 
493       /* Bind the new framebuffer */
494       ctx->hDrawDC = hDrawDC;
495       ctx->hReadDC = hReadDC;
496 
497       struct stw_framebuffer *old_fb = ctx->current_framebuffer;
498       if (old_fb != fb) {
499          stw_framebuffer_reference_locked(fb);
500          ctx->current_framebuffer = fb;
501       }
502       stw_framebuffer_unlock(fb);
503 
504       if (hReadDC) {
505          if (hReadDC == hDrawDC) {
506             fbRead = fb;
507          }
508          else {
509             fbRead = stw_framebuffer_from_hdc( hReadDC );
510 
511             if (fbRead) {
512                stw_framebuffer_update(fbRead);
513             }
514             else {
515                /* Applications should call SetPixelFormat before creating a
516                 * context, but not all do, and the opengl32 runtime seems to
517                 * use a default pixel format in some cases, so we must create
518                 * a framebuffer for those here.
519                 */
520                int iPixelFormat = GetPixelFormat(hReadDC);
521                if (iPixelFormat)
522                   fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
523                if (!fbRead)
524                   goto fail;
525             }
526 
527             if (fbRead->iPixelFormat != ctx->iPixelFormat) {
528                stw_framebuffer_unlock(fbRead);
529                SetLastError(ERROR_INVALID_PIXEL_FORMAT);
530                goto fail;
531             }
532             stw_framebuffer_unlock(fbRead);
533          }
534          ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
535                                             fb->stfb, fbRead->stfb);
536       }
537       else {
538          /* Note: when we call this function we will wind up in the
539           * stw_st_framebuffer_validate_locked() function which will incur
540           * a recursive fb->mutex lock.
541           */
542          ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
543                                             fb->stfb, fb->stfb);
544       }
545 
546       if (old_fb && old_fb != fb) {
547          stw_lock_framebuffers(stw_dev);
548          stw_framebuffer_lock(old_fb);
549          stw_framebuffer_release_locked(old_fb);
550          stw_unlock_framebuffers(stw_dev);
551       }
552 
553 fail:
554       if (fb) {
555          /* fb must be unlocked at this point. */
556          assert(!stw_own_mutex(&fb->mutex));
557       }
558 
559       /* On failure, make the thread's current rendering context not current
560        * before returning.
561        */
562       if (!ret) {
563          stw_make_current(NULL, NULL, 0);
564       }
565    } else {
566       ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
567    }
568 
569    /* Unreference the previous framebuffer if any. It must be done after
570     * make_current, as it can be referenced inside.
571     */
572    if (old_ctx && old_ctx != ctx) {
573       struct stw_framebuffer *old_fb = old_ctx->current_framebuffer;
574       if (old_fb) {
575          old_ctx->current_framebuffer = NULL;
576          stw_lock_framebuffers(stw_dev);
577          stw_framebuffer_lock(old_fb);
578          stw_framebuffer_release_locked(old_fb);
579          stw_unlock_framebuffers(stw_dev);
580       }
581    }
582 
583    return ret;
584 }
585 
586 
587 /**
588  * Notify the current context that the framebuffer has become invalid.
589  */
590 void
stw_notify_current_locked(struct stw_framebuffer * fb)591 stw_notify_current_locked( struct stw_framebuffer *fb )
592 {
593    p_atomic_inc(&fb->stfb->stamp);
594 }
595 
596 
597 /**
598  * Although WGL allows different dispatch entrypoints per context
599  */
600 static const GLCLTPROCTABLE cpt =
601 {
602    OPENGL_VERSION_110_ENTRIES,
603    {
604       &glNewList,
605       &glEndList,
606       &glCallList,
607       &glCallLists,
608       &glDeleteLists,
609       &glGenLists,
610       &glListBase,
611       &glBegin,
612       &glBitmap,
613       &glColor3b,
614       &glColor3bv,
615       &glColor3d,
616       &glColor3dv,
617       &glColor3f,
618       &glColor3fv,
619       &glColor3i,
620       &glColor3iv,
621       &glColor3s,
622       &glColor3sv,
623       &glColor3ub,
624       &glColor3ubv,
625       &glColor3ui,
626       &glColor3uiv,
627       &glColor3us,
628       &glColor3usv,
629       &glColor4b,
630       &glColor4bv,
631       &glColor4d,
632       &glColor4dv,
633       &glColor4f,
634       &glColor4fv,
635       &glColor4i,
636       &glColor4iv,
637       &glColor4s,
638       &glColor4sv,
639       &glColor4ub,
640       &glColor4ubv,
641       &glColor4ui,
642       &glColor4uiv,
643       &glColor4us,
644       &glColor4usv,
645       &glEdgeFlag,
646       &glEdgeFlagv,
647       &glEnd,
648       &glIndexd,
649       &glIndexdv,
650       &glIndexf,
651       &glIndexfv,
652       &glIndexi,
653       &glIndexiv,
654       &glIndexs,
655       &glIndexsv,
656       &glNormal3b,
657       &glNormal3bv,
658       &glNormal3d,
659       &glNormal3dv,
660       &glNormal3f,
661       &glNormal3fv,
662       &glNormal3i,
663       &glNormal3iv,
664       &glNormal3s,
665       &glNormal3sv,
666       &glRasterPos2d,
667       &glRasterPos2dv,
668       &glRasterPos2f,
669       &glRasterPos2fv,
670       &glRasterPos2i,
671       &glRasterPos2iv,
672       &glRasterPos2s,
673       &glRasterPos2sv,
674       &glRasterPos3d,
675       &glRasterPos3dv,
676       &glRasterPos3f,
677       &glRasterPos3fv,
678       &glRasterPos3i,
679       &glRasterPos3iv,
680       &glRasterPos3s,
681       &glRasterPos3sv,
682       &glRasterPos4d,
683       &glRasterPos4dv,
684       &glRasterPos4f,
685       &glRasterPos4fv,
686       &glRasterPos4i,
687       &glRasterPos4iv,
688       &glRasterPos4s,
689       &glRasterPos4sv,
690       &glRectd,
691       &glRectdv,
692       &glRectf,
693       &glRectfv,
694       &glRecti,
695       &glRectiv,
696       &glRects,
697       &glRectsv,
698       &glTexCoord1d,
699       &glTexCoord1dv,
700       &glTexCoord1f,
701       &glTexCoord1fv,
702       &glTexCoord1i,
703       &glTexCoord1iv,
704       &glTexCoord1s,
705       &glTexCoord1sv,
706       &glTexCoord2d,
707       &glTexCoord2dv,
708       &glTexCoord2f,
709       &glTexCoord2fv,
710       &glTexCoord2i,
711       &glTexCoord2iv,
712       &glTexCoord2s,
713       &glTexCoord2sv,
714       &glTexCoord3d,
715       &glTexCoord3dv,
716       &glTexCoord3f,
717       &glTexCoord3fv,
718       &glTexCoord3i,
719       &glTexCoord3iv,
720       &glTexCoord3s,
721       &glTexCoord3sv,
722       &glTexCoord4d,
723       &glTexCoord4dv,
724       &glTexCoord4f,
725       &glTexCoord4fv,
726       &glTexCoord4i,
727       &glTexCoord4iv,
728       &glTexCoord4s,
729       &glTexCoord4sv,
730       &glVertex2d,
731       &glVertex2dv,
732       &glVertex2f,
733       &glVertex2fv,
734       &glVertex2i,
735       &glVertex2iv,
736       &glVertex2s,
737       &glVertex2sv,
738       &glVertex3d,
739       &glVertex3dv,
740       &glVertex3f,
741       &glVertex3fv,
742       &glVertex3i,
743       &glVertex3iv,
744       &glVertex3s,
745       &glVertex3sv,
746       &glVertex4d,
747       &glVertex4dv,
748       &glVertex4f,
749       &glVertex4fv,
750       &glVertex4i,
751       &glVertex4iv,
752       &glVertex4s,
753       &glVertex4sv,
754       &glClipPlane,
755       &glColorMaterial,
756       &glCullFace,
757       &glFogf,
758       &glFogfv,
759       &glFogi,
760       &glFogiv,
761       &glFrontFace,
762       &glHint,
763       &glLightf,
764       &glLightfv,
765       &glLighti,
766       &glLightiv,
767       &glLightModelf,
768       &glLightModelfv,
769       &glLightModeli,
770       &glLightModeliv,
771       &glLineStipple,
772       &glLineWidth,
773       &glMaterialf,
774       &glMaterialfv,
775       &glMateriali,
776       &glMaterialiv,
777       &glPointSize,
778       &glPolygonMode,
779       &glPolygonStipple,
780       &glScissor,
781       &glShadeModel,
782       &glTexParameterf,
783       &glTexParameterfv,
784       &glTexParameteri,
785       &glTexParameteriv,
786       &glTexImage1D,
787       &glTexImage2D,
788       &glTexEnvf,
789       &glTexEnvfv,
790       &glTexEnvi,
791       &glTexEnviv,
792       &glTexGend,
793       &glTexGendv,
794       &glTexGenf,
795       &glTexGenfv,
796       &glTexGeni,
797       &glTexGeniv,
798       &glFeedbackBuffer,
799       &glSelectBuffer,
800       &glRenderMode,
801       &glInitNames,
802       &glLoadName,
803       &glPassThrough,
804       &glPopName,
805       &glPushName,
806       &glDrawBuffer,
807       &glClear,
808       &glClearAccum,
809       &glClearIndex,
810       &glClearColor,
811       &glClearStencil,
812       &glClearDepth,
813       &glStencilMask,
814       &glColorMask,
815       &glDepthMask,
816       &glIndexMask,
817       &glAccum,
818       &glDisable,
819       &glEnable,
820       &glFinish,
821       &glFlush,
822       &glPopAttrib,
823       &glPushAttrib,
824       &glMap1d,
825       &glMap1f,
826       &glMap2d,
827       &glMap2f,
828       &glMapGrid1d,
829       &glMapGrid1f,
830       &glMapGrid2d,
831       &glMapGrid2f,
832       &glEvalCoord1d,
833       &glEvalCoord1dv,
834       &glEvalCoord1f,
835       &glEvalCoord1fv,
836       &glEvalCoord2d,
837       &glEvalCoord2dv,
838       &glEvalCoord2f,
839       &glEvalCoord2fv,
840       &glEvalMesh1,
841       &glEvalPoint1,
842       &glEvalMesh2,
843       &glEvalPoint2,
844       &glAlphaFunc,
845       &glBlendFunc,
846       &glLogicOp,
847       &glStencilFunc,
848       &glStencilOp,
849       &glDepthFunc,
850       &glPixelZoom,
851       &glPixelTransferf,
852       &glPixelTransferi,
853       &glPixelStoref,
854       &glPixelStorei,
855       &glPixelMapfv,
856       &glPixelMapuiv,
857       &glPixelMapusv,
858       &glReadBuffer,
859       &glCopyPixels,
860       &glReadPixels,
861       &glDrawPixels,
862       &glGetBooleanv,
863       &glGetClipPlane,
864       &glGetDoublev,
865       &glGetError,
866       &glGetFloatv,
867       &glGetIntegerv,
868       &glGetLightfv,
869       &glGetLightiv,
870       &glGetMapdv,
871       &glGetMapfv,
872       &glGetMapiv,
873       &glGetMaterialfv,
874       &glGetMaterialiv,
875       &glGetPixelMapfv,
876       &glGetPixelMapuiv,
877       &glGetPixelMapusv,
878       &glGetPolygonStipple,
879       &glGetString,
880       &glGetTexEnvfv,
881       &glGetTexEnviv,
882       &glGetTexGendv,
883       &glGetTexGenfv,
884       &glGetTexGeniv,
885       &glGetTexImage,
886       &glGetTexParameterfv,
887       &glGetTexParameteriv,
888       &glGetTexLevelParameterfv,
889       &glGetTexLevelParameteriv,
890       &glIsEnabled,
891       &glIsList,
892       &glDepthRange,
893       &glFrustum,
894       &glLoadIdentity,
895       &glLoadMatrixf,
896       &glLoadMatrixd,
897       &glMatrixMode,
898       &glMultMatrixf,
899       &glMultMatrixd,
900       &glOrtho,
901       &glPopMatrix,
902       &glPushMatrix,
903       &glRotated,
904       &glRotatef,
905       &glScaled,
906       &glScalef,
907       &glTranslated,
908       &glTranslatef,
909       &glViewport,
910       &glArrayElement,
911       &glBindTexture,
912       &glColorPointer,
913       &glDisableClientState,
914       &glDrawArrays,
915       &glDrawElements,
916       &glEdgeFlagPointer,
917       &glEnableClientState,
918       &glIndexPointer,
919       &glIndexub,
920       &glIndexubv,
921       &glInterleavedArrays,
922       &glNormalPointer,
923       &glPolygonOffset,
924       &glTexCoordPointer,
925       &glVertexPointer,
926       &glAreTexturesResident,
927       &glCopyTexImage1D,
928       &glCopyTexImage2D,
929       &glCopyTexSubImage1D,
930       &glCopyTexSubImage2D,
931       &glDeleteTextures,
932       &glGenTextures,
933       &glGetPointerv,
934       &glIsTexture,
935       &glPrioritizeTextures,
936       &glTexSubImage1D,
937       &glTexSubImage2D,
938       &glPopClientAttrib,
939       &glPushClientAttrib
940    }
941 };
942 
943 
944 PGLCLTPROCTABLE APIENTRY
DrvSetContext(HDC hdc,DHGLRC dhglrc,PFN_SETPROCTABLE pfnSetProcTable)945 DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
946 {
947    PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
948 
949    if (!stw_make_current(hdc, hdc, dhglrc))
950       r = NULL;
951 
952    return r;
953 }
954