st/wgl: Implement WGL_EXT_create_context_es/es2_profile.
[mesa.git] / src / gallium / state_trackers / wgl / stw_context.c
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 *
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 BOOL APIENTRY
63 DrvCopyContext(
64 DHGLRC dhrcSource,
65 DHGLRC dhrcDest,
66 UINT fuMask )
67 {
68 struct stw_context *src;
69 struct stw_context *dst;
70 BOOL ret = FALSE;
71
72 if (!stw_dev)
73 return FALSE;
74
75 pipe_mutex_lock( stw_dev->ctx_mutex );
76
77 src = stw_lookup_context_locked( dhrcSource );
78 dst = stw_lookup_context_locked( dhrcDest );
79
80 if (src && dst) {
81 /* FIXME */
82 assert(0);
83 (void) src;
84 (void) dst;
85 (void) fuMask;
86 }
87
88 pipe_mutex_unlock( stw_dev->ctx_mutex );
89
90 return ret;
91 }
92
93 BOOL APIENTRY
94 DrvShareLists(
95 DHGLRC dhglrc1,
96 DHGLRC dhglrc2 )
97 {
98 struct stw_context *ctx1;
99 struct stw_context *ctx2;
100 BOOL ret = FALSE;
101
102 if (!stw_dev)
103 return FALSE;
104
105 pipe_mutex_lock( stw_dev->ctx_mutex );
106
107 ctx1 = stw_lookup_context_locked( dhglrc1 );
108 ctx2 = stw_lookup_context_locked( dhglrc2 );
109
110 if (ctx1 && ctx2 && ctx2->st->share)
111 ret = ctx2->st->share(ctx2->st, ctx1->st);
112
113 pipe_mutex_unlock( stw_dev->ctx_mutex );
114
115 return ret;
116 }
117
118 DHGLRC APIENTRY
119 DrvCreateContext(
120 HDC hdc )
121 {
122 return DrvCreateLayerContext( hdc, 0 );
123 }
124
125 DHGLRC APIENTRY
126 DrvCreateLayerContext(
127 HDC hdc,
128 INT iLayerPlane )
129 {
130 return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
131 WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
132 0);
133 }
134
135
136 /**
137 * Called via DrvCreateContext(), DrvCreateLayerContext() and
138 * wglCreateContextAttribsARB() to actually create a rendering context.
139 * \param handle the desired DHGLRC handle to use for the context, or zero
140 * if a new handle should be allocated.
141 * \return the handle for the new context or zero if there was a problem.
142 */
143 DHGLRC
144 stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
145 int majorVersion, int minorVersion,
146 int contextFlags, int profileMask,
147 DHGLRC handle)
148 {
149 int iPixelFormat;
150 struct stw_framebuffer *fb;
151 const struct stw_pixelformat_info *pfi;
152 struct st_context_attribs attribs;
153 struct stw_context *ctx = NULL;
154 struct stw_context *shareCtx = NULL;
155 enum st_context_error ctx_err = 0;
156
157 if (!stw_dev)
158 return 0;
159
160 if (iLayerPlane != 0)
161 return 0;
162
163 iPixelFormat = GetPixelFormat(hdc);
164 if(!iPixelFormat)
165 return 0;
166
167 /*
168 * GDI only knows about displayable pixel formats, so determine the pixel
169 * format from the framebuffer.
170 *
171 * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
172 */
173 fb = stw_framebuffer_from_hdc( hdc );
174 if (fb) {
175 assert(iPixelFormat == fb->iDisplayablePixelFormat);
176 iPixelFormat = fb->iPixelFormat;
177 stw_framebuffer_release(fb);
178 }
179
180 pfi = stw_pixelformat_get_info( iPixelFormat );
181
182 if (hShareContext != 0) {
183 pipe_mutex_lock( stw_dev->ctx_mutex );
184 shareCtx = stw_lookup_context_locked( hShareContext );
185 pipe_mutex_unlock( stw_dev->ctx_mutex );
186 }
187
188 ctx = CALLOC_STRUCT( stw_context );
189 if (ctx == NULL)
190 goto no_ctx;
191
192 ctx->hdc = hdc;
193 ctx->iPixelFormat = iPixelFormat;
194
195 memset(&attribs, 0, sizeof(attribs));
196 attribs.visual = pfi->stvis;
197 attribs.major = majorVersion;
198 attribs.minor = minorVersion;
199 if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
200 attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
201 if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
202 attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
203
204 switch (profileMask) {
205 case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
206 /* There are no profiles before OpenGL 3.2. The
207 * WGL_ARB_create_context_profile spec says:
208 *
209 * "If the requested OpenGL version is less than 3.2,
210 * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
211 * of the context is determined solely by the requested version."
212 */
213 if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
214 attribs.profile = ST_PROFILE_OPENGL_CORE;
215 break;
216 }
217 /* fall-through */
218 case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
219 /*
220 * The spec also says:
221 *
222 * "If version 3.1 is requested, the context returned may implement
223 * any of the following versions:
224 *
225 * * Version 3.1. The GL_ARB_compatibility extension may or may not
226 * be implemented, as determined by the implementation.
227 * * The core profile of version 3.2 or greater."
228 *
229 * and because Mesa doesn't support GL_ARB_compatibility, the only chance to
230 * honour a 3.1 context is through core profile.
231 */
232 if (majorVersion == 3 && minorVersion == 1) {
233 attribs.profile = ST_PROFILE_OPENGL_CORE;
234 } else {
235 attribs.profile = ST_PROFILE_DEFAULT;
236 }
237 break;
238 case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
239 if (majorVersion >= 2) {
240 attribs.profile = ST_PROFILE_OPENGL_ES2;
241 } else {
242 attribs.profile = ST_PROFILE_OPENGL_ES1;
243 }
244 break;
245 default:
246 assert(0);
247 goto no_st_ctx;
248 }
249
250 ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
251 stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
252 if (ctx->st == NULL)
253 goto no_st_ctx;
254
255 ctx->st->st_manager_private = (void *) ctx;
256
257 if (ctx->st->cso_context) {
258 ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
259 }
260
261 pipe_mutex_lock( stw_dev->ctx_mutex );
262 if (handle) {
263 /* We're replacing the context data for this handle. See the
264 * wglCreateContextAttribsARB() function.
265 */
266 struct stw_context *old_ctx =
267 stw_lookup_context_locked((unsigned) handle);
268 if (old_ctx) {
269 /* free the old context data associated with this handle */
270 if (old_ctx->hud) {
271 hud_destroy(old_ctx->hud);
272 }
273 ctx->st->destroy(old_ctx->st);
274 FREE(old_ctx);
275 }
276
277 /* replace table entry */
278 handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
279 }
280 else {
281 /* create new table entry */
282 handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
283 }
284
285 ctx->dhglrc = handle;
286
287 pipe_mutex_unlock( stw_dev->ctx_mutex );
288 if (!ctx->dhglrc)
289 goto no_hglrc;
290
291 return ctx->dhglrc;
292
293 no_hglrc:
294 if (ctx->hud) {
295 hud_destroy(ctx->hud);
296 }
297 ctx->st->destroy(ctx->st);
298 no_st_ctx:
299 FREE(ctx);
300 no_ctx:
301 return 0;
302 }
303
304 BOOL APIENTRY
305 DrvDeleteContext(
306 DHGLRC dhglrc )
307 {
308 struct stw_context *ctx ;
309 BOOL ret = FALSE;
310
311 if (!stw_dev)
312 return FALSE;
313
314 pipe_mutex_lock( stw_dev->ctx_mutex );
315 ctx = stw_lookup_context_locked(dhglrc);
316 handle_table_remove(stw_dev->ctx_table, dhglrc);
317 pipe_mutex_unlock( stw_dev->ctx_mutex );
318
319 if (ctx) {
320 struct stw_context *curctx = stw_current_context();
321
322 /* Unbind current if deleting current context. */
323 if (curctx == ctx)
324 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
325
326 if (ctx->hud) {
327 hud_destroy(ctx->hud);
328 }
329
330 ctx->st->destroy(ctx->st);
331 FREE(ctx);
332
333 ret = TRUE;
334 }
335
336 return ret;
337 }
338
339 BOOL APIENTRY
340 DrvReleaseContext(
341 DHGLRC dhglrc )
342 {
343 struct stw_context *ctx;
344
345 if (!stw_dev)
346 return FALSE;
347
348 pipe_mutex_lock( stw_dev->ctx_mutex );
349 ctx = stw_lookup_context_locked( dhglrc );
350 pipe_mutex_unlock( stw_dev->ctx_mutex );
351
352 if (!ctx)
353 return FALSE;
354
355 /* The expectation is that ctx is the same context which is
356 * current for this thread. We should check that and return False
357 * if not the case.
358 */
359 if (ctx != stw_current_context())
360 return FALSE;
361
362 if (stw_make_current( NULL, 0 ) == FALSE)
363 return FALSE;
364
365 return TRUE;
366 }
367
368
369 DHGLRC
370 stw_get_current_context( void )
371 {
372 struct stw_context *ctx;
373
374 ctx = stw_current_context();
375 if(!ctx)
376 return 0;
377
378 return ctx->dhglrc;
379 }
380
381 HDC
382 stw_get_current_dc( void )
383 {
384 struct stw_context *ctx;
385
386 ctx = stw_current_context();
387 if(!ctx)
388 return NULL;
389
390 return ctx->hdc;
391 }
392
393 BOOL
394 stw_make_current(
395 HDC hdc,
396 DHGLRC dhglrc )
397 {
398 struct stw_context *curctx = NULL;
399 struct stw_context *ctx = NULL;
400 struct stw_framebuffer *fb = NULL;
401 BOOL ret = FALSE;
402
403 if (!stw_dev)
404 return FALSE;
405
406 curctx = stw_current_context();
407 if (curctx != NULL) {
408 if (curctx->dhglrc == dhglrc) {
409 if (curctx->hdc == hdc) {
410 /* Return if already current. */
411 return TRUE;
412 }
413 } else {
414 curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
415 }
416 }
417
418 if (dhglrc) {
419 pipe_mutex_lock( stw_dev->ctx_mutex );
420 ctx = stw_lookup_context_locked( dhglrc );
421 pipe_mutex_unlock( stw_dev->ctx_mutex );
422 if (!ctx) {
423 goto fail;
424 }
425
426 fb = stw_framebuffer_from_hdc( hdc );
427 if (fb) {
428 stw_framebuffer_update(fb);
429 }
430 else {
431 /* Applications should call SetPixelFormat before creating a context,
432 * but not all do, and the opengl32 runtime seems to use a default pixel
433 * format in some cases, so we must create a framebuffer for those here
434 */
435 int iPixelFormat = GetPixelFormat(hdc);
436 if (iPixelFormat)
437 fb = stw_framebuffer_create( hdc, iPixelFormat );
438 if (!fb)
439 goto fail;
440 }
441
442 if (fb->iPixelFormat != ctx->iPixelFormat) {
443 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
444 goto fail;
445 }
446
447 /* Bind the new framebuffer */
448 ctx->hdc = hdc;
449
450 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
451 fb->stfb, fb->stfb);
452 stw_framebuffer_reference(&ctx->current_framebuffer, fb);
453 } else {
454 ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
455 }
456
457 fail:
458
459 if (fb) {
460 stw_framebuffer_release(fb);
461 }
462
463 /* On failure, make the thread's current rendering context not current
464 * before returning */
465 if (!ret) {
466 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
467 ctx = NULL;
468 }
469
470 /* Unreference the previous framebuffer if any. It must be done after
471 * make_current, as it can be referenced inside.
472 */
473 if (curctx && curctx != ctx) {
474 stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
475 }
476
477 return ret;
478 }
479
480 /**
481 * Flush the current context if it is bound to the framebuffer.
482 */
483 void
484 stw_flush_current_locked( struct stw_framebuffer *fb )
485 {
486 struct stw_context *ctx = stw_current_context();
487
488 if (ctx && ctx->current_framebuffer == fb) {
489 ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
490 }
491 }
492
493 /**
494 * Notify the current context that the framebuffer has become invalid.
495 */
496 void
497 stw_notify_current_locked( struct stw_framebuffer *fb )
498 {
499 p_atomic_inc(&fb->stfb->stamp);
500 }
501
502 /**
503 * Although WGL allows different dispatch entrypoints per context
504 */
505 static const GLCLTPROCTABLE cpt =
506 {
507 OPENGL_VERSION_110_ENTRIES,
508 {
509 &glNewList,
510 &glEndList,
511 &glCallList,
512 &glCallLists,
513 &glDeleteLists,
514 &glGenLists,
515 &glListBase,
516 &glBegin,
517 &glBitmap,
518 &glColor3b,
519 &glColor3bv,
520 &glColor3d,
521 &glColor3dv,
522 &glColor3f,
523 &glColor3fv,
524 &glColor3i,
525 &glColor3iv,
526 &glColor3s,
527 &glColor3sv,
528 &glColor3ub,
529 &glColor3ubv,
530 &glColor3ui,
531 &glColor3uiv,
532 &glColor3us,
533 &glColor3usv,
534 &glColor4b,
535 &glColor4bv,
536 &glColor4d,
537 &glColor4dv,
538 &glColor4f,
539 &glColor4fv,
540 &glColor4i,
541 &glColor4iv,
542 &glColor4s,
543 &glColor4sv,
544 &glColor4ub,
545 &glColor4ubv,
546 &glColor4ui,
547 &glColor4uiv,
548 &glColor4us,
549 &glColor4usv,
550 &glEdgeFlag,
551 &glEdgeFlagv,
552 &glEnd,
553 &glIndexd,
554 &glIndexdv,
555 &glIndexf,
556 &glIndexfv,
557 &glIndexi,
558 &glIndexiv,
559 &glIndexs,
560 &glIndexsv,
561 &glNormal3b,
562 &glNormal3bv,
563 &glNormal3d,
564 &glNormal3dv,
565 &glNormal3f,
566 &glNormal3fv,
567 &glNormal3i,
568 &glNormal3iv,
569 &glNormal3s,
570 &glNormal3sv,
571 &glRasterPos2d,
572 &glRasterPos2dv,
573 &glRasterPos2f,
574 &glRasterPos2fv,
575 &glRasterPos2i,
576 &glRasterPos2iv,
577 &glRasterPos2s,
578 &glRasterPos2sv,
579 &glRasterPos3d,
580 &glRasterPos3dv,
581 &glRasterPos3f,
582 &glRasterPos3fv,
583 &glRasterPos3i,
584 &glRasterPos3iv,
585 &glRasterPos3s,
586 &glRasterPos3sv,
587 &glRasterPos4d,
588 &glRasterPos4dv,
589 &glRasterPos4f,
590 &glRasterPos4fv,
591 &glRasterPos4i,
592 &glRasterPos4iv,
593 &glRasterPos4s,
594 &glRasterPos4sv,
595 &glRectd,
596 &glRectdv,
597 &glRectf,
598 &glRectfv,
599 &glRecti,
600 &glRectiv,
601 &glRects,
602 &glRectsv,
603 &glTexCoord1d,
604 &glTexCoord1dv,
605 &glTexCoord1f,
606 &glTexCoord1fv,
607 &glTexCoord1i,
608 &glTexCoord1iv,
609 &glTexCoord1s,
610 &glTexCoord1sv,
611 &glTexCoord2d,
612 &glTexCoord2dv,
613 &glTexCoord2f,
614 &glTexCoord2fv,
615 &glTexCoord2i,
616 &glTexCoord2iv,
617 &glTexCoord2s,
618 &glTexCoord2sv,
619 &glTexCoord3d,
620 &glTexCoord3dv,
621 &glTexCoord3f,
622 &glTexCoord3fv,
623 &glTexCoord3i,
624 &glTexCoord3iv,
625 &glTexCoord3s,
626 &glTexCoord3sv,
627 &glTexCoord4d,
628 &glTexCoord4dv,
629 &glTexCoord4f,
630 &glTexCoord4fv,
631 &glTexCoord4i,
632 &glTexCoord4iv,
633 &glTexCoord4s,
634 &glTexCoord4sv,
635 &glVertex2d,
636 &glVertex2dv,
637 &glVertex2f,
638 &glVertex2fv,
639 &glVertex2i,
640 &glVertex2iv,
641 &glVertex2s,
642 &glVertex2sv,
643 &glVertex3d,
644 &glVertex3dv,
645 &glVertex3f,
646 &glVertex3fv,
647 &glVertex3i,
648 &glVertex3iv,
649 &glVertex3s,
650 &glVertex3sv,
651 &glVertex4d,
652 &glVertex4dv,
653 &glVertex4f,
654 &glVertex4fv,
655 &glVertex4i,
656 &glVertex4iv,
657 &glVertex4s,
658 &glVertex4sv,
659 &glClipPlane,
660 &glColorMaterial,
661 &glCullFace,
662 &glFogf,
663 &glFogfv,
664 &glFogi,
665 &glFogiv,
666 &glFrontFace,
667 &glHint,
668 &glLightf,
669 &glLightfv,
670 &glLighti,
671 &glLightiv,
672 &glLightModelf,
673 &glLightModelfv,
674 &glLightModeli,
675 &glLightModeliv,
676 &glLineStipple,
677 &glLineWidth,
678 &glMaterialf,
679 &glMaterialfv,
680 &glMateriali,
681 &glMaterialiv,
682 &glPointSize,
683 &glPolygonMode,
684 &glPolygonStipple,
685 &glScissor,
686 &glShadeModel,
687 &glTexParameterf,
688 &glTexParameterfv,
689 &glTexParameteri,
690 &glTexParameteriv,
691 &glTexImage1D,
692 &glTexImage2D,
693 &glTexEnvf,
694 &glTexEnvfv,
695 &glTexEnvi,
696 &glTexEnviv,
697 &glTexGend,
698 &glTexGendv,
699 &glTexGenf,
700 &glTexGenfv,
701 &glTexGeni,
702 &glTexGeniv,
703 &glFeedbackBuffer,
704 &glSelectBuffer,
705 &glRenderMode,
706 &glInitNames,
707 &glLoadName,
708 &glPassThrough,
709 &glPopName,
710 &glPushName,
711 &glDrawBuffer,
712 &glClear,
713 &glClearAccum,
714 &glClearIndex,
715 &glClearColor,
716 &glClearStencil,
717 &glClearDepth,
718 &glStencilMask,
719 &glColorMask,
720 &glDepthMask,
721 &glIndexMask,
722 &glAccum,
723 &glDisable,
724 &glEnable,
725 &glFinish,
726 &glFlush,
727 &glPopAttrib,
728 &glPushAttrib,
729 &glMap1d,
730 &glMap1f,
731 &glMap2d,
732 &glMap2f,
733 &glMapGrid1d,
734 &glMapGrid1f,
735 &glMapGrid2d,
736 &glMapGrid2f,
737 &glEvalCoord1d,
738 &glEvalCoord1dv,
739 &glEvalCoord1f,
740 &glEvalCoord1fv,
741 &glEvalCoord2d,
742 &glEvalCoord2dv,
743 &glEvalCoord2f,
744 &glEvalCoord2fv,
745 &glEvalMesh1,
746 &glEvalPoint1,
747 &glEvalMesh2,
748 &glEvalPoint2,
749 &glAlphaFunc,
750 &glBlendFunc,
751 &glLogicOp,
752 &glStencilFunc,
753 &glStencilOp,
754 &glDepthFunc,
755 &glPixelZoom,
756 &glPixelTransferf,
757 &glPixelTransferi,
758 &glPixelStoref,
759 &glPixelStorei,
760 &glPixelMapfv,
761 &glPixelMapuiv,
762 &glPixelMapusv,
763 &glReadBuffer,
764 &glCopyPixels,
765 &glReadPixels,
766 &glDrawPixels,
767 &glGetBooleanv,
768 &glGetClipPlane,
769 &glGetDoublev,
770 &glGetError,
771 &glGetFloatv,
772 &glGetIntegerv,
773 &glGetLightfv,
774 &glGetLightiv,
775 &glGetMapdv,
776 &glGetMapfv,
777 &glGetMapiv,
778 &glGetMaterialfv,
779 &glGetMaterialiv,
780 &glGetPixelMapfv,
781 &glGetPixelMapuiv,
782 &glGetPixelMapusv,
783 &glGetPolygonStipple,
784 &glGetString,
785 &glGetTexEnvfv,
786 &glGetTexEnviv,
787 &glGetTexGendv,
788 &glGetTexGenfv,
789 &glGetTexGeniv,
790 &glGetTexImage,
791 &glGetTexParameterfv,
792 &glGetTexParameteriv,
793 &glGetTexLevelParameterfv,
794 &glGetTexLevelParameteriv,
795 &glIsEnabled,
796 &glIsList,
797 &glDepthRange,
798 &glFrustum,
799 &glLoadIdentity,
800 &glLoadMatrixf,
801 &glLoadMatrixd,
802 &glMatrixMode,
803 &glMultMatrixf,
804 &glMultMatrixd,
805 &glOrtho,
806 &glPopMatrix,
807 &glPushMatrix,
808 &glRotated,
809 &glRotatef,
810 &glScaled,
811 &glScalef,
812 &glTranslated,
813 &glTranslatef,
814 &glViewport,
815 &glArrayElement,
816 &glBindTexture,
817 &glColorPointer,
818 &glDisableClientState,
819 &glDrawArrays,
820 &glDrawElements,
821 &glEdgeFlagPointer,
822 &glEnableClientState,
823 &glIndexPointer,
824 &glIndexub,
825 &glIndexubv,
826 &glInterleavedArrays,
827 &glNormalPointer,
828 &glPolygonOffset,
829 &glTexCoordPointer,
830 &glVertexPointer,
831 &glAreTexturesResident,
832 &glCopyTexImage1D,
833 &glCopyTexImage2D,
834 &glCopyTexSubImage1D,
835 &glCopyTexSubImage2D,
836 &glDeleteTextures,
837 &glGenTextures,
838 &glGetPointerv,
839 &glIsTexture,
840 &glPrioritizeTextures,
841 &glTexSubImage1D,
842 &glTexSubImage2D,
843 &glPopClientAttrib,
844 &glPushClientAttrib
845 }
846 };
847
848 PGLCLTPROCTABLE APIENTRY
849 DrvSetContext(
850 HDC hdc,
851 DHGLRC dhglrc,
852 PFN_SETPROCTABLE pfnSetProcTable )
853 {
854 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
855
856 if (!stw_make_current( hdc, dhglrc ))
857 r = NULL;
858
859 return r;
860 }