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