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