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