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