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