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