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