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