1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27 /* 28 * This is an emulation of the GLX API which allows Mesa/GLX-based programs 29 * to run on X servers which do not have the real GLX extension. 30 * 31 * Thanks to the contributors: 32 * 33 * Initial version: Philip Brown (phil (at) bolthole.com) 34 * Better glXGetConfig() support: Armin Liebchen (liebchen (at) asylum.cs.utah.edu) 35 * Further visual-handling refinements: Wolfram Gloger 36 * (wmglo (at) Dent.MED.Uni-Muenchen.DE). 37 * 38 * Notes: 39 * Don't be fooled, stereo isn't supported yet. 40 */ 41 42 43 #include <string.h> 44 #include <stdio.h> 45 #include "glxheader.h" 46 #include "glxapi.h" 47 #include "main/context.h" 48 #include "main/config.h" 49 #include "main/macros.h" 50 #include "main/imports.h" 51 #include "main/mtypes.h" 52 #include "main/version.h" 53 #include "xfonts.h" 54 #include "xmesaP.h" 55 56 /* This indicates the client-side GLX API and GLX encoder version. */ 57 #define CLIENT_MAJOR_VERSION 1 58 #define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ 59 60 /* This indicates the server-side GLX decoder version. 61 * GLX 1.4 indicates OpenGL 1.3 support 62 */ 63 #define SERVER_MAJOR_VERSION 1 64 #define SERVER_MINOR_VERSION 4 65 66 /* This is appended onto the glXGetClient/ServerString version strings. */ 67 #define MESA_GLX_VERSION "Mesa " PACKAGE_VERSION 68 69 /* Who implemented this GLX? */ 70 #define VENDOR "Brian Paul" 71 72 #define EXTENSIONS \ 73 "GLX_MESA_set_3dfx_mode " \ 74 "GLX_MESA_copy_sub_buffer " \ 75 "GLX_MESA_pixmap_colormap " \ 76 "GLX_MESA_release_buffers " \ 77 "GLX_ARB_create_context " \ 78 "GLX_ARB_get_proc_address " \ 79 "GLX_EXT_texture_from_pixmap " \ 80 "GLX_EXT_visual_info " \ 81 "GLX_EXT_visual_rating " \ 82 /*"GLX_SGI_video_sync "*/ \ 83 "GLX_SGIX_fbconfig " \ 84 "GLX_SGIX_pbuffer " 85 86 87 88 /**********************************************************************/ 89 /*** GLX Visual Code ***/ 90 /**********************************************************************/ 91 92 #define DONT_CARE -1 93 94 95 static XMesaVisual *VisualTable = NULL; 96 static int NumVisuals = 0; 97 98 99 /* 100 * This struct and some code fragments borrowed 101 * from Mark Kilgard's GLUT library. 102 */ 103 typedef struct _OverlayInfo { 104 /* Avoid 64-bit portability problems by being careful to use 105 longs due to the way XGetWindowProperty is specified. Note 106 that these parameters are passed as CARD32s over X 107 protocol. */ 108 unsigned long overlay_visual; 109 long transparent_type; 110 long value; 111 long layer; 112 } OverlayInfo; 113 114 115 116 /* Macro to handle c_class vs class field name in XVisualInfo struct */ 117 #if defined(__cplusplus) || defined(c_plusplus) 118 #define CLASS c_class 119 #else 120 #define CLASS class 121 #endif 122 123 124 125 /* 126 * Test if the given XVisualInfo is usable for Mesa rendering. 127 */ 128 static GLboolean 129 is_usable_visual( XVisualInfo *vinfo ) 130 { 131 switch (vinfo->CLASS) { 132 case StaticGray: 133 case GrayScale: 134 /* Any StaticGray/GrayScale visual works in RGB or CI mode */ 135 return GL_TRUE; 136 case StaticColor: 137 case PseudoColor: 138 /* Color-index rendering is not supported. */ 139 return GL_FALSE; 140 case TrueColor: 141 case DirectColor: 142 /* Any depth of TrueColor or DirectColor works in RGB mode */ 143 return GL_TRUE; 144 default: 145 /* This should never happen */ 146 return GL_FALSE; 147 } 148 } 149 150 151 152 /** 153 * Get an array OverlayInfo records for specified screen. 154 * \param dpy the display 155 * \param screen screen number 156 * \param numOverlays returns numver of OverlayInfo records 157 * \return pointer to OverlayInfo array, free with XFree() 158 */ 159 static OverlayInfo * 160 GetOverlayInfo(Display *dpy, int screen, int *numOverlays) 161 { 162 Atom overlayVisualsAtom; 163 Atom actualType; 164 Status status; 165 unsigned char *ovInfo; 166 unsigned long sizeData, bytesLeft; 167 int actualFormat; 168 169 /* 170 * The SERVER_OVERLAY_VISUALS property on the root window contains 171 * a list of overlay visuals. Get that list now. 172 */ 173 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); 174 if (overlayVisualsAtom == None) { 175 return 0; 176 } 177 178 status = XGetWindowProperty(dpy, RootWindow(dpy, screen), 179 overlayVisualsAtom, 0L, (long) 10000, False, 180 overlayVisualsAtom, &actualType, &actualFormat, 181 &sizeData, &bytesLeft, 182 &ovInfo); 183 184 if (status != Success || actualType != overlayVisualsAtom || 185 actualFormat != 32 || sizeData < 4) { 186 /* something went wrong */ 187 free((void *) ovInfo); 188 *numOverlays = 0; 189 return NULL; 190 } 191 192 *numOverlays = sizeData / 4; 193 return (OverlayInfo *) ovInfo; 194 } 195 196 197 198 /** 199 * Return the level (overlay, normal, underlay) of a given XVisualInfo. 200 * Input: dpy - the X display 201 * vinfo - the XVisualInfo to test 202 * Return: level of the visual: 203 * 0 = normal planes 204 * >0 = overlay planes 205 * <0 = underlay planes 206 */ 207 static int 208 level_of_visual( Display *dpy, XVisualInfo *vinfo ) 209 { 210 OverlayInfo *overlay_info; 211 int numOverlaysPerScreen, i; 212 213 overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); 214 if (!overlay_info) { 215 return 0; 216 } 217 218 /* search the overlay visual list for the visual ID of interest */ 219 for (i = 0; i < numOverlaysPerScreen; i++) { 220 const OverlayInfo *ov = overlay_info + i; 221 if (ov->overlay_visual == vinfo->visualid) { 222 /* found the visual */ 223 if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { 224 int level = ov->layer; 225 free((void *) overlay_info); 226 return level; 227 } 228 else { 229 free((void *) overlay_info); 230 return 0; 231 } 232 } 233 } 234 235 /* The visual ID was not found in the overlay list. */ 236 free((void *) overlay_info); 237 return 0; 238 } 239 240 241 242 243 /* 244 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the 245 * configuration in our list of GLX visuals. 246 */ 247 static XMesaVisual 248 save_glx_visual( Display *dpy, XVisualInfo *vinfo, 249 GLboolean alphaFlag, GLboolean dbFlag, 250 GLboolean stereoFlag, 251 GLint depth_size, GLint stencil_size, 252 GLint accumRedSize, GLint accumGreenSize, 253 GLint accumBlueSize, GLint accumAlphaSize, 254 GLint level, GLint numAuxBuffers ) 255 { 256 GLboolean ximageFlag = GL_TRUE; 257 XMesaVisual xmvis; 258 GLint i; 259 260 if (dbFlag) { 261 /* Check if the MESA_BACK_BUFFER env var is set */ 262 char *backbuffer = getenv("MESA_BACK_BUFFER"); 263 if (backbuffer) { 264 if (backbuffer[0]=='p' || backbuffer[0]=='P') { 265 ximageFlag = GL_FALSE; 266 } 267 else if (backbuffer[0]=='x' || backbuffer[0]=='X') { 268 ximageFlag = GL_TRUE; 269 } 270 else { 271 _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); 272 } 273 } 274 } 275 276 if (stereoFlag) { 277 /* stereo not supported */ 278 return NULL; 279 } 280 281 282 /* Force the visual to have an alpha channel */ 283 if (getenv("MESA_GLX_FORCE_ALPHA")) 284 alphaFlag = GL_TRUE; 285 286 /* First check if a matching visual is already in the list */ 287 for (i=0; i<NumVisuals; i++) { 288 XMesaVisual v = VisualTable[i]; 289 if (v->display == dpy 290 && v->mesa_visual.level == level 291 && v->mesa_visual.numAuxBuffers == numAuxBuffers 292 && v->ximage_flag == ximageFlag 293 && v->mesa_visual.doubleBufferMode == dbFlag 294 && v->mesa_visual.stereoMode == stereoFlag 295 && (v->mesa_visual.alphaBits > 0) == alphaFlag 296 && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) 297 && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) 298 && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) 299 && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) 300 && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) 301 && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { 302 /* now compare visual IDs */ 303 if (v->visinfo->visualid == vinfo->visualid) { 304 return v; 305 } 306 } 307 } 308 309 /* Create a new visual and add it to the list. */ 310 311 xmvis = XMesaCreateVisual( dpy, vinfo, GL_TRUE, alphaFlag, dbFlag, 312 stereoFlag, ximageFlag, 313 depth_size, stencil_size, 314 accumRedSize, accumBlueSize, 315 accumBlueSize, accumAlphaSize, 0, level, 316 GLX_NONE_EXT ); 317 if (xmvis) { 318 /* Allocate more space for additional visual */ 319 VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1)); 320 /* add xmvis to the list */ 321 VisualTable[NumVisuals] = xmvis; 322 NumVisuals++; 323 /* XXX minor hack, because XMesaCreateVisual doesn't support an 324 * aux buffers parameter. 325 */ 326 xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; 327 } 328 return xmvis; 329 } 330 331 332 /** 333 * Return the default number of bits for the Z buffer. 334 * If defined, use the MESA_GLX_DEPTH_BITS env var value. 335 * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. 336 * XXX probably do the same thing for stencil, accum, etc. 337 */ 338 static GLint 339 default_depth_bits(void) 340 { 341 int zBits; 342 const char *zEnv = getenv("MESA_GLX_DEPTH_BITS"); 343 if (zEnv) 344 zBits = atoi(zEnv); 345 else 346 zBits = DEFAULT_SOFTWARE_DEPTH_BITS; 347 return zBits; 348 } 349 350 static GLint 351 default_alpha_bits(void) 352 { 353 int aBits; 354 const char *aEnv = getenv("MESA_GLX_ALPHA_BITS"); 355 if (aEnv) 356 aBits = atoi(aEnv); 357 else 358 aBits = 0; 359 return aBits; 360 } 361 362 static GLint 363 default_accum_bits(void) 364 { 365 return 16; 366 } 367 368 369 370 /* 371 * Create a GLX visual from a regular XVisualInfo. 372 * This is called when Fake GLX is given an XVisualInfo which wasn't 373 * returned by glXChooseVisual. Since this is the first time we're 374 * considering this visual we'll take a guess at reasonable values 375 * for depth buffer size, stencil size, accum size, etc. 376 * This is the best we can do with a client-side emulation of GLX. 377 */ 378 static XMesaVisual 379 create_glx_visual( Display *dpy, XVisualInfo *visinfo ) 380 { 381 int vislevel; 382 GLint zBits = default_depth_bits(); 383 GLint accBits = default_accum_bits(); 384 GLboolean alphaFlag = default_alpha_bits() > 0; 385 386 vislevel = level_of_visual( dpy, visinfo ); 387 if (vislevel) { 388 /* Color-index rendering to overlays is not supported. */ 389 return NULL; 390 } 391 else if (is_usable_visual( visinfo )) { 392 /* Configure this visual as RGB, double-buffered, depth-buffered. */ 393 /* This is surely wrong for some people's needs but what else */ 394 /* can be done? They should use glXChooseVisual(). */ 395 return save_glx_visual( dpy, visinfo, 396 alphaFlag, /* alpha */ 397 GL_TRUE, /* double */ 398 GL_FALSE, /* stereo */ 399 zBits, 400 8, /* stencil bits */ 401 accBits, /* r */ 402 accBits, /* g */ 403 accBits, /* b */ 404 accBits, /* a */ 405 0, /* level */ 406 0 /* numAux */ 407 ); 408 } 409 else { 410 _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); 411 return NULL; 412 } 413 } 414 415 416 417 /* 418 * Find the GLX visual associated with an XVisualInfo. 419 */ 420 static XMesaVisual 421 find_glx_visual( Display *dpy, XVisualInfo *vinfo ) 422 { 423 int i; 424 425 /* try to match visual id */ 426 for (i=0;i<NumVisuals;i++) { 427 if (VisualTable[i]->display==dpy 428 && VisualTable[i]->visinfo->visualid == vinfo->visualid) { 429 return VisualTable[i]; 430 } 431 } 432 433 return NULL; 434 } 435 436 437 438 /** 439 * Return the transparent pixel value for a GLX visual. 440 * Input: glxvis - the glx_visual 441 * Return: a pixel value or -1 if no transparent pixel 442 */ 443 static int 444 transparent_pixel( XMesaVisual glxvis ) 445 { 446 Display *dpy = glxvis->display; 447 XVisualInfo *vinfo = glxvis->visinfo; 448 OverlayInfo *overlay_info; 449 int numOverlaysPerScreen, i; 450 451 overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); 452 if (!overlay_info) { 453 return -1; 454 } 455 456 for (i = 0; i < numOverlaysPerScreen; i++) { 457 const OverlayInfo *ov = overlay_info + i; 458 if (ov->overlay_visual == vinfo->visualid) { 459 /* found it! */ 460 if (ov->transparent_type == 0) { 461 /* type 0 indicates no transparency */ 462 free((void *) overlay_info); 463 return -1; 464 } 465 else { 466 /* ov->value is the transparent pixel */ 467 free((void *) overlay_info); 468 return ov->value; 469 } 470 } 471 } 472 473 /* The visual ID was not found in the overlay list. */ 474 free((void *) overlay_info); 475 return -1; 476 } 477 478 479 480 /** 481 * Try to get an X visual which matches the given arguments. 482 */ 483 static XVisualInfo * 484 get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) 485 { 486 XVisualInfo temp, *vis; 487 long mask; 488 int n; 489 unsigned int default_depth; 490 int default_class; 491 492 mask = VisualScreenMask | VisualDepthMask | VisualClassMask; 493 temp.screen = scr; 494 temp.depth = depth; 495 temp.CLASS = xclass; 496 497 default_depth = DefaultDepth(dpy,scr); 498 default_class = DefaultVisual(dpy,scr)->CLASS; 499 500 if (depth==default_depth && xclass==default_class) { 501 /* try to get root window's visual */ 502 temp.visualid = DefaultVisual(dpy,scr)->visualid; 503 mask |= VisualIDMask; 504 } 505 506 vis = XGetVisualInfo( dpy, mask, &temp, &n ); 507 508 /* In case bits/pixel > 24, make sure color channels are still <=8 bits. 509 * An SGI Infinite Reality system, for example, can have 30bpp pixels: 510 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. 511 */ 512 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { 513 if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && 514 _mesa_bitcount((GLuint) vis->green_mask) <= 8 && 515 _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { 516 return vis; 517 } 518 else { 519 free((void *) vis); 520 return NULL; 521 } 522 } 523 524 return vis; 525 } 526 527 528 529 /* 530 * Retrieve the value of the given environment variable and find 531 * the X visual which matches it. 532 * Input: dpy - the display 533 * screen - the screen number 534 * varname - the name of the environment variable 535 * Return: an XVisualInfo pointer to NULL if error. 536 */ 537 static XVisualInfo * 538 get_env_visual(Display *dpy, int scr, const char *varname) 539 { 540 char value[100], type[100]; 541 int depth, xclass = -1; 542 XVisualInfo *vis; 543 544 if (!getenv( varname )) { 545 return NULL; 546 } 547 548 strncpy( value, getenv(varname), 100 ); 549 value[99] = 0; 550 551 sscanf( value, "%s %d", type, &depth ); 552 553 if (strcmp(type,"TrueColor")==0) xclass = TrueColor; 554 else if (strcmp(type,"DirectColor")==0) xclass = DirectColor; 555 else if (strcmp(type,"GrayScale")==0) xclass = GrayScale; 556 else if (strcmp(type,"StaticGray")==0) xclass = StaticGray; 557 558 if (xclass>-1 && depth>0) { 559 vis = get_visual( dpy, scr, depth, xclass ); 560 if (vis) { 561 return vis; 562 } 563 } 564 565 _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", 566 type, depth); 567 568 return NULL; 569 } 570 571 572 573 /* 574 * Select an X visual which satisfies the RGBA/CI flag and minimum depth. 575 * Input: dpy, screen - X display and screen number 576 * min_depth - minimum visual depth 577 * preferred_class - preferred GLX visual class or DONT_CARE 578 * Return: pointer to an XVisualInfo or NULL. 579 */ 580 static XVisualInfo * 581 choose_x_visual(Display *dpy, int screen, int min_depth, int preferred_class) 582 { 583 XVisualInfo *vis; 584 int xclass, visclass = 0; 585 int depth; 586 587 /* First see if the MESA_RGB_VISUAL env var is defined */ 588 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); 589 if (vis) { 590 return vis; 591 } 592 /* Otherwise, search for a suitable visual */ 593 if (preferred_class==DONT_CARE) { 594 for (xclass=0;xclass<4;xclass++) { 595 switch (xclass) { 596 case 0: visclass = TrueColor; break; 597 case 1: visclass = DirectColor; break; 598 case 2: visclass = GrayScale; break; 599 case 3: visclass = StaticGray; break; 600 } 601 if (min_depth==0) { 602 /* start with shallowest */ 603 for (depth=0;depth<=32;depth++) { 604 vis = get_visual( dpy, screen, depth, visclass ); 605 if (vis) { 606 return vis; 607 } 608 } 609 } 610 else { 611 /* start with deepest */ 612 for (depth=32;depth>=min_depth;depth--) { 613 vis = get_visual( dpy, screen, depth, visclass ); 614 if (vis) { 615 return vis; 616 } 617 } 618 } 619 } 620 } 621 else { 622 /* search for a specific visual class */ 623 switch (preferred_class) { 624 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; 625 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; 626 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; 627 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; 628 case GLX_PSEUDO_COLOR_EXT: 629 case GLX_STATIC_COLOR_EXT: 630 default: return NULL; 631 } 632 if (min_depth==0) { 633 /* start with shallowest */ 634 for (depth=0;depth<=32;depth++) { 635 vis = get_visual( dpy, screen, depth, visclass ); 636 if (vis) { 637 return vis; 638 } 639 } 640 } 641 else { 642 /* start with deepest */ 643 for (depth=32;depth>=min_depth;depth--) { 644 vis = get_visual( dpy, screen, depth, visclass ); 645 if (vis) { 646 return vis; 647 } 648 } 649 } 650 } 651 652 /* didn't find a visual */ 653 return NULL; 654 } 655 656 657 658 /* 659 * Find the deepest X over/underlay visual of at least min_depth. 660 * Input: dpy, screen - X display and screen number 661 * level - the over/underlay level 662 * trans_type - transparent pixel type: GLX_NONE_EXT, 663 * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT, 664 * or DONT_CARE 665 * trans_value - transparent pixel value or DONT_CARE 666 * min_depth - minimum visual depth 667 * preferred_class - preferred GLX visual class or DONT_CARE 668 * Return: pointer to an XVisualInfo or NULL. 669 */ 670 static XVisualInfo * 671 choose_x_overlay_visual( Display *dpy, int scr, 672 int level, int trans_type, int trans_value, 673 int min_depth, int preferred_class ) 674 { 675 OverlayInfo *overlay_info; 676 int numOverlaysPerScreen; 677 int i; 678 XVisualInfo *deepvis; 679 int deepest; 680 681 /*DEBUG int tt, tv; */ 682 683 switch (preferred_class) { 684 case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break; 685 case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break; 686 case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break; 687 case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break; 688 case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break; 689 case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break; 690 default: preferred_class = DONT_CARE; 691 } 692 693 overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); 694 if (!overlay_info) { 695 return NULL; 696 } 697 698 /* Search for the deepest overlay which satisifies all criteria. */ 699 deepest = min_depth; 700 deepvis = NULL; 701 702 for (i = 0; i < numOverlaysPerScreen; i++) { 703 const OverlayInfo *ov = overlay_info + i; 704 XVisualInfo *vislist, vistemplate; 705 int count; 706 707 if (ov->layer!=level) { 708 /* failed overlay level criteria */ 709 continue; 710 } 711 if (!(trans_type==DONT_CARE 712 || (trans_type==GLX_TRANSPARENT_INDEX_EXT 713 && ov->transparent_type>0) 714 || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) { 715 /* failed transparent pixel type criteria */ 716 continue; 717 } 718 if (trans_value!=DONT_CARE && trans_value!=ov->value) { 719 /* failed transparent pixel value criteria */ 720 continue; 721 } 722 723 /* get XVisualInfo and check the depth */ 724 vistemplate.visualid = ov->overlay_visual; 725 vistemplate.screen = scr; 726 vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, 727 &vistemplate, &count ); 728 729 if (!vislist) { 730 /* no matches */ 731 continue; 732 } 733 734 if (count!=1) { 735 /* something went wrong */ 736 free(vislist); 737 continue; 738 } 739 if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { 740 /* wrong visual class */ 741 free(vislist); 742 continue; 743 } 744 745 /* Color-index rendering is not supported. Make sure we have True/DirectColor */ 746 if (vislist->CLASS != TrueColor && vislist->CLASS != DirectColor) { 747 free(vislist); 748 continue; 749 } 750 751 if (deepvis!=NULL && vislist->depth <= deepest) { 752 free(vislist); 753 continue; 754 } 755 756 /* YES! found a satisfactory visual */ 757 free(deepvis); 758 deepest = vislist->depth; 759 deepvis = vislist; 760 /* DEBUG tt = ov->transparent_type;*/ 761 /* DEBUG tv = ov->value; */ 762 } 763 764 /*DEBUG 765 if (deepvis) { 766 printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n", 767 deepvis->visualid, level, deepvis->depth, tt, tv ); 768 } 769 */ 770 return deepvis; 771 } 772 773 774 /**********************************************************************/ 775 /*** Display-related functions ***/ 776 /**********************************************************************/ 777 778 779 /** 780 * Free all XMesaVisuals which are associated with the given display. 781 */ 782 static void 783 destroy_visuals_on_display(Display *dpy) 784 { 785 int i; 786 for (i = 0; i < NumVisuals; i++) { 787 if (VisualTable[i]->display == dpy) { 788 /* remove this visual */ 789 int j; 790 XMesaDestroyVisual(VisualTable[i]); 791 for (j = i; j < NumVisuals - 1; j++) 792 VisualTable[j] = VisualTable[j + 1]; 793 NumVisuals--; 794 } 795 } 796 } 797 798 799 /** 800 * Called from XCloseDisplay() to let us free our display-related data. 801 */ 802 static int 803 close_display_callback(Display *dpy, XExtCodes *codes) 804 { 805 destroy_visuals_on_display(dpy); 806 xmesa_destroy_buffers_on_display(dpy); 807 return 0; 808 } 809 810 811 /** 812 * Look for the named extension on given display and return a pointer 813 * to the _XExtension data, or NULL if extension not found. 814 */ 815 static _XExtension * 816 lookup_extension(Display *dpy, const char *extName) 817 { 818 _XExtension *ext; 819 for (ext = dpy->ext_procs; ext; ext = ext->next) { 820 if (ext->name && strcmp(ext->name, extName) == 0) { 821 return ext; 822 } 823 } 824 return NULL; 825 } 826 827 828 /** 829 * Whenever we're given a new Display pointer, call this function to 830 * register our close_display_callback function. 831 */ 832 static void 833 register_with_display(Display *dpy) 834 { 835 const char *extName = "MesaGLX"; 836 _XExtension *ext; 837 838 ext = lookup_extension(dpy, extName); 839 if (!ext) { 840 XExtCodes *c = XAddExtension(dpy); 841 ext = dpy->ext_procs; /* new extension is at head of list */ 842 assert(c->extension == ext->codes.extension); 843 (void) c; /* silence warning */ 844 ext->name = strdup(extName); 845 ext->close_display = close_display_callback; 846 } 847 } 848 849 850 /**********************************************************************/ 851 /*** Begin Fake GLX API Functions ***/ 852 /**********************************************************************/ 853 854 855 /** 856 * Helper used by glXChooseVisual and glXChooseFBConfig. 857 * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for 858 * the later. 859 * In either case, the attribute list is terminated with the value 'None'. 860 */ 861 static XMesaVisual 862 choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 863 { 864 const GLboolean rgbModeDefault = fbConfig; 865 const int *parselist; 866 XVisualInfo *vis; 867 int min_ci = 0; 868 int min_red=0, min_green=0, min_blue=0; 869 GLboolean rgb_flag = rgbModeDefault; 870 GLboolean alpha_flag = GL_FALSE; 871 GLboolean double_flag = GL_FALSE; 872 GLboolean stereo_flag = GL_FALSE; 873 GLint depth_size = 0; 874 GLint stencil_size = 0; 875 GLint accumRedSize = 0; 876 GLint accumGreenSize = 0; 877 GLint accumBlueSize = 0; 878 GLint accumAlphaSize = 0; 879 int level = 0; 880 int visual_type = DONT_CARE; 881 int trans_type = DONT_CARE; 882 int trans_value = DONT_CARE; 883 GLint caveat = DONT_CARE; 884 XMesaVisual xmvis = NULL; 885 int desiredVisualID = -1; 886 int numAux = 0; 887 888 parselist = list; 889 890 while (*parselist) { 891 892 if (fbConfig && 893 parselist[1] == GLX_DONT_CARE && 894 parselist[0] != GLX_LEVEL) { 895 /* For glXChooseFBConfig(), skip attributes whose value is 896 * GLX_DONT_CARE (-1), unless it's GLX_LEVEL (which can legitimately be 897 * a negative value). 898 * 899 * From page 17 (23 of the pdf) of the GLX 1.4 spec: 900 * GLX DONT CARE may be specified for all attributes except GLX LEVEL. 901 */ 902 parselist += 2; 903 continue; 904 } 905 906 switch (*parselist) { 907 case GLX_USE_GL: 908 if (fbConfig) { 909 /* invalid token */ 910 return NULL; 911 } 912 else { 913 /* skip */ 914 parselist++; 915 } 916 break; 917 case GLX_BUFFER_SIZE: 918 parselist++; 919 min_ci = *parselist++; 920 break; 921 case GLX_LEVEL: 922 parselist++; 923 level = *parselist++; 924 break; 925 case GLX_RGBA: 926 if (fbConfig) { 927 /* invalid token */ 928 return NULL; 929 } 930 else { 931 rgb_flag = GL_TRUE; 932 parselist++; 933 } 934 break; 935 case GLX_DOUBLEBUFFER: 936 parselist++; 937 if (fbConfig) { 938 double_flag = *parselist++; 939 } 940 else { 941 double_flag = GL_TRUE; 942 } 943 break; 944 case GLX_STEREO: 945 parselist++; 946 if (fbConfig) { 947 stereo_flag = *parselist++; 948 } 949 else { 950 stereo_flag = GL_TRUE; 951 } 952 break; 953 case GLX_AUX_BUFFERS: 954 parselist++; 955 numAux = *parselist++; 956 if (numAux > MAX_AUX_BUFFERS) 957 return NULL; 958 break; 959 case GLX_RED_SIZE: 960 parselist++; 961 min_red = *parselist++; 962 break; 963 case GLX_GREEN_SIZE: 964 parselist++; 965 min_green = *parselist++; 966 break; 967 case GLX_BLUE_SIZE: 968 parselist++; 969 min_blue = *parselist++; 970 break; 971 case GLX_ALPHA_SIZE: 972 parselist++; 973 { 974 GLint size = *parselist++; 975 alpha_flag = size ? GL_TRUE : GL_FALSE; 976 } 977 break; 978 case GLX_DEPTH_SIZE: 979 parselist++; 980 depth_size = *parselist++; 981 break; 982 case GLX_STENCIL_SIZE: 983 parselist++; 984 stencil_size = *parselist++; 985 break; 986 case GLX_ACCUM_RED_SIZE: 987 parselist++; 988 { 989 GLint size = *parselist++; 990 accumRedSize = MAX2( accumRedSize, size ); 991 } 992 break; 993 case GLX_ACCUM_GREEN_SIZE: 994 parselist++; 995 { 996 GLint size = *parselist++; 997 accumGreenSize = MAX2( accumGreenSize, size ); 998 } 999 break; 1000 case GLX_ACCUM_BLUE_SIZE: 1001 parselist++; 1002 { 1003 GLint size = *parselist++; 1004 accumBlueSize = MAX2( accumBlueSize, size ); 1005 } 1006 break; 1007 case GLX_ACCUM_ALPHA_SIZE: 1008 parselist++; 1009 { 1010 GLint size = *parselist++; 1011 accumAlphaSize = MAX2( accumAlphaSize, size ); 1012 } 1013 break; 1014 1015 /* 1016 * GLX_EXT_visual_info extension 1017 */ 1018 case GLX_X_VISUAL_TYPE_EXT: 1019 parselist++; 1020 visual_type = *parselist++; 1021 break; 1022 case GLX_TRANSPARENT_TYPE_EXT: 1023 parselist++; 1024 trans_type = *parselist++; 1025 break; 1026 case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1027 parselist++; 1028 trans_value = *parselist++; 1029 break; 1030 case GLX_TRANSPARENT_RED_VALUE_EXT: 1031 case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1032 case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1033 case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1034 /* ignore */ 1035 parselist++; 1036 parselist++; 1037 break; 1038 1039 /* 1040 * GLX_EXT_visual_info extension 1041 */ 1042 case GLX_VISUAL_CAVEAT_EXT: 1043 parselist++; 1044 caveat = *parselist++; /* ignored for now */ 1045 break; 1046 1047 /* 1048 * GLX_ARB_multisample 1049 */ 1050 case GLX_SAMPLE_BUFFERS_ARB: 1051 case GLX_SAMPLES_ARB: 1052 parselist++; 1053 if (*parselist++ != 0) 1054 /* ms not supported */ 1055 return NULL; 1056 break; 1057 1058 /* 1059 * FBConfig attribs. 1060 */ 1061 case GLX_RENDER_TYPE: 1062 if (!fbConfig) 1063 return NULL; 1064 parselist++; 1065 if (*parselist & GLX_RGBA_BIT) { 1066 rgb_flag = GL_TRUE; 1067 } 1068 else if (*parselist & GLX_COLOR_INDEX_BIT) { 1069 rgb_flag = GL_FALSE; 1070 } 1071 else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) { 1072 rgb_flag = GL_TRUE; 1073 } 1074 else if (*parselist == 0) { 1075 rgb_flag = GL_TRUE; 1076 } 1077 parselist++; 1078 break; 1079 case GLX_DRAWABLE_TYPE: 1080 if (!fbConfig) 1081 return NULL; 1082 parselist++; 1083 if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { 1084 return NULL; /* bad bit */ 1085 } 1086 parselist++; 1087 break; 1088 case GLX_FBCONFIG_ID: 1089 case GLX_VISUAL_ID: 1090 if (!fbConfig) 1091 return NULL; 1092 parselist++; 1093 desiredVisualID = *parselist++; 1094 break; 1095 case GLX_X_RENDERABLE: 1096 case GLX_MAX_PBUFFER_WIDTH: 1097 case GLX_MAX_PBUFFER_HEIGHT: 1098 case GLX_MAX_PBUFFER_PIXELS: 1099 if (!fbConfig) 1100 return NULL; 1101 parselist += 2; 1102 /* ignore */ 1103 break; 1104 1105 case GLX_BIND_TO_TEXTURE_RGB_EXT: 1106 parselist++; /*skip*/ 1107 break; 1108 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1109 parselist++; /*skip*/ 1110 break; 1111 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1112 parselist++; /*skip*/ 1113 break; 1114 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1115 parselist++; 1116 if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | 1117 GLX_TEXTURE_2D_BIT_EXT | 1118 GLX_TEXTURE_RECTANGLE_BIT_EXT)) { 1119 /* invalid bit */ 1120 return NULL; 1121 } 1122 break; 1123 case GLX_Y_INVERTED_EXT: 1124 parselist++; /*skip*/ 1125 break; 1126 1127 case None: 1128 /* end of list */ 1129 break; 1130 1131 default: 1132 /* undefined attribute */ 1133 _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", 1134 *parselist); 1135 return NULL; 1136 } 1137 } 1138 1139 if (!rgb_flag) 1140 return NULL; 1141 1142 (void) caveat; 1143 (void) min_ci; 1144 1145 /* 1146 * Since we're only simulating the GLX extension this function will never 1147 * find any real GL visuals. Instead, all we can do is try to find an RGB 1148 * or CI visual of appropriate depth. Other requested attributes such as 1149 * double buffering, depth buffer, etc. will be associated with the X 1150 * visual and stored in the VisualTable[]. 1151 */ 1152 if (desiredVisualID != -1) { 1153 /* try to get a specific visual, by visualID */ 1154 XVisualInfo temp; 1155 int n; 1156 temp.visualid = desiredVisualID; 1157 temp.screen = screen; 1158 vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); 1159 if (vis) { 1160 /* give the visual some useful GLX attributes */ 1161 double_flag = GL_TRUE; 1162 if (vis->depth <= 8) 1163 return NULL; 1164 depth_size = default_depth_bits(); 1165 stencil_size = 8; 1166 /* XXX accum??? */ 1167 } 1168 } 1169 else { 1170 /* RGB visual */ 1171 int min_rgb = min_red + min_green + min_blue; 1172 if (min_rgb>1 && min_rgb<8) { 1173 /* a special case to be sure we can get a monochrome visual */ 1174 min_rgb = 1; 1175 } 1176 1177 if (level==0) { 1178 vis = choose_x_visual(dpy, screen, min_rgb, visual_type); 1179 } 1180 else { 1181 vis = choose_x_overlay_visual(dpy, screen, level, 1182 trans_type, trans_value, min_rgb, visual_type); 1183 } 1184 } 1185 1186 if (vis) { 1187 /* Note: we're not exactly obeying the glXChooseVisual rules here. 1188 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the 1189 * largest depth buffer size, which is 32bits/value. Instead, we 1190 * return 16 to maintain performance with earlier versions of Mesa. 1191 */ 1192 if (depth_size > 24) 1193 depth_size = 32; 1194 else if (depth_size > 16) 1195 depth_size = 24; 1196 else if (depth_size > 0) { 1197 depth_size = default_depth_bits(); 1198 } 1199 1200 if (!alpha_flag) { 1201 alpha_flag = default_alpha_bits() > 0; 1202 } 1203 1204 /* we only support one size of stencil and accum buffers. */ 1205 if (stencil_size > 0) 1206 stencil_size = 8; 1207 if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || 1208 accumAlphaSize > 0) { 1209 accumRedSize = 1210 accumGreenSize = 1211 accumBlueSize = default_accum_bits(); 1212 accumAlphaSize = alpha_flag ? accumRedSize : 0; 1213 } 1214 1215 xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag, 1216 stereo_flag, depth_size, stencil_size, 1217 accumRedSize, accumGreenSize, 1218 accumBlueSize, accumAlphaSize, level, numAux ); 1219 free(vis); 1220 } 1221 1222 return xmvis; 1223 } 1224 1225 1226 static XVisualInfo * 1227 Fake_glXChooseVisual( Display *dpy, int screen, int *list ) 1228 { 1229 XMesaVisual xmvis; 1230 1231 /* register ourselves as an extension on this display */ 1232 register_with_display(dpy); 1233 1234 xmvis = choose_visual(dpy, screen, list, GL_FALSE); 1235 if (xmvis) { 1236 XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1237 if (visinfo) { 1238 memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1239 } 1240 return visinfo; 1241 } 1242 else 1243 return NULL; 1244 } 1245 1246 1247 static GLXContext 1248 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, 1249 GLXContext share_list, Bool direct ) 1250 { 1251 XMesaVisual xmvis; 1252 XMesaContext xmesaCtx; 1253 1254 if (!dpy || !visinfo) 1255 return 0; 1256 1257 /* deallocate unused windows/buffers */ 1258 #if 0 1259 XMesaGarbageCollect(dpy); 1260 #endif 1261 1262 xmvis = find_glx_visual( dpy, visinfo ); 1263 if (!xmvis) { 1264 /* This visual wasn't found with glXChooseVisual() */ 1265 xmvis = create_glx_visual( dpy, visinfo ); 1266 if (!xmvis) { 1267 return NULL; 1268 } 1269 } 1270 1271 xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 1272 1273 return (GLXContext) xmesaCtx; 1274 } 1275 1276 1277 /* XXX these may have to be removed due to thread-safety issues. */ 1278 static GLXContext MakeCurrent_PrevContext = 0; 1279 static GLXDrawable MakeCurrent_PrevDrawable = 0; 1280 static GLXDrawable MakeCurrent_PrevReadable = 0; 1281 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; 1282 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; 1283 1284 1285 /* GLX 1.3 and later */ 1286 static Bool 1287 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, 1288 GLXDrawable read, GLXContext ctx ) 1289 { 1290 if (ctx && draw && read) { 1291 XMesaBuffer drawBuffer, readBuffer; 1292 XMesaContext xmctx = (XMesaContext) ctx; 1293 1294 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ 1295 if (ctx == MakeCurrent_PrevContext 1296 && draw == MakeCurrent_PrevDrawable) { 1297 drawBuffer = MakeCurrent_PrevDrawBuffer; 1298 } 1299 else { 1300 drawBuffer = XMesaFindBuffer( dpy, draw ); 1301 } 1302 if (!drawBuffer) { 1303 /* drawable must be a new window! */ 1304 drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); 1305 if (!drawBuffer) { 1306 /* Out of memory, or context/drawable depth mismatch */ 1307 return False; 1308 } 1309 } 1310 1311 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ 1312 if (ctx == MakeCurrent_PrevContext 1313 && read == MakeCurrent_PrevReadable) { 1314 readBuffer = MakeCurrent_PrevReadBuffer; 1315 } 1316 else { 1317 readBuffer = XMesaFindBuffer( dpy, read ); 1318 } 1319 if (!readBuffer) { 1320 /* drawable must be a new window! */ 1321 readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); 1322 if (!readBuffer) { 1323 /* Out of memory, or context/drawable depth mismatch */ 1324 return False; 1325 } 1326 } 1327 1328 MakeCurrent_PrevContext = ctx; 1329 MakeCurrent_PrevDrawable = draw; 1330 MakeCurrent_PrevReadable = read; 1331 MakeCurrent_PrevDrawBuffer = drawBuffer; 1332 MakeCurrent_PrevReadBuffer = readBuffer; 1333 1334 /* Now make current! */ 1335 return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer); 1336 } 1337 else if (!ctx && !draw && !read) { 1338 /* release current context w/out assigning new one. */ 1339 XMesaMakeCurrent( NULL, NULL ); 1340 MakeCurrent_PrevContext = 0; 1341 MakeCurrent_PrevDrawable = 0; 1342 MakeCurrent_PrevReadable = 0; 1343 MakeCurrent_PrevDrawBuffer = 0; 1344 MakeCurrent_PrevReadBuffer = 0; 1345 return True; 1346 } 1347 else { 1348 /* The args must either all be non-zero or all zero. 1349 * This is an error. 1350 */ 1351 return False; 1352 } 1353 } 1354 1355 1356 static Bool 1357 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) 1358 { 1359 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); 1360 } 1361 1362 1363 static GLXPixmap 1364 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) 1365 { 1366 XMesaVisual v; 1367 XMesaBuffer b; 1368 1369 v = find_glx_visual( dpy, visinfo ); 1370 if (!v) { 1371 v = create_glx_visual( dpy, visinfo ); 1372 if (!v) { 1373 /* unusable visual */ 1374 return 0; 1375 } 1376 } 1377 1378 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 1379 if (!b) { 1380 return 0; 1381 } 1382 return b->frontxrb->pixmap; 1383 } 1384 1385 1386 /*** GLX_MESA_pixmap_colormap ***/ 1387 1388 static GLXPixmap 1389 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, 1390 Pixmap pixmap, Colormap cmap ) 1391 { 1392 XMesaVisual v; 1393 XMesaBuffer b; 1394 1395 v = find_glx_visual( dpy, visinfo ); 1396 if (!v) { 1397 v = create_glx_visual( dpy, visinfo ); 1398 if (!v) { 1399 /* unusable visual */ 1400 return 0; 1401 } 1402 } 1403 1404 b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); 1405 if (!b) { 1406 return 0; 1407 } 1408 return b->frontxrb->pixmap; 1409 } 1410 1411 1412 static void 1413 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) 1414 { 1415 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); 1416 if (b) { 1417 XMesaDestroyBuffer(b); 1418 } 1419 else if (getenv("MESA_DEBUG")) { 1420 _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); 1421 } 1422 } 1423 1424 1425 static void 1426 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, 1427 unsigned long mask ) 1428 { 1429 XMesaContext xmSrc = (XMesaContext) src; 1430 XMesaContext xmDst = (XMesaContext) dst; 1431 (void) dpy; 1432 if (MakeCurrent_PrevContext == src) { 1433 _mesa_Flush(); 1434 } 1435 _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask ); 1436 } 1437 1438 1439 static Bool 1440 Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) 1441 { 1442 int op, ev, err; 1443 /* Mesa's GLX isn't really an X extension but we try to act like one. */ 1444 if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err)) 1445 ev = err = 0; 1446 if (errorBase) 1447 *errorBase = err; 1448 if (eventBase) 1449 *eventBase = ev; 1450 return True; /* we're faking GLX so always return success */ 1451 } 1452 1453 1454 extern void _kw_ungrab_all( Display *dpy ); 1455 void _kw_ungrab_all( Display *dpy ) 1456 { 1457 XUngrabPointer( dpy, CurrentTime ); 1458 XUngrabKeyboard( dpy, CurrentTime ); 1459 } 1460 1461 1462 static void 1463 Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) 1464 { 1465 if (ctx) { 1466 (void) dpy; 1467 MakeCurrent_PrevContext = 0; 1468 MakeCurrent_PrevDrawable = 0; 1469 MakeCurrent_PrevReadable = 0; 1470 MakeCurrent_PrevDrawBuffer = 0; 1471 MakeCurrent_PrevReadBuffer = 0; 1472 XMesaDestroyContext((XMesaContext) ctx); 1473 XMesaGarbageCollect(dpy); 1474 } 1475 } 1476 1477 1478 static Bool 1479 Fake_glXIsDirect( Display *dpy, GLXContext ctx ) 1480 { 1481 XMesaContext xmCtx = (XMesaContext) ctx; 1482 return xmCtx ? xmCtx->direct : False; 1483 } 1484 1485 1486 1487 static void 1488 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) 1489 { 1490 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1491 1492 if (buffer) { 1493 XMesaSwapBuffers(buffer); 1494 } 1495 else if (getenv("MESA_DEBUG")) { 1496 _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", 1497 (int) drawable); 1498 } 1499 } 1500 1501 1502 1503 /*** GLX_MESA_copy_sub_buffer ***/ 1504 1505 static void 1506 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, 1507 int x, int y, int width, int height ) 1508 { 1509 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1510 if (buffer) { 1511 XMesaCopySubBuffer(buffer, x, y, width, height); 1512 } 1513 else if (getenv("MESA_DEBUG")) { 1514 _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); 1515 } 1516 } 1517 1518 1519 static Bool 1520 Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) 1521 { 1522 (void) dpy; 1523 /* Return GLX version, not Mesa version */ 1524 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); 1525 *maj = CLIENT_MAJOR_VERSION; 1526 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); 1527 return True; 1528 } 1529 1530 1531 /* 1532 * Query the GLX attributes of the given XVisualInfo. 1533 */ 1534 static int 1535 get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) 1536 { 1537 assert(xmvis); 1538 switch(attrib) { 1539 case GLX_USE_GL: 1540 if (fbconfig) 1541 return GLX_BAD_ATTRIBUTE; 1542 *value = (int) True; 1543 return 0; 1544 case GLX_BUFFER_SIZE: 1545 *value = xmvis->visinfo->depth; 1546 return 0; 1547 case GLX_LEVEL: 1548 *value = xmvis->mesa_visual.level; 1549 return 0; 1550 case GLX_RGBA: 1551 if (fbconfig) 1552 return GLX_BAD_ATTRIBUTE; 1553 if (xmvis->mesa_visual.rgbMode) { 1554 *value = True; 1555 } 1556 else { 1557 *value = False; 1558 } 1559 return 0; 1560 case GLX_DOUBLEBUFFER: 1561 *value = (int) xmvis->mesa_visual.doubleBufferMode; 1562 return 0; 1563 case GLX_STEREO: 1564 *value = (int) xmvis->mesa_visual.stereoMode; 1565 return 0; 1566 case GLX_AUX_BUFFERS: 1567 *value = xmvis->mesa_visual.numAuxBuffers; 1568 return 0; 1569 case GLX_RED_SIZE: 1570 *value = xmvis->mesa_visual.redBits; 1571 return 0; 1572 case GLX_GREEN_SIZE: 1573 *value = xmvis->mesa_visual.greenBits; 1574 return 0; 1575 case GLX_BLUE_SIZE: 1576 *value = xmvis->mesa_visual.blueBits; 1577 return 0; 1578 case GLX_ALPHA_SIZE: 1579 *value = xmvis->mesa_visual.alphaBits; 1580 return 0; 1581 case GLX_DEPTH_SIZE: 1582 *value = xmvis->mesa_visual.depthBits; 1583 return 0; 1584 case GLX_STENCIL_SIZE: 1585 *value = xmvis->mesa_visual.stencilBits; 1586 return 0; 1587 case GLX_ACCUM_RED_SIZE: 1588 *value = xmvis->mesa_visual.accumRedBits; 1589 return 0; 1590 case GLX_ACCUM_GREEN_SIZE: 1591 *value = xmvis->mesa_visual.accumGreenBits; 1592 return 0; 1593 case GLX_ACCUM_BLUE_SIZE: 1594 *value = xmvis->mesa_visual.accumBlueBits; 1595 return 0; 1596 case GLX_ACCUM_ALPHA_SIZE: 1597 *value = xmvis->mesa_visual.accumAlphaBits; 1598 return 0; 1599 1600 /* 1601 * GLX_EXT_visual_info extension 1602 */ 1603 case GLX_X_VISUAL_TYPE_EXT: 1604 switch (xmvis->visinfo->CLASS) { 1605 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; 1606 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; 1607 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; 1608 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; 1609 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; 1610 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; 1611 } 1612 return 0; 1613 case GLX_TRANSPARENT_TYPE_EXT: 1614 if (xmvis->mesa_visual.level==0) { 1615 /* normal planes */ 1616 *value = GLX_NONE_EXT; 1617 } 1618 else if (xmvis->mesa_visual.level>0) { 1619 /* overlay */ 1620 if (xmvis->mesa_visual.rgbMode) { 1621 *value = GLX_TRANSPARENT_RGB_EXT; 1622 } 1623 else { 1624 *value = GLX_TRANSPARENT_INDEX_EXT; 1625 } 1626 } 1627 else if (xmvis->mesa_visual.level<0) { 1628 /* underlay */ 1629 *value = GLX_NONE_EXT; 1630 } 1631 return 0; 1632 case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1633 { 1634 int pixel = transparent_pixel( xmvis ); 1635 if (pixel>=0) { 1636 *value = pixel; 1637 } 1638 /* else undefined */ 1639 } 1640 return 0; 1641 case GLX_TRANSPARENT_RED_VALUE_EXT: 1642 /* undefined */ 1643 return 0; 1644 case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1645 /* undefined */ 1646 return 0; 1647 case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1648 /* undefined */ 1649 return 0; 1650 case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1651 /* undefined */ 1652 return 0; 1653 1654 /* 1655 * GLX_EXT_visual_info extension 1656 */ 1657 case GLX_VISUAL_CAVEAT_EXT: 1658 /* test for zero, just in case */ 1659 if (xmvis->mesa_visual.visualRating > 0) 1660 *value = xmvis->mesa_visual.visualRating; 1661 else 1662 *value = GLX_NONE_EXT; 1663 return 0; 1664 1665 /* 1666 * GLX_ARB_multisample 1667 */ 1668 case GLX_SAMPLE_BUFFERS_ARB: 1669 *value = 0; 1670 return 0; 1671 case GLX_SAMPLES_ARB: 1672 *value = 0; 1673 return 0; 1674 1675 /* 1676 * For FBConfigs: 1677 */ 1678 case GLX_SCREEN_EXT: 1679 if (!fbconfig) 1680 return GLX_BAD_ATTRIBUTE; 1681 *value = xmvis->visinfo->screen; 1682 break; 1683 case GLX_DRAWABLE_TYPE: /*SGIX too */ 1684 if (!fbconfig) 1685 return GLX_BAD_ATTRIBUTE; 1686 *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; 1687 break; 1688 case GLX_RENDER_TYPE_SGIX: 1689 if (!fbconfig) 1690 return GLX_BAD_ATTRIBUTE; 1691 if (xmvis->mesa_visual.floatMode) 1692 *value = GLX_RGBA_FLOAT_BIT_ARB; 1693 else if (xmvis->mesa_visual.rgbMode) 1694 *value = GLX_RGBA_BIT; 1695 else 1696 *value = GLX_COLOR_INDEX_BIT; 1697 break; 1698 case GLX_X_RENDERABLE_SGIX: 1699 if (!fbconfig) 1700 return GLX_BAD_ATTRIBUTE; 1701 *value = True; /* XXX really? */ 1702 break; 1703 case GLX_FBCONFIG_ID_SGIX: 1704 if (!fbconfig) 1705 return GLX_BAD_ATTRIBUTE; 1706 *value = xmvis->visinfo->visualid; 1707 break; 1708 case GLX_MAX_PBUFFER_WIDTH: 1709 if (!fbconfig) 1710 return GLX_BAD_ATTRIBUTE; 1711 /* XXX should be same as ctx->Const.MaxRenderbufferSize */ 1712 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); 1713 break; 1714 case GLX_MAX_PBUFFER_HEIGHT: 1715 if (!fbconfig) 1716 return GLX_BAD_ATTRIBUTE; 1717 *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1718 break; 1719 case GLX_MAX_PBUFFER_PIXELS: 1720 if (!fbconfig) 1721 return GLX_BAD_ATTRIBUTE; 1722 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * 1723 DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1724 break; 1725 case GLX_VISUAL_ID: 1726 if (!fbconfig) 1727 return GLX_BAD_ATTRIBUTE; 1728 *value = xmvis->visinfo->visualid; 1729 break; 1730 1731 case GLX_BIND_TO_TEXTURE_RGB_EXT: 1732 *value = True; /*XXX*/ 1733 break; 1734 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1735 /* XXX review */ 1736 *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; 1737 break; 1738 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1739 *value = True; /*XXX*/ 1740 break; 1741 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1742 *value = (GLX_TEXTURE_1D_BIT_EXT | 1743 GLX_TEXTURE_2D_BIT_EXT | 1744 GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ 1745 break; 1746 case GLX_Y_INVERTED_EXT: 1747 *value = True; /*XXX*/ 1748 break; 1749 1750 default: 1751 return GLX_BAD_ATTRIBUTE; 1752 } 1753 return Success; 1754 } 1755 1756 1757 static int 1758 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, 1759 int attrib, int *value ) 1760 { 1761 XMesaVisual xmvis; 1762 int k; 1763 if (!dpy || !visinfo) 1764 return GLX_BAD_ATTRIBUTE; 1765 1766 xmvis = find_glx_visual( dpy, visinfo ); 1767 if (!xmvis) { 1768 /* this visual wasn't obtained with glXChooseVisual */ 1769 xmvis = create_glx_visual( dpy, visinfo ); 1770 if (!xmvis) { 1771 /* this visual can't be used for GL rendering */ 1772 if (attrib==GLX_USE_GL) { 1773 *value = (int) False; 1774 return 0; 1775 } 1776 else { 1777 return GLX_BAD_VISUAL; 1778 } 1779 } 1780 } 1781 1782 k = get_config(xmvis, attrib, value, GL_FALSE); 1783 return k; 1784 } 1785 1786 1787 static GLXContext 1788 Fake_glXGetCurrentContext(void) 1789 { 1790 XMesaContext xmesa = XMesaGetCurrentContext(); 1791 return (GLXContext) xmesa; 1792 } 1793 1794 static void 1795 Fake_glXWaitGL( void ) 1796 { 1797 XMesaContext xmesa = XMesaGetCurrentContext(); 1798 XMesaFlush( xmesa ); 1799 } 1800 1801 1802 1803 static void 1804 Fake_glXWaitX( void ) 1805 { 1806 XMesaContext xmesa = XMesaGetCurrentContext(); 1807 XMesaFlush( xmesa ); 1808 } 1809 1810 1811 static const char * 1812 get_extensions( void ) 1813 { 1814 return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ 1815 } 1816 1817 1818 1819 /* GLX 1.1 and later */ 1820 static const char * 1821 Fake_glXQueryExtensionsString( Display *dpy, int screen ) 1822 { 1823 (void) dpy; 1824 (void) screen; 1825 return get_extensions(); 1826 } 1827 1828 1829 1830 /* GLX 1.1 and later */ 1831 static const char * 1832 Fake_glXQueryServerString( Display *dpy, int screen, int name ) 1833 { 1834 static char version[1000]; 1835 sprintf(version, "%d.%d %s", 1836 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); 1837 1838 (void) dpy; 1839 (void) screen; 1840 1841 switch (name) { 1842 case GLX_EXTENSIONS: 1843 return get_extensions(); 1844 case GLX_VENDOR: 1845 return VENDOR; 1846 case GLX_VERSION: 1847 return version; 1848 default: 1849 return NULL; 1850 } 1851 } 1852 1853 1854 1855 /* GLX 1.1 and later */ 1856 static const char * 1857 Fake_glXGetClientString( Display *dpy, int name ) 1858 { 1859 static char version[1000]; 1860 sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, 1861 CLIENT_MINOR_VERSION, MESA_GLX_VERSION); 1862 1863 (void) dpy; 1864 1865 switch (name) { 1866 case GLX_EXTENSIONS: 1867 return get_extensions(); 1868 case GLX_VENDOR: 1869 return VENDOR; 1870 case GLX_VERSION: 1871 return version; 1872 default: 1873 return NULL; 1874 } 1875 } 1876 1877 1878 1879 /* 1880 * GLX 1.3 and later 1881 */ 1882 1883 1884 static int 1885 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, 1886 int attribute, int *value ) 1887 { 1888 XMesaVisual v = (XMesaVisual) config; 1889 (void) dpy; 1890 (void) config; 1891 1892 if (!dpy || !config || !value) 1893 return -1; 1894 1895 return get_config(v, attribute, value, GL_TRUE); 1896 } 1897 1898 1899 static GLXFBConfig * 1900 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) 1901 { 1902 XVisualInfo *visuals, visTemplate; 1903 const long visMask = VisualScreenMask; 1904 int i; 1905 1906 /* Get list of all X visuals */ 1907 visTemplate.screen = screen; 1908 visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); 1909 if (*nelements > 0) { 1910 XMesaVisual *results; 1911 results = malloc(*nelements * sizeof(XMesaVisual)); 1912 if (!results) { 1913 *nelements = 0; 1914 return NULL; 1915 } 1916 for (i = 0; i < *nelements; i++) { 1917 results[i] = create_glx_visual(dpy, visuals + i); 1918 } 1919 free(visuals); 1920 return (GLXFBConfig *) results; 1921 } 1922 return NULL; 1923 } 1924 1925 1926 static GLXFBConfig * 1927 Fake_glXChooseFBConfig( Display *dpy, int screen, 1928 const int *attribList, int *nitems ) 1929 { 1930 XMesaVisual xmvis; 1931 1932 /* register ourselves as an extension on this display */ 1933 register_with_display(dpy); 1934 1935 if (!attribList || !attribList[0]) { 1936 /* return list of all configs (per GLX_SGIX_fbconfig spec) */ 1937 return Fake_glXGetFBConfigs(dpy, screen, nitems); 1938 } 1939 1940 xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); 1941 if (xmvis) { 1942 GLXFBConfig *config = malloc(sizeof(XMesaVisual)); 1943 if (!config) { 1944 *nitems = 0; 1945 return NULL; 1946 } 1947 *nitems = 1; 1948 config[0] = (GLXFBConfig) xmvis; 1949 return (GLXFBConfig *) config; 1950 } 1951 else { 1952 *nitems = 0; 1953 return NULL; 1954 } 1955 } 1956 1957 1958 static XVisualInfo * 1959 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) 1960 { 1961 if (dpy && config) { 1962 XMesaVisual xmvis = (XMesaVisual) config; 1963 XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1964 if (visinfo) { 1965 memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1966 } 1967 return visinfo; 1968 } 1969 else { 1970 return NULL; 1971 } 1972 } 1973 1974 1975 static GLXWindow 1976 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, 1977 const int *attribList ) 1978 { 1979 XMesaVisual xmvis = (XMesaVisual) config; 1980 XMesaBuffer xmbuf; 1981 if (!xmvis) 1982 return 0; 1983 1984 xmbuf = XMesaCreateWindowBuffer(xmvis, win); 1985 if (!xmbuf) 1986 return 0; 1987 1988 (void) dpy; 1989 (void) attribList; /* Ignored in GLX 1.3 */ 1990 1991 return win; /* A hack for now */ 1992 } 1993 1994 1995 static void 1996 Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) 1997 { 1998 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); 1999 if (b) 2000 XMesaDestroyBuffer(b); 2001 /* don't destroy X window */ 2002 } 2003 2004 2005 /* XXX untested */ 2006 static GLXPixmap 2007 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, 2008 const int *attribList ) 2009 { 2010 XMesaVisual v = (XMesaVisual) config; 2011 XMesaBuffer b; 2012 const int *attr; 2013 int target = 0, format = 0, mipmap = 0; 2014 int value; 2015 2016 if (!dpy || !config || !pixmap) 2017 return 0; 2018 2019 for (attr = attribList; attr && *attr; attr++) { 2020 switch (*attr) { 2021 case GLX_TEXTURE_FORMAT_EXT: 2022 attr++; 2023 switch (*attr) { 2024 case GLX_TEXTURE_FORMAT_NONE_EXT: 2025 case GLX_TEXTURE_FORMAT_RGB_EXT: 2026 case GLX_TEXTURE_FORMAT_RGBA_EXT: 2027 format = *attr; 2028 break; 2029 default: 2030 /* error */ 2031 return 0; 2032 } 2033 break; 2034 case GLX_TEXTURE_TARGET_EXT: 2035 attr++; 2036 switch (*attr) { 2037 case GLX_TEXTURE_1D_EXT: 2038 case GLX_TEXTURE_2D_EXT: 2039 case GLX_TEXTURE_RECTANGLE_EXT: 2040 target = *attr; 2041 break; 2042 default: 2043 /* error */ 2044 return 0; 2045 } 2046 break; 2047 case GLX_MIPMAP_TEXTURE_EXT: 2048 attr++; 2049 if (*attr) 2050 mipmap = 1; 2051 break; 2052 default: 2053 /* error */ 2054 return 0; 2055 } 2056 } 2057 2058 if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { 2059 if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, 2060 &value, GL_TRUE) != Success 2061 || !value) { 2062 return 0; /* error! */ 2063 } 2064 } 2065 else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { 2066 if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, 2067 &value, GL_TRUE) != Success 2068 || !value) { 2069 return 0; /* error! */ 2070 } 2071 } 2072 if (mipmap) { 2073 if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, 2074 &value, GL_TRUE) != Success 2075 || !value) { 2076 return 0; /* error! */ 2077 } 2078 } 2079 if (target == GLX_TEXTURE_1D_EXT) { 2080 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2081 &value, GL_TRUE) != Success 2082 || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { 2083 return 0; /* error! */ 2084 } 2085 } 2086 else if (target == GLX_TEXTURE_2D_EXT) { 2087 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2088 &value, GL_TRUE) != Success 2089 || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { 2090 return 0; /* error! */ 2091 } 2092 } 2093 if (target == GLX_TEXTURE_RECTANGLE_EXT) { 2094 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2095 &value, GL_TRUE) != Success 2096 || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { 2097 return 0; /* error! */ 2098 } 2099 } 2100 2101 if (format || target || mipmap) { 2102 /* texture from pixmap */ 2103 b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); 2104 } 2105 else { 2106 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 2107 } 2108 if (!b) { 2109 return 0; 2110 } 2111 2112 return pixmap; 2113 } 2114 2115 2116 static void 2117 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) 2118 { 2119 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); 2120 if (b) 2121 XMesaDestroyBuffer(b); 2122 /* don't destroy X pixmap */ 2123 } 2124 2125 2126 static GLXPbuffer 2127 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, 2128 const int *attribList ) 2129 { 2130 XMesaVisual xmvis = (XMesaVisual) config; 2131 XMesaBuffer xmbuf; 2132 const int *attrib; 2133 int width = 0, height = 0; 2134 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2135 2136 (void) dpy; 2137 2138 for (attrib = attribList; *attrib; attrib++) { 2139 switch (*attrib) { 2140 case GLX_PBUFFER_WIDTH: 2141 attrib++; 2142 width = *attrib; 2143 break; 2144 case GLX_PBUFFER_HEIGHT: 2145 attrib++; 2146 height = *attrib; 2147 break; 2148 case GLX_PRESERVED_CONTENTS: 2149 attrib++; 2150 preserveContents = *attrib; 2151 break; 2152 case GLX_LARGEST_PBUFFER: 2153 attrib++; 2154 useLargest = *attrib; 2155 break; 2156 default: 2157 return 0; 2158 } 2159 } 2160 2161 if (width == 0 || height == 0) 2162 return 0; 2163 2164 if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) { 2165 /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, 2166 * allocate the largest possible buffer. 2167 */ 2168 if (useLargest) { 2169 width = SWRAST_MAX_WIDTH; 2170 height = SWRAST_MAX_HEIGHT; 2171 } 2172 } 2173 2174 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2175 /* A GLXPbuffer handle must be an X Drawable because that's what 2176 * glXMakeCurrent takes. 2177 */ 2178 if (xmbuf) { 2179 xmbuf->largestPbuffer = useLargest; 2180 xmbuf->preservedContents = preserveContents; 2181 return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2182 } 2183 else { 2184 return 0; 2185 } 2186 } 2187 2188 2189 static void 2190 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) 2191 { 2192 XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); 2193 if (b) { 2194 XMesaDestroyBuffer(b); 2195 } 2196 } 2197 2198 2199 static void 2200 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, 2201 unsigned int *value ) 2202 { 2203 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); 2204 if (!xmbuf) 2205 return; 2206 2207 /* make sure buffer's dimensions are up to date */ 2208 xmesa_check_and_update_buffer_size(NULL, xmbuf); 2209 2210 switch (attribute) { 2211 case GLX_WIDTH: 2212 *value = xmbuf->mesa_buffer.Width; 2213 break; 2214 case GLX_HEIGHT: 2215 *value = xmbuf->mesa_buffer.Height; 2216 break; 2217 case GLX_PRESERVED_CONTENTS: 2218 *value = xmbuf->preservedContents; 2219 break; 2220 case GLX_LARGEST_PBUFFER: 2221 *value = xmbuf->largestPbuffer; 2222 break; 2223 case GLX_FBCONFIG_ID: 2224 *value = xmbuf->xm_visual->visinfo->visualid; 2225 return; 2226 case GLX_TEXTURE_FORMAT_EXT: 2227 *value = xmbuf->TextureFormat; 2228 break; 2229 case GLX_TEXTURE_TARGET_EXT: 2230 *value = xmbuf->TextureTarget; 2231 break; 2232 case GLX_MIPMAP_TEXTURE_EXT: 2233 *value = xmbuf->TextureMipmap; 2234 break; 2235 2236 default: 2237 return; /* raise BadValue error */ 2238 } 2239 } 2240 2241 2242 static GLXContext 2243 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, 2244 int renderType, GLXContext shareList, Bool direct ) 2245 { 2246 XMesaContext xmCtx; 2247 XMesaVisual xmvis = (XMesaVisual) config; 2248 2249 if (!dpy || !config || 2250 (renderType != GLX_RGBA_TYPE && 2251 renderType != GLX_COLOR_INDEX_TYPE && 2252 renderType != GLX_RGBA_FLOAT_TYPE_ARB && 2253 renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT)) 2254 return 0; 2255 2256 /* deallocate unused windows/buffers */ 2257 XMesaGarbageCollect(dpy); 2258 2259 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList); 2260 2261 return (GLXContext) xmCtx; 2262 } 2263 2264 2265 static int 2266 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) 2267 { 2268 XMesaContext xmctx = (XMesaContext) ctx; 2269 (void) dpy; 2270 (void) ctx; 2271 2272 switch (attribute) { 2273 case GLX_FBCONFIG_ID: 2274 *value = xmctx->xm_visual->visinfo->visualid; 2275 break; 2276 case GLX_RENDER_TYPE: 2277 *value = GLX_RGBA_TYPE; 2278 break; 2279 case GLX_SCREEN: 2280 *value = 0; 2281 return Success; 2282 default: 2283 return GLX_BAD_ATTRIBUTE; 2284 } 2285 return 0; 2286 } 2287 2288 2289 static void 2290 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) 2291 { 2292 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2293 if (xmbuf) 2294 xmbuf->selectedEvents = mask; 2295 } 2296 2297 2298 static void 2299 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, 2300 unsigned long *mask ) 2301 { 2302 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2303 if (xmbuf) 2304 *mask = xmbuf->selectedEvents; 2305 else 2306 *mask = 0; 2307 } 2308 2309 2310 2311 /*** GLX_SGI_swap_control ***/ 2312 2313 static int 2314 Fake_glXSwapIntervalSGI(int interval) 2315 { 2316 (void) interval; 2317 return 0; 2318 } 2319 2320 2321 2322 /*** GLX_SGI_video_sync ***/ 2323 2324 static unsigned int FrameCounter = 0; 2325 2326 static int 2327 Fake_glXGetVideoSyncSGI(unsigned int *count) 2328 { 2329 /* this is a bogus implementation */ 2330 *count = FrameCounter++; 2331 return 0; 2332 } 2333 2334 static int 2335 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 2336 { 2337 if (divisor <= 0 || remainder < 0) 2338 return GLX_BAD_VALUE; 2339 /* this is a bogus implementation */ 2340 FrameCounter++; 2341 while (FrameCounter % divisor != remainder) 2342 FrameCounter++; 2343 *count = FrameCounter; 2344 return 0; 2345 } 2346 2347 2348 2349 /*** GLX_SGI_make_current_read ***/ 2350 2351 static Bool 2352 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) 2353 { 2354 return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); 2355 } 2356 2357 /* not used 2358 static GLXDrawable 2359 Fake_glXGetCurrentReadDrawableSGI(void) 2360 { 2361 return 0; 2362 } 2363 */ 2364 2365 2366 /*** GLX_SGIX_video_source ***/ 2367 #if defined(_VL_H) 2368 2369 static GLXVideoSourceSGIX 2370 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) 2371 { 2372 (void) dpy; 2373 (void) screen; 2374 (void) server; 2375 (void) path; 2376 (void) nodeClass; 2377 (void) drainNode; 2378 return 0; 2379 } 2380 2381 static void 2382 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) 2383 { 2384 (void) dpy; 2385 (void) src; 2386 } 2387 2388 #endif 2389 2390 2391 /*** GLX_EXT_import_context ***/ 2392 2393 static void 2394 Fake_glXFreeContextEXT(Display *dpy, GLXContext context) 2395 { 2396 (void) dpy; 2397 (void) context; 2398 } 2399 2400 static GLXContextID 2401 Fake_glXGetContextIDEXT(const GLXContext context) 2402 { 2403 (void) context; 2404 return 0; 2405 } 2406 2407 static GLXContext 2408 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) 2409 { 2410 (void) dpy; 2411 (void) contextID; 2412 return 0; 2413 } 2414 2415 static int 2416 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) 2417 { 2418 (void) dpy; 2419 (void) context; 2420 (void) attribute; 2421 (void) value; 2422 return 0; 2423 } 2424 2425 2426 2427 /*** GLX_SGIX_fbconfig ***/ 2428 2429 static int 2430 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) 2431 { 2432 return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); 2433 } 2434 2435 static GLXFBConfigSGIX * 2436 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) 2437 { 2438 return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); 2439 } 2440 2441 2442 static GLXPixmap 2443 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) 2444 { 2445 XMesaVisual xmvis = (XMesaVisual) config; 2446 XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); 2447 return xmbuf->frontxrb->pixmap; /* need to return an X ID */ 2448 } 2449 2450 2451 static GLXContext 2452 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) 2453 { 2454 XMesaContext xmCtx; 2455 XMesaVisual xmvis = (XMesaVisual) config; 2456 2457 /* deallocate unused windows/buffers */ 2458 XMesaGarbageCollect(dpy); 2459 2460 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 2461 2462 return (GLXContext) xmCtx; 2463 } 2464 2465 2466 static XVisualInfo * 2467 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) 2468 { 2469 return Fake_glXGetVisualFromFBConfig(dpy, config); 2470 } 2471 2472 2473 static GLXFBConfigSGIX 2474 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) 2475 { 2476 XMesaVisual xmvis = find_glx_visual(dpy, vis); 2477 if (!xmvis) { 2478 /* This visual wasn't found with glXChooseVisual() */ 2479 xmvis = create_glx_visual(dpy, vis); 2480 } 2481 2482 return (GLXFBConfigSGIX) xmvis; 2483 } 2484 2485 2486 2487 /*** GLX_SGIX_pbuffer ***/ 2488 2489 static GLXPbufferSGIX 2490 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, 2491 unsigned int width, unsigned int height, 2492 int *attribList) 2493 { 2494 XMesaVisual xmvis = (XMesaVisual) config; 2495 XMesaBuffer xmbuf; 2496 const int *attrib; 2497 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2498 2499 (void) dpy; 2500 2501 for (attrib = attribList; attrib && *attrib; attrib++) { 2502 switch (*attrib) { 2503 case GLX_PRESERVED_CONTENTS_SGIX: 2504 attrib++; 2505 preserveContents = *attrib; /* ignored */ 2506 break; 2507 case GLX_LARGEST_PBUFFER_SGIX: 2508 attrib++; 2509 useLargest = *attrib; /* ignored */ 2510 break; 2511 default: 2512 return 0; 2513 } 2514 } 2515 2516 /* not used at this time */ 2517 (void) useLargest; 2518 (void) preserveContents; 2519 2520 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2521 /* A GLXPbuffer handle must be an X Drawable because that's what 2522 * glXMakeCurrent takes. 2523 */ 2524 return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2525 } 2526 2527 2528 static void 2529 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) 2530 { 2531 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2532 if (xmbuf) { 2533 XMesaDestroyBuffer(xmbuf); 2534 } 2535 } 2536 2537 2538 static int 2539 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) 2540 { 2541 const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2542 2543 if (!xmbuf) { 2544 /* Generate GLXBadPbufferSGIX for bad pbuffer */ 2545 return 0; 2546 } 2547 2548 switch (attribute) { 2549 case GLX_PRESERVED_CONTENTS_SGIX: 2550 *value = xmbuf->preservedContents; 2551 break; 2552 case GLX_LARGEST_PBUFFER_SGIX: 2553 *value = xmbuf->largestPbuffer; 2554 break; 2555 case GLX_WIDTH_SGIX: 2556 *value = xmbuf->mesa_buffer.Width; 2557 break; 2558 case GLX_HEIGHT_SGIX: 2559 *value = xmbuf->mesa_buffer.Height; 2560 break; 2561 case GLX_EVENT_MASK_SGIX: 2562 *value = 0; /* XXX might be wrong */ 2563 break; 2564 default: 2565 *value = 0; 2566 } 2567 return 0; 2568 } 2569 2570 2571 static void 2572 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) 2573 { 2574 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2575 if (xmbuf) { 2576 /* Note: we'll never generate clobber events */ 2577 xmbuf->selectedEvents = mask; 2578 } 2579 } 2580 2581 2582 static void 2583 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) 2584 { 2585 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2586 if (xmbuf) { 2587 *mask = xmbuf->selectedEvents; 2588 } 2589 else { 2590 *mask = 0; 2591 } 2592 } 2593 2594 2595 2596 /*** GLX_SGI_cushion ***/ 2597 2598 static void 2599 Fake_glXCushionSGI(Display *dpy, Window win, float cushion) 2600 { 2601 (void) dpy; 2602 (void) win; 2603 (void) cushion; 2604 } 2605 2606 2607 2608 /*** GLX_SGIX_video_resize ***/ 2609 2610 static int 2611 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) 2612 { 2613 (void) dpy; 2614 (void) screen; 2615 (void) channel; 2616 (void) window; 2617 return 0; 2618 } 2619 2620 static int 2621 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) 2622 { 2623 (void) dpy; 2624 (void) screen; 2625 (void) channel; 2626 (void) x; 2627 (void) y; 2628 (void) w; 2629 (void) h; 2630 return 0; 2631 } 2632 2633 static int 2634 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) 2635 { 2636 (void) dpy; 2637 (void) screen; 2638 (void) channel; 2639 (void) x; 2640 (void) y; 2641 (void) w; 2642 (void) h; 2643 return 0; 2644 } 2645 2646 static int 2647 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) 2648 { 2649 (void) dpy; 2650 (void) screen; 2651 (void) channel; 2652 (void) dx; 2653 (void) dy; 2654 (void) dw; 2655 (void) dh; 2656 return 0; 2657 } 2658 2659 static int 2660 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) 2661 { 2662 (void) dpy; 2663 (void) screen; 2664 (void) channel; 2665 (void) synctype; 2666 return 0; 2667 } 2668 2669 2670 2671 /*** GLX_SGIX_dmbuffer **/ 2672 2673 #if defined(_DM_BUFFER_H_) 2674 static Bool 2675 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) 2676 { 2677 (void) dpy; 2678 (void) pbuffer; 2679 (void) params; 2680 (void) dmbuffer; 2681 return False; 2682 } 2683 #endif 2684 2685 2686 /*** GLX_SGIX_swap_group ***/ 2687 2688 static void 2689 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) 2690 { 2691 (void) dpy; 2692 (void) drawable; 2693 (void) member; 2694 } 2695 2696 2697 2698 /*** GLX_SGIX_swap_barrier ***/ 2699 2700 static void 2701 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) 2702 { 2703 (void) dpy; 2704 (void) drawable; 2705 (void) barrier; 2706 } 2707 2708 static Bool 2709 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) 2710 { 2711 (void) dpy; 2712 (void) screen; 2713 (void) max; 2714 return False; 2715 } 2716 2717 2718 2719 /*** GLX_SUN_get_transparent_index ***/ 2720 2721 static Status 2722 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) 2723 { 2724 (void) dpy; 2725 (void) overlay; 2726 (void) underlay; 2727 (void) pTransparent; 2728 return 0; 2729 } 2730 2731 2732 2733 /*** GLX_MESA_release_buffers ***/ 2734 2735 /* 2736 * Release the depth, stencil, accum buffers attached to a GLXDrawable 2737 * (a window or pixmap) prior to destroying the GLXDrawable. 2738 */ 2739 static Bool 2740 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) 2741 { 2742 XMesaBuffer b = XMesaFindBuffer(dpy, d); 2743 if (b) { 2744 XMesaDestroyBuffer(b); 2745 return True; 2746 } 2747 return False; 2748 } 2749 2750 2751 2752 /*** GLX_MESA_agp_offset ***/ 2753 2754 static GLuint 2755 Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) 2756 { 2757 (void) pointer; 2758 return ~0; 2759 } 2760 2761 2762 /*** GLX_EXT_texture_from_pixmap ***/ 2763 2764 static void 2765 Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, 2766 const int *attrib_list) 2767 { 2768 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2769 if (b) 2770 XMesaBindTexImage(dpy, b, buffer, attrib_list); 2771 } 2772 2773 static void 2774 Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) 2775 { 2776 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2777 if (b) 2778 XMesaReleaseTexImage(dpy, b, buffer); 2779 } 2780 2781 2782 static GLXContext 2783 Fake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config, 2784 GLXContext share_context, Bool direct, 2785 const int *attrib_list) 2786 { 2787 XMesaContext xmCtx; 2788 XMesaVisual xmvis = (XMesaVisual) config; 2789 int i; 2790 int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0; 2791 2792 for (i = 0; attrib_list[i]; i += 2) { 2793 switch (attrib_list[i]) { 2794 case GLX_CONTEXT_MAJOR_VERSION_ARB: 2795 major = attrib_list[i + 1]; 2796 break; 2797 case GLX_CONTEXT_MINOR_VERSION_ARB: 2798 minor = attrib_list[i + 1]; 2799 break; 2800 case GLX_CONTEXT_FLAGS_ARB: 2801 ctxFlags = attrib_list[i + 1]; 2802 break; 2803 case GLX_CONTEXT_PROFILE_MASK_ARB: 2804 profileFlags = attrib_list[i + 1]; 2805 break; 2806 default: 2807 _mesa_warning(NULL, "Unexpected attribute 0x%x in " 2808 "glXCreateContextAttribs()\n", attrib_list[i]); 2809 return 0; 2810 } 2811 } 2812 2813 if (major * 10 + minor > 21) { 2814 /* swrast only supports GL 2.1 and earlier */ 2815 return 0; 2816 } 2817 2818 /* These are ignored for now. We'd have to enhance XMesaCreateContext 2819 * to take these flags and the version, at least. 2820 */ 2821 (void) ctxFlags; 2822 (void) profileFlags; 2823 2824 /* deallocate unused windows/buffers */ 2825 XMesaGarbageCollect(dpy); 2826 2827 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context); 2828 2829 return (GLXContext) xmCtx; 2830 } 2831 2832 2833 /* silence warning */ 2834 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); 2835 2836 2837 /** 2838 * Create a new GLX API dispatch table with its function pointers 2839 * initialized to point to Mesa's "fake" GLX API functions. 2840 * Note: there's a similar function (_real_GetGLXDispatchTable) that 2841 * returns a new dispatch table with all pointers initalized to point 2842 * to "real" GLX functions (which understand GLX wire protocol, etc). 2843 */ 2844 struct _glxapi_table * 2845 _mesa_GetGLXDispatchTable(void) 2846 { 2847 static struct _glxapi_table glx; 2848 2849 /* be sure our dispatch table size <= libGL's table */ 2850 { 2851 GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); 2852 (void) size; 2853 assert(_glxapi_get_dispatch_table_size() >= size); 2854 } 2855 2856 /* initialize the whole table to no-ops */ 2857 _glxapi_set_no_op_table(&glx); 2858 2859 /* now initialize the table with the functions I implement */ 2860 glx.ChooseVisual = Fake_glXChooseVisual; 2861 glx.CopyContext = Fake_glXCopyContext; 2862 glx.CreateContext = Fake_glXCreateContext; 2863 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; 2864 glx.DestroyContext = Fake_glXDestroyContext; 2865 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; 2866 glx.GetConfig = Fake_glXGetConfig; 2867 glx.GetCurrentContext = Fake_glXGetCurrentContext; 2868 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ 2869 glx.IsDirect = Fake_glXIsDirect; 2870 glx.MakeCurrent = Fake_glXMakeCurrent; 2871 glx.QueryExtension = Fake_glXQueryExtension; 2872 glx.QueryVersion = Fake_glXQueryVersion; 2873 glx.SwapBuffers = Fake_glXSwapBuffers; 2874 glx.UseXFont = Fake_glXUseXFont; 2875 glx.WaitGL = Fake_glXWaitGL; 2876 glx.WaitX = Fake_glXWaitX; 2877 2878 /*** GLX_VERSION_1_1 ***/ 2879 glx.GetClientString = Fake_glXGetClientString; 2880 glx.QueryExtensionsString = Fake_glXQueryExtensionsString; 2881 glx.QueryServerString = Fake_glXQueryServerString; 2882 2883 /*** GLX_VERSION_1_2 ***/ 2884 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ 2885 2886 /*** GLX_VERSION_1_3 ***/ 2887 glx.ChooseFBConfig = Fake_glXChooseFBConfig; 2888 glx.CreateNewContext = Fake_glXCreateNewContext; 2889 glx.CreatePbuffer = Fake_glXCreatePbuffer; 2890 glx.CreatePixmap = Fake_glXCreatePixmap; 2891 glx.CreateWindow = Fake_glXCreateWindow; 2892 glx.DestroyPbuffer = Fake_glXDestroyPbuffer; 2893 glx.DestroyPixmap = Fake_glXDestroyPixmap; 2894 glx.DestroyWindow = Fake_glXDestroyWindow; 2895 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ 2896 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; 2897 glx.GetFBConfigs = Fake_glXGetFBConfigs; 2898 glx.GetSelectedEvent = Fake_glXGetSelectedEvent; 2899 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; 2900 glx.MakeContextCurrent = Fake_glXMakeContextCurrent; 2901 glx.QueryContext = Fake_glXQueryContext; 2902 glx.QueryDrawable = Fake_glXQueryDrawable; 2903 glx.SelectEvent = Fake_glXSelectEvent; 2904 2905 /*** GLX_SGI_swap_control ***/ 2906 glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; 2907 2908 /*** GLX_SGI_video_sync ***/ 2909 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; 2910 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; 2911 2912 /*** GLX_SGI_make_current_read ***/ 2913 glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; 2914 /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ 2915 2916 /*** GLX_SGIX_video_source ***/ 2917 #if defined(_VL_H) 2918 glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; 2919 glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; 2920 #endif 2921 2922 /*** GLX_EXT_import_context ***/ 2923 glx.FreeContextEXT = Fake_glXFreeContextEXT; 2924 glx.GetContextIDEXT = Fake_glXGetContextIDEXT; 2925 /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ 2926 glx.ImportContextEXT = Fake_glXImportContextEXT; 2927 glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; 2928 2929 /*** GLX_SGIX_fbconfig ***/ 2930 glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; 2931 glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; 2932 glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; 2933 glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; 2934 glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; 2935 glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; 2936 2937 /*** GLX_SGIX_pbuffer ***/ 2938 glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; 2939 glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; 2940 glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; 2941 glx.SelectEventSGIX = Fake_glXSelectEventSGIX; 2942 glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; 2943 2944 /*** GLX_SGI_cushion ***/ 2945 glx.CushionSGI = Fake_glXCushionSGI; 2946 2947 /*** GLX_SGIX_video_resize ***/ 2948 glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; 2949 glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; 2950 glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; 2951 glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; 2952 glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; 2953 2954 /*** GLX_SGIX_dmbuffer **/ 2955 #if defined(_DM_BUFFER_H_) 2956 glx.AssociateDMPbufferSGIX = NULL; 2957 #endif 2958 2959 /*** GLX_SGIX_swap_group ***/ 2960 glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; 2961 2962 /*** GLX_SGIX_swap_barrier ***/ 2963 glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; 2964 glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; 2965 2966 /*** GLX_SUN_get_transparent_index ***/ 2967 glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; 2968 2969 /*** GLX_MESA_copy_sub_buffer ***/ 2970 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; 2971 2972 /*** GLX_MESA_release_buffers ***/ 2973 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; 2974 2975 /*** GLX_MESA_pixmap_colormap ***/ 2976 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; 2977 2978 /*** GLX_EXT_texture_from_pixmap ***/ 2979 glx.BindTexImageEXT = Fake_glXBindTexImageEXT; 2980 glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; 2981 2982 glx.CreateContextAttribs = Fake_glXCreateContextAttribs; 2983 return &glx; 2984 } 2985