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