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 #ifdef GLX_EXT_texture_from_pixmap 1106 case GLX_BIND_TO_TEXTURE_RGB_EXT: 1107 parselist++; /*skip*/ 1108 break; 1109 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1110 parselist++; /*skip*/ 1111 break; 1112 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1113 parselist++; /*skip*/ 1114 break; 1115 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1116 parselist++; 1117 if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | 1118 GLX_TEXTURE_2D_BIT_EXT | 1119 GLX_TEXTURE_RECTANGLE_BIT_EXT)) { 1120 /* invalid bit */ 1121 return NULL; 1122 } 1123 break; 1124 case GLX_Y_INVERTED_EXT: 1125 parselist++; /*skip*/ 1126 break; 1127 #endif 1128 1129 case None: 1130 /* end of list */ 1131 break; 1132 1133 default: 1134 /* undefined attribute */ 1135 _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", 1136 *parselist); 1137 return NULL; 1138 } 1139 } 1140 1141 if (!rgb_flag) 1142 return NULL; 1143 1144 (void) caveat; 1145 (void) min_ci; 1146 1147 /* 1148 * Since we're only simulating the GLX extension this function will never 1149 * find any real GL visuals. Instead, all we can do is try to find an RGB 1150 * or CI visual of appropriate depth. Other requested attributes such as 1151 * double buffering, depth buffer, etc. will be associated with the X 1152 * visual and stored in the VisualTable[]. 1153 */ 1154 if (desiredVisualID != -1) { 1155 /* try to get a specific visual, by visualID */ 1156 XVisualInfo temp; 1157 int n; 1158 temp.visualid = desiredVisualID; 1159 temp.screen = screen; 1160 vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); 1161 if (vis) { 1162 /* give the visual some useful GLX attributes */ 1163 double_flag = GL_TRUE; 1164 if (vis->depth <= 8) 1165 return NULL; 1166 depth_size = default_depth_bits(); 1167 stencil_size = 8; 1168 /* XXX accum??? */ 1169 } 1170 } 1171 else { 1172 /* RGB visual */ 1173 int min_rgb = min_red + min_green + min_blue; 1174 if (min_rgb>1 && min_rgb<8) { 1175 /* a special case to be sure we can get a monochrome visual */ 1176 min_rgb = 1; 1177 } 1178 1179 if (level==0) { 1180 vis = choose_x_visual(dpy, screen, min_rgb, visual_type); 1181 } 1182 else { 1183 vis = choose_x_overlay_visual(dpy, screen, level, 1184 trans_type, trans_value, min_rgb, visual_type); 1185 } 1186 } 1187 1188 if (vis) { 1189 /* Note: we're not exactly obeying the glXChooseVisual rules here. 1190 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the 1191 * largest depth buffer size, which is 32bits/value. Instead, we 1192 * return 16 to maintain performance with earlier versions of Mesa. 1193 */ 1194 if (depth_size > 24) 1195 depth_size = 32; 1196 else if (depth_size > 16) 1197 depth_size = 24; 1198 else if (depth_size > 0) { 1199 depth_size = default_depth_bits(); 1200 } 1201 1202 if (!alpha_flag) { 1203 alpha_flag = default_alpha_bits() > 0; 1204 } 1205 1206 /* we only support one size of stencil and accum buffers. */ 1207 if (stencil_size > 0) 1208 stencil_size = 8; 1209 if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || 1210 accumAlphaSize > 0) { 1211 accumRedSize = 1212 accumGreenSize = 1213 accumBlueSize = default_accum_bits(); 1214 accumAlphaSize = alpha_flag ? accumRedSize : 0; 1215 } 1216 1217 xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag, 1218 stereo_flag, depth_size, stencil_size, 1219 accumRedSize, accumGreenSize, 1220 accumBlueSize, accumAlphaSize, level, numAux ); 1221 free(vis); 1222 } 1223 1224 return xmvis; 1225 } 1226 1227 1228 static XVisualInfo * 1229 Fake_glXChooseVisual( Display *dpy, int screen, int *list ) 1230 { 1231 XMesaVisual xmvis; 1232 1233 /* register ourselves as an extension on this display */ 1234 register_with_display(dpy); 1235 1236 xmvis = choose_visual(dpy, screen, list, GL_FALSE); 1237 if (xmvis) { 1238 XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1239 if (visinfo) { 1240 memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1241 } 1242 return visinfo; 1243 } 1244 else 1245 return NULL; 1246 } 1247 1248 1249 static GLXContext 1250 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, 1251 GLXContext share_list, Bool direct ) 1252 { 1253 XMesaVisual xmvis; 1254 XMesaContext xmesaCtx; 1255 1256 if (!dpy || !visinfo) 1257 return 0; 1258 1259 /* deallocate unused windows/buffers */ 1260 #if 0 1261 XMesaGarbageCollect(dpy); 1262 #endif 1263 1264 xmvis = find_glx_visual( dpy, visinfo ); 1265 if (!xmvis) { 1266 /* This visual wasn't found with glXChooseVisual() */ 1267 xmvis = create_glx_visual( dpy, visinfo ); 1268 if (!xmvis) { 1269 return NULL; 1270 } 1271 } 1272 1273 xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 1274 1275 return (GLXContext) xmesaCtx; 1276 } 1277 1278 1279 /* XXX these may have to be removed due to thread-safety issues. */ 1280 static GLXContext MakeCurrent_PrevContext = 0; 1281 static GLXDrawable MakeCurrent_PrevDrawable = 0; 1282 static GLXDrawable MakeCurrent_PrevReadable = 0; 1283 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; 1284 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; 1285 1286 1287 /* GLX 1.3 and later */ 1288 static Bool 1289 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, 1290 GLXDrawable read, GLXContext ctx ) 1291 { 1292 if (ctx && draw && read) { 1293 XMesaBuffer drawBuffer, readBuffer; 1294 XMesaContext xmctx = (XMesaContext) ctx; 1295 1296 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ 1297 if (ctx == MakeCurrent_PrevContext 1298 && draw == MakeCurrent_PrevDrawable) { 1299 drawBuffer = MakeCurrent_PrevDrawBuffer; 1300 } 1301 else { 1302 drawBuffer = XMesaFindBuffer( dpy, draw ); 1303 } 1304 if (!drawBuffer) { 1305 /* drawable must be a new window! */ 1306 drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); 1307 if (!drawBuffer) { 1308 /* Out of memory, or context/drawable depth mismatch */ 1309 return False; 1310 } 1311 } 1312 1313 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ 1314 if (ctx == MakeCurrent_PrevContext 1315 && read == MakeCurrent_PrevReadable) { 1316 readBuffer = MakeCurrent_PrevReadBuffer; 1317 } 1318 else { 1319 readBuffer = XMesaFindBuffer( dpy, read ); 1320 } 1321 if (!readBuffer) { 1322 /* drawable must be a new window! */ 1323 readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); 1324 if (!readBuffer) { 1325 /* Out of memory, or context/drawable depth mismatch */ 1326 return False; 1327 } 1328 } 1329 1330 MakeCurrent_PrevContext = ctx; 1331 MakeCurrent_PrevDrawable = draw; 1332 MakeCurrent_PrevReadable = read; 1333 MakeCurrent_PrevDrawBuffer = drawBuffer; 1334 MakeCurrent_PrevReadBuffer = readBuffer; 1335 1336 /* Now make current! */ 1337 return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer); 1338 } 1339 else if (!ctx && !draw && !read) { 1340 /* release current context w/out assigning new one. */ 1341 XMesaMakeCurrent( NULL, NULL ); 1342 MakeCurrent_PrevContext = 0; 1343 MakeCurrent_PrevDrawable = 0; 1344 MakeCurrent_PrevReadable = 0; 1345 MakeCurrent_PrevDrawBuffer = 0; 1346 MakeCurrent_PrevReadBuffer = 0; 1347 return True; 1348 } 1349 else { 1350 /* The args must either all be non-zero or all zero. 1351 * This is an error. 1352 */ 1353 return False; 1354 } 1355 } 1356 1357 1358 static Bool 1359 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) 1360 { 1361 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); 1362 } 1363 1364 1365 static GLXPixmap 1366 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) 1367 { 1368 XMesaVisual v; 1369 XMesaBuffer b; 1370 1371 v = find_glx_visual( dpy, visinfo ); 1372 if (!v) { 1373 v = create_glx_visual( dpy, visinfo ); 1374 if (!v) { 1375 /* unusable visual */ 1376 return 0; 1377 } 1378 } 1379 1380 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 1381 if (!b) { 1382 return 0; 1383 } 1384 return b->frontxrb->pixmap; 1385 } 1386 1387 1388 /*** GLX_MESA_pixmap_colormap ***/ 1389 1390 static GLXPixmap 1391 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, 1392 Pixmap pixmap, Colormap cmap ) 1393 { 1394 XMesaVisual v; 1395 XMesaBuffer b; 1396 1397 v = find_glx_visual( dpy, visinfo ); 1398 if (!v) { 1399 v = create_glx_visual( dpy, visinfo ); 1400 if (!v) { 1401 /* unusable visual */ 1402 return 0; 1403 } 1404 } 1405 1406 b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); 1407 if (!b) { 1408 return 0; 1409 } 1410 return b->frontxrb->pixmap; 1411 } 1412 1413 1414 static void 1415 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) 1416 { 1417 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); 1418 if (b) { 1419 XMesaDestroyBuffer(b); 1420 } 1421 else if (getenv("MESA_DEBUG")) { 1422 _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); 1423 } 1424 } 1425 1426 1427 static void 1428 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, 1429 unsigned long mask ) 1430 { 1431 XMesaContext xmSrc = (XMesaContext) src; 1432 XMesaContext xmDst = (XMesaContext) dst; 1433 (void) dpy; 1434 if (MakeCurrent_PrevContext == src) { 1435 _mesa_Flush(); 1436 } 1437 _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask ); 1438 } 1439 1440 1441 static Bool 1442 Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) 1443 { 1444 int op, ev, err; 1445 /* Mesa's GLX isn't really an X extension but we try to act like one. */ 1446 if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err)) 1447 ev = err = 0; 1448 if (errorBase) 1449 *errorBase = err; 1450 if (eventBase) 1451 *eventBase = ev; 1452 return True; /* we're faking GLX so always return success */ 1453 } 1454 1455 1456 extern void _kw_ungrab_all( Display *dpy ); 1457 void _kw_ungrab_all( Display *dpy ) 1458 { 1459 XUngrabPointer( dpy, CurrentTime ); 1460 XUngrabKeyboard( dpy, CurrentTime ); 1461 } 1462 1463 1464 static void 1465 Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) 1466 { 1467 if (ctx) { 1468 (void) dpy; 1469 MakeCurrent_PrevContext = 0; 1470 MakeCurrent_PrevDrawable = 0; 1471 MakeCurrent_PrevReadable = 0; 1472 MakeCurrent_PrevDrawBuffer = 0; 1473 MakeCurrent_PrevReadBuffer = 0; 1474 XMesaDestroyContext((XMesaContext) ctx); 1475 XMesaGarbageCollect(dpy); 1476 } 1477 } 1478 1479 1480 static Bool 1481 Fake_glXIsDirect( Display *dpy, GLXContext ctx ) 1482 { 1483 XMesaContext xmCtx = (XMesaContext) ctx; 1484 return xmCtx ? xmCtx->direct : False; 1485 } 1486 1487 1488 1489 static void 1490 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) 1491 { 1492 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1493 1494 if (buffer) { 1495 XMesaSwapBuffers(buffer); 1496 } 1497 else if (getenv("MESA_DEBUG")) { 1498 _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", 1499 (int) drawable); 1500 } 1501 } 1502 1503 1504 1505 /*** GLX_MESA_copy_sub_buffer ***/ 1506 1507 static void 1508 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, 1509 int x, int y, int width, int height ) 1510 { 1511 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1512 if (buffer) { 1513 XMesaCopySubBuffer(buffer, x, y, width, height); 1514 } 1515 else if (getenv("MESA_DEBUG")) { 1516 _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); 1517 } 1518 } 1519 1520 1521 static Bool 1522 Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) 1523 { 1524 (void) dpy; 1525 /* Return GLX version, not Mesa version */ 1526 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); 1527 *maj = CLIENT_MAJOR_VERSION; 1528 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); 1529 return True; 1530 } 1531 1532 1533 /* 1534 * Query the GLX attributes of the given XVisualInfo. 1535 */ 1536 static int 1537 get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) 1538 { 1539 assert(xmvis); 1540 switch(attrib) { 1541 case GLX_USE_GL: 1542 if (fbconfig) 1543 return GLX_BAD_ATTRIBUTE; 1544 *value = (int) True; 1545 return 0; 1546 case GLX_BUFFER_SIZE: 1547 *value = xmvis->visinfo->depth; 1548 return 0; 1549 case GLX_LEVEL: 1550 *value = xmvis->mesa_visual.level; 1551 return 0; 1552 case GLX_RGBA: 1553 if (fbconfig) 1554 return GLX_BAD_ATTRIBUTE; 1555 if (xmvis->mesa_visual.rgbMode) { 1556 *value = True; 1557 } 1558 else { 1559 *value = False; 1560 } 1561 return 0; 1562 case GLX_DOUBLEBUFFER: 1563 *value = (int) xmvis->mesa_visual.doubleBufferMode; 1564 return 0; 1565 case GLX_STEREO: 1566 *value = (int) xmvis->mesa_visual.stereoMode; 1567 return 0; 1568 case GLX_AUX_BUFFERS: 1569 *value = xmvis->mesa_visual.numAuxBuffers; 1570 return 0; 1571 case GLX_RED_SIZE: 1572 *value = xmvis->mesa_visual.redBits; 1573 return 0; 1574 case GLX_GREEN_SIZE: 1575 *value = xmvis->mesa_visual.greenBits; 1576 return 0; 1577 case GLX_BLUE_SIZE: 1578 *value = xmvis->mesa_visual.blueBits; 1579 return 0; 1580 case GLX_ALPHA_SIZE: 1581 *value = xmvis->mesa_visual.alphaBits; 1582 return 0; 1583 case GLX_DEPTH_SIZE: 1584 *value = xmvis->mesa_visual.depthBits; 1585 return 0; 1586 case GLX_STENCIL_SIZE: 1587 *value = xmvis->mesa_visual.stencilBits; 1588 return 0; 1589 case GLX_ACCUM_RED_SIZE: 1590 *value = xmvis->mesa_visual.accumRedBits; 1591 return 0; 1592 case GLX_ACCUM_GREEN_SIZE: 1593 *value = xmvis->mesa_visual.accumGreenBits; 1594 return 0; 1595 case GLX_ACCUM_BLUE_SIZE: 1596 *value = xmvis->mesa_visual.accumBlueBits; 1597 return 0; 1598 case GLX_ACCUM_ALPHA_SIZE: 1599 *value = xmvis->mesa_visual.accumAlphaBits; 1600 return 0; 1601 1602 /* 1603 * GLX_EXT_visual_info extension 1604 */ 1605 case GLX_X_VISUAL_TYPE_EXT: 1606 switch (xmvis->visinfo->CLASS) { 1607 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; 1608 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; 1609 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; 1610 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; 1611 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; 1612 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; 1613 } 1614 return 0; 1615 case GLX_TRANSPARENT_TYPE_EXT: 1616 if (xmvis->mesa_visual.level==0) { 1617 /* normal planes */ 1618 *value = GLX_NONE_EXT; 1619 } 1620 else if (xmvis->mesa_visual.level>0) { 1621 /* overlay */ 1622 if (xmvis->mesa_visual.rgbMode) { 1623 *value = GLX_TRANSPARENT_RGB_EXT; 1624 } 1625 else { 1626 *value = GLX_TRANSPARENT_INDEX_EXT; 1627 } 1628 } 1629 else if (xmvis->mesa_visual.level<0) { 1630 /* underlay */ 1631 *value = GLX_NONE_EXT; 1632 } 1633 return 0; 1634 case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1635 { 1636 int pixel = transparent_pixel( xmvis ); 1637 if (pixel>=0) { 1638 *value = pixel; 1639 } 1640 /* else undefined */ 1641 } 1642 return 0; 1643 case GLX_TRANSPARENT_RED_VALUE_EXT: 1644 /* undefined */ 1645 return 0; 1646 case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1647 /* undefined */ 1648 return 0; 1649 case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1650 /* undefined */ 1651 return 0; 1652 case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1653 /* undefined */ 1654 return 0; 1655 1656 /* 1657 * GLX_EXT_visual_info extension 1658 */ 1659 case GLX_VISUAL_CAVEAT_EXT: 1660 /* test for zero, just in case */ 1661 if (xmvis->mesa_visual.visualRating > 0) 1662 *value = xmvis->mesa_visual.visualRating; 1663 else 1664 *value = GLX_NONE_EXT; 1665 return 0; 1666 1667 /* 1668 * GLX_ARB_multisample 1669 */ 1670 case GLX_SAMPLE_BUFFERS_ARB: 1671 *value = 0; 1672 return 0; 1673 case GLX_SAMPLES_ARB: 1674 *value = 0; 1675 return 0; 1676 1677 /* 1678 * For FBConfigs: 1679 */ 1680 case GLX_SCREEN_EXT: 1681 if (!fbconfig) 1682 return GLX_BAD_ATTRIBUTE; 1683 *value = xmvis->visinfo->screen; 1684 break; 1685 case GLX_DRAWABLE_TYPE: /*SGIX too */ 1686 if (!fbconfig) 1687 return GLX_BAD_ATTRIBUTE; 1688 *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; 1689 break; 1690 case GLX_RENDER_TYPE_SGIX: 1691 if (!fbconfig) 1692 return GLX_BAD_ATTRIBUTE; 1693 if (xmvis->mesa_visual.floatMode) 1694 *value = GLX_RGBA_FLOAT_BIT_ARB; 1695 else if (xmvis->mesa_visual.rgbMode) 1696 *value = GLX_RGBA_BIT; 1697 else 1698 *value = GLX_COLOR_INDEX_BIT; 1699 break; 1700 case GLX_X_RENDERABLE_SGIX: 1701 if (!fbconfig) 1702 return GLX_BAD_ATTRIBUTE; 1703 *value = True; /* XXX really? */ 1704 break; 1705 case GLX_FBCONFIG_ID_SGIX: 1706 if (!fbconfig) 1707 return GLX_BAD_ATTRIBUTE; 1708 *value = xmvis->visinfo->visualid; 1709 break; 1710 case GLX_MAX_PBUFFER_WIDTH: 1711 if (!fbconfig) 1712 return GLX_BAD_ATTRIBUTE; 1713 /* XXX should be same as ctx->Const.MaxRenderbufferSize */ 1714 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); 1715 break; 1716 case GLX_MAX_PBUFFER_HEIGHT: 1717 if (!fbconfig) 1718 return GLX_BAD_ATTRIBUTE; 1719 *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1720 break; 1721 case GLX_MAX_PBUFFER_PIXELS: 1722 if (!fbconfig) 1723 return GLX_BAD_ATTRIBUTE; 1724 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * 1725 DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1726 break; 1727 case GLX_VISUAL_ID: 1728 if (!fbconfig) 1729 return GLX_BAD_ATTRIBUTE; 1730 *value = xmvis->visinfo->visualid; 1731 break; 1732 1733 #ifdef GLX_EXT_texture_from_pixmap 1734 case GLX_BIND_TO_TEXTURE_RGB_EXT: 1735 *value = True; /*XXX*/ 1736 break; 1737 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1738 /* XXX review */ 1739 *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; 1740 break; 1741 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1742 *value = True; /*XXX*/ 1743 break; 1744 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1745 *value = (GLX_TEXTURE_1D_BIT_EXT | 1746 GLX_TEXTURE_2D_BIT_EXT | 1747 GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ 1748 break; 1749 case GLX_Y_INVERTED_EXT: 1750 *value = True; /*XXX*/ 1751 break; 1752 #endif 1753 1754 default: 1755 return GLX_BAD_ATTRIBUTE; 1756 } 1757 return Success; 1758 } 1759 1760 1761 static int 1762 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, 1763 int attrib, int *value ) 1764 { 1765 XMesaVisual xmvis; 1766 int k; 1767 if (!dpy || !visinfo) 1768 return GLX_BAD_ATTRIBUTE; 1769 1770 xmvis = find_glx_visual( dpy, visinfo ); 1771 if (!xmvis) { 1772 /* this visual wasn't obtained with glXChooseVisual */ 1773 xmvis = create_glx_visual( dpy, visinfo ); 1774 if (!xmvis) { 1775 /* this visual can't be used for GL rendering */ 1776 if (attrib==GLX_USE_GL) { 1777 *value = (int) False; 1778 return 0; 1779 } 1780 else { 1781 return GLX_BAD_VISUAL; 1782 } 1783 } 1784 } 1785 1786 k = get_config(xmvis, attrib, value, GL_FALSE); 1787 return k; 1788 } 1789 1790 1791 static GLXContext 1792 Fake_glXGetCurrentContext(void) 1793 { 1794 XMesaContext xmesa = XMesaGetCurrentContext(); 1795 return (GLXContext) xmesa; 1796 } 1797 1798 static void 1799 Fake_glXWaitGL( void ) 1800 { 1801 XMesaContext xmesa = XMesaGetCurrentContext(); 1802 XMesaFlush( xmesa ); 1803 } 1804 1805 1806 1807 static void 1808 Fake_glXWaitX( void ) 1809 { 1810 XMesaContext xmesa = XMesaGetCurrentContext(); 1811 XMesaFlush( xmesa ); 1812 } 1813 1814 1815 static const char * 1816 get_extensions( void ) 1817 { 1818 return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ 1819 } 1820 1821 1822 1823 /* GLX 1.1 and later */ 1824 static const char * 1825 Fake_glXQueryExtensionsString( Display *dpy, int screen ) 1826 { 1827 (void) dpy; 1828 (void) screen; 1829 return get_extensions(); 1830 } 1831 1832 1833 1834 /* GLX 1.1 and later */ 1835 static const char * 1836 Fake_glXQueryServerString( Display *dpy, int screen, int name ) 1837 { 1838 static char version[1000]; 1839 sprintf(version, "%d.%d %s", 1840 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); 1841 1842 (void) dpy; 1843 (void) screen; 1844 1845 switch (name) { 1846 case GLX_EXTENSIONS: 1847 return get_extensions(); 1848 case GLX_VENDOR: 1849 return VENDOR; 1850 case GLX_VERSION: 1851 return version; 1852 default: 1853 return NULL; 1854 } 1855 } 1856 1857 1858 1859 /* GLX 1.1 and later */ 1860 static const char * 1861 Fake_glXGetClientString( Display *dpy, int name ) 1862 { 1863 static char version[1000]; 1864 sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, 1865 CLIENT_MINOR_VERSION, MESA_GLX_VERSION); 1866 1867 (void) dpy; 1868 1869 switch (name) { 1870 case GLX_EXTENSIONS: 1871 return get_extensions(); 1872 case GLX_VENDOR: 1873 return VENDOR; 1874 case GLX_VERSION: 1875 return version; 1876 default: 1877 return NULL; 1878 } 1879 } 1880 1881 1882 1883 /* 1884 * GLX 1.3 and later 1885 */ 1886 1887 1888 static int 1889 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, 1890 int attribute, int *value ) 1891 { 1892 XMesaVisual v = (XMesaVisual) config; 1893 (void) dpy; 1894 (void) config; 1895 1896 if (!dpy || !config || !value) 1897 return -1; 1898 1899 return get_config(v, attribute, value, GL_TRUE); 1900 } 1901 1902 1903 static GLXFBConfig * 1904 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) 1905 { 1906 XVisualInfo *visuals, visTemplate; 1907 const long visMask = VisualScreenMask; 1908 int i; 1909 1910 /* Get list of all X visuals */ 1911 visTemplate.screen = screen; 1912 visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); 1913 if (*nelements > 0) { 1914 XMesaVisual *results; 1915 results = malloc(*nelements * sizeof(XMesaVisual)); 1916 if (!results) { 1917 *nelements = 0; 1918 return NULL; 1919 } 1920 for (i = 0; i < *nelements; i++) { 1921 results[i] = create_glx_visual(dpy, visuals + i); 1922 } 1923 free(visuals); 1924 return (GLXFBConfig *) results; 1925 } 1926 return NULL; 1927 } 1928 1929 1930 static GLXFBConfig * 1931 Fake_glXChooseFBConfig( Display *dpy, int screen, 1932 const int *attribList, int *nitems ) 1933 { 1934 XMesaVisual xmvis; 1935 1936 /* register ourselves as an extension on this display */ 1937 register_with_display(dpy); 1938 1939 if (!attribList || !attribList[0]) { 1940 /* return list of all configs (per GLX_SGIX_fbconfig spec) */ 1941 return Fake_glXGetFBConfigs(dpy, screen, nitems); 1942 } 1943 1944 xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); 1945 if (xmvis) { 1946 GLXFBConfig *config = malloc(sizeof(XMesaVisual)); 1947 if (!config) { 1948 *nitems = 0; 1949 return NULL; 1950 } 1951 *nitems = 1; 1952 config[0] = (GLXFBConfig) xmvis; 1953 return (GLXFBConfig *) config; 1954 } 1955 else { 1956 *nitems = 0; 1957 return NULL; 1958 } 1959 } 1960 1961 1962 static XVisualInfo * 1963 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) 1964 { 1965 if (dpy && config) { 1966 XMesaVisual xmvis = (XMesaVisual) config; 1967 XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); 1968 if (visinfo) { 1969 memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); 1970 } 1971 return visinfo; 1972 } 1973 else { 1974 return NULL; 1975 } 1976 } 1977 1978 1979 static GLXWindow 1980 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, 1981 const int *attribList ) 1982 { 1983 XMesaVisual xmvis = (XMesaVisual) config; 1984 XMesaBuffer xmbuf; 1985 if (!xmvis) 1986 return 0; 1987 1988 xmbuf = XMesaCreateWindowBuffer(xmvis, win); 1989 if (!xmbuf) 1990 return 0; 1991 1992 (void) dpy; 1993 (void) attribList; /* Ignored in GLX 1.3 */ 1994 1995 return win; /* A hack for now */ 1996 } 1997 1998 1999 static void 2000 Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) 2001 { 2002 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); 2003 if (b) 2004 XMesaDestroyBuffer(b); 2005 /* don't destroy X window */ 2006 } 2007 2008 2009 /* XXX untested */ 2010 static GLXPixmap 2011 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, 2012 const int *attribList ) 2013 { 2014 XMesaVisual v = (XMesaVisual) config; 2015 XMesaBuffer b; 2016 const int *attr; 2017 int target = 0, format = 0, mipmap = 0; 2018 int value; 2019 2020 if (!dpy || !config || !pixmap) 2021 return 0; 2022 2023 for (attr = attribList; attr && *attr; attr++) { 2024 switch (*attr) { 2025 case GLX_TEXTURE_FORMAT_EXT: 2026 attr++; 2027 switch (*attr) { 2028 case GLX_TEXTURE_FORMAT_NONE_EXT: 2029 case GLX_TEXTURE_FORMAT_RGB_EXT: 2030 case GLX_TEXTURE_FORMAT_RGBA_EXT: 2031 format = *attr; 2032 break; 2033 default: 2034 /* error */ 2035 return 0; 2036 } 2037 break; 2038 case GLX_TEXTURE_TARGET_EXT: 2039 attr++; 2040 switch (*attr) { 2041 case GLX_TEXTURE_1D_EXT: 2042 case GLX_TEXTURE_2D_EXT: 2043 case GLX_TEXTURE_RECTANGLE_EXT: 2044 target = *attr; 2045 break; 2046 default: 2047 /* error */ 2048 return 0; 2049 } 2050 break; 2051 case GLX_MIPMAP_TEXTURE_EXT: 2052 attr++; 2053 if (*attr) 2054 mipmap = 1; 2055 break; 2056 default: 2057 /* error */ 2058 return 0; 2059 } 2060 } 2061 2062 if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { 2063 if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, 2064 &value, GL_TRUE) != Success 2065 || !value) { 2066 return 0; /* error! */ 2067 } 2068 } 2069 else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { 2070 if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, 2071 &value, GL_TRUE) != Success 2072 || !value) { 2073 return 0; /* error! */ 2074 } 2075 } 2076 if (mipmap) { 2077 if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, 2078 &value, GL_TRUE) != Success 2079 || !value) { 2080 return 0; /* error! */ 2081 } 2082 } 2083 if (target == GLX_TEXTURE_1D_EXT) { 2084 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2085 &value, GL_TRUE) != Success 2086 || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { 2087 return 0; /* error! */ 2088 } 2089 } 2090 else if (target == GLX_TEXTURE_2D_EXT) { 2091 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2092 &value, GL_TRUE) != Success 2093 || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { 2094 return 0; /* error! */ 2095 } 2096 } 2097 if (target == GLX_TEXTURE_RECTANGLE_EXT) { 2098 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 2099 &value, GL_TRUE) != Success 2100 || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { 2101 return 0; /* error! */ 2102 } 2103 } 2104 2105 if (format || target || mipmap) { 2106 /* texture from pixmap */ 2107 b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); 2108 } 2109 else { 2110 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 2111 } 2112 if (!b) { 2113 return 0; 2114 } 2115 2116 return pixmap; 2117 } 2118 2119 2120 static void 2121 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) 2122 { 2123 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); 2124 if (b) 2125 XMesaDestroyBuffer(b); 2126 /* don't destroy X pixmap */ 2127 } 2128 2129 2130 static GLXPbuffer 2131 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, 2132 const int *attribList ) 2133 { 2134 XMesaVisual xmvis = (XMesaVisual) config; 2135 XMesaBuffer xmbuf; 2136 const int *attrib; 2137 int width = 0, height = 0; 2138 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2139 2140 (void) dpy; 2141 2142 for (attrib = attribList; *attrib; attrib++) { 2143 switch (*attrib) { 2144 case GLX_PBUFFER_WIDTH: 2145 attrib++; 2146 width = *attrib; 2147 break; 2148 case GLX_PBUFFER_HEIGHT: 2149 attrib++; 2150 height = *attrib; 2151 break; 2152 case GLX_PRESERVED_CONTENTS: 2153 attrib++; 2154 preserveContents = *attrib; 2155 break; 2156 case GLX_LARGEST_PBUFFER: 2157 attrib++; 2158 useLargest = *attrib; 2159 break; 2160 default: 2161 return 0; 2162 } 2163 } 2164 2165 if (width == 0 || height == 0) 2166 return 0; 2167 2168 if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) { 2169 /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, 2170 * allocate the largest possible buffer. 2171 */ 2172 if (useLargest) { 2173 width = SWRAST_MAX_WIDTH; 2174 height = SWRAST_MAX_HEIGHT; 2175 } 2176 } 2177 2178 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2179 /* A GLXPbuffer handle must be an X Drawable because that's what 2180 * glXMakeCurrent takes. 2181 */ 2182 if (xmbuf) { 2183 xmbuf->largestPbuffer = useLargest; 2184 xmbuf->preservedContents = preserveContents; 2185 return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2186 } 2187 else { 2188 return 0; 2189 } 2190 } 2191 2192 2193 static void 2194 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) 2195 { 2196 XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); 2197 if (b) { 2198 XMesaDestroyBuffer(b); 2199 } 2200 } 2201 2202 2203 static void 2204 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, 2205 unsigned int *value ) 2206 { 2207 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); 2208 if (!xmbuf) 2209 return; 2210 2211 /* make sure buffer's dimensions are up to date */ 2212 xmesa_check_and_update_buffer_size(NULL, xmbuf); 2213 2214 switch (attribute) { 2215 case GLX_WIDTH: 2216 *value = xmbuf->mesa_buffer.Width; 2217 break; 2218 case GLX_HEIGHT: 2219 *value = xmbuf->mesa_buffer.Height; 2220 break; 2221 case GLX_PRESERVED_CONTENTS: 2222 *value = xmbuf->preservedContents; 2223 break; 2224 case GLX_LARGEST_PBUFFER: 2225 *value = xmbuf->largestPbuffer; 2226 break; 2227 case GLX_FBCONFIG_ID: 2228 *value = xmbuf->xm_visual->visinfo->visualid; 2229 return; 2230 #ifdef GLX_EXT_texture_from_pixmap 2231 case GLX_TEXTURE_FORMAT_EXT: 2232 *value = xmbuf->TextureFormat; 2233 break; 2234 case GLX_TEXTURE_TARGET_EXT: 2235 *value = xmbuf->TextureTarget; 2236 break; 2237 case GLX_MIPMAP_TEXTURE_EXT: 2238 *value = xmbuf->TextureMipmap; 2239 break; 2240 #endif 2241 2242 default: 2243 return; /* raise BadValue error */ 2244 } 2245 } 2246 2247 2248 static GLXContext 2249 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, 2250 int renderType, GLXContext shareList, Bool direct ) 2251 { 2252 XMesaContext xmCtx; 2253 XMesaVisual xmvis = (XMesaVisual) config; 2254 2255 if (!dpy || !config || 2256 (renderType != GLX_RGBA_TYPE && 2257 renderType != GLX_COLOR_INDEX_TYPE && 2258 renderType != GLX_RGBA_FLOAT_TYPE_ARB && 2259 renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT)) 2260 return 0; 2261 2262 /* deallocate unused windows/buffers */ 2263 XMesaGarbageCollect(dpy); 2264 2265 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList); 2266 2267 return (GLXContext) xmCtx; 2268 } 2269 2270 2271 static int 2272 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) 2273 { 2274 XMesaContext xmctx = (XMesaContext) ctx; 2275 (void) dpy; 2276 (void) ctx; 2277 2278 switch (attribute) { 2279 case GLX_FBCONFIG_ID: 2280 *value = xmctx->xm_visual->visinfo->visualid; 2281 break; 2282 case GLX_RENDER_TYPE: 2283 *value = GLX_RGBA_TYPE; 2284 break; 2285 case GLX_SCREEN: 2286 *value = 0; 2287 return Success; 2288 default: 2289 return GLX_BAD_ATTRIBUTE; 2290 } 2291 return 0; 2292 } 2293 2294 2295 static void 2296 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) 2297 { 2298 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2299 if (xmbuf) 2300 xmbuf->selectedEvents = mask; 2301 } 2302 2303 2304 static void 2305 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, 2306 unsigned long *mask ) 2307 { 2308 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2309 if (xmbuf) 2310 *mask = xmbuf->selectedEvents; 2311 else 2312 *mask = 0; 2313 } 2314 2315 2316 2317 /*** GLX_SGI_swap_control ***/ 2318 2319 static int 2320 Fake_glXSwapIntervalSGI(int interval) 2321 { 2322 (void) interval; 2323 return 0; 2324 } 2325 2326 2327 2328 /*** GLX_SGI_video_sync ***/ 2329 2330 static unsigned int FrameCounter = 0; 2331 2332 static int 2333 Fake_glXGetVideoSyncSGI(unsigned int *count) 2334 { 2335 /* this is a bogus implementation */ 2336 *count = FrameCounter++; 2337 return 0; 2338 } 2339 2340 static int 2341 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 2342 { 2343 if (divisor <= 0 || remainder < 0) 2344 return GLX_BAD_VALUE; 2345 /* this is a bogus implementation */ 2346 FrameCounter++; 2347 while (FrameCounter % divisor != remainder) 2348 FrameCounter++; 2349 *count = FrameCounter; 2350 return 0; 2351 } 2352 2353 2354 2355 /*** GLX_SGI_make_current_read ***/ 2356 2357 static Bool 2358 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) 2359 { 2360 return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); 2361 } 2362 2363 /* not used 2364 static GLXDrawable 2365 Fake_glXGetCurrentReadDrawableSGI(void) 2366 { 2367 return 0; 2368 } 2369 */ 2370 2371 2372 /*** GLX_SGIX_video_source ***/ 2373 #if defined(_VL_H) 2374 2375 static GLXVideoSourceSGIX 2376 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) 2377 { 2378 (void) dpy; 2379 (void) screen; 2380 (void) server; 2381 (void) path; 2382 (void) nodeClass; 2383 (void) drainNode; 2384 return 0; 2385 } 2386 2387 static void 2388 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) 2389 { 2390 (void) dpy; 2391 (void) src; 2392 } 2393 2394 #endif 2395 2396 2397 /*** GLX_EXT_import_context ***/ 2398 2399 static void 2400 Fake_glXFreeContextEXT(Display *dpy, GLXContext context) 2401 { 2402 (void) dpy; 2403 (void) context; 2404 } 2405 2406 static GLXContextID 2407 Fake_glXGetContextIDEXT(const GLXContext context) 2408 { 2409 (void) context; 2410 return 0; 2411 } 2412 2413 static GLXContext 2414 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) 2415 { 2416 (void) dpy; 2417 (void) contextID; 2418 return 0; 2419 } 2420 2421 static int 2422 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) 2423 { 2424 (void) dpy; 2425 (void) context; 2426 (void) attribute; 2427 (void) value; 2428 return 0; 2429 } 2430 2431 2432 2433 /*** GLX_SGIX_fbconfig ***/ 2434 2435 static int 2436 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) 2437 { 2438 return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); 2439 } 2440 2441 static GLXFBConfigSGIX * 2442 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) 2443 { 2444 return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); 2445 } 2446 2447 2448 static GLXPixmap 2449 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) 2450 { 2451 XMesaVisual xmvis = (XMesaVisual) config; 2452 XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); 2453 return xmbuf->frontxrb->pixmap; /* need to return an X ID */ 2454 } 2455 2456 2457 static GLXContext 2458 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) 2459 { 2460 XMesaContext xmCtx; 2461 XMesaVisual xmvis = (XMesaVisual) config; 2462 2463 /* deallocate unused windows/buffers */ 2464 XMesaGarbageCollect(dpy); 2465 2466 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); 2467 2468 return (GLXContext) xmCtx; 2469 } 2470 2471 2472 static XVisualInfo * 2473 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) 2474 { 2475 return Fake_glXGetVisualFromFBConfig(dpy, config); 2476 } 2477 2478 2479 static GLXFBConfigSGIX 2480 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) 2481 { 2482 XMesaVisual xmvis = find_glx_visual(dpy, vis); 2483 if (!xmvis) { 2484 /* This visual wasn't found with glXChooseVisual() */ 2485 xmvis = create_glx_visual(dpy, vis); 2486 } 2487 2488 return (GLXFBConfigSGIX) xmvis; 2489 } 2490 2491 2492 2493 /*** GLX_SGIX_pbuffer ***/ 2494 2495 static GLXPbufferSGIX 2496 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, 2497 unsigned int width, unsigned int height, 2498 int *attribList) 2499 { 2500 XMesaVisual xmvis = (XMesaVisual) config; 2501 XMesaBuffer xmbuf; 2502 const int *attrib; 2503 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2504 2505 (void) dpy; 2506 2507 for (attrib = attribList; attrib && *attrib; attrib++) { 2508 switch (*attrib) { 2509 case GLX_PRESERVED_CONTENTS_SGIX: 2510 attrib++; 2511 preserveContents = *attrib; /* ignored */ 2512 break; 2513 case GLX_LARGEST_PBUFFER_SGIX: 2514 attrib++; 2515 useLargest = *attrib; /* ignored */ 2516 break; 2517 default: 2518 return 0; 2519 } 2520 } 2521 2522 /* not used at this time */ 2523 (void) useLargest; 2524 (void) preserveContents; 2525 2526 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2527 /* A GLXPbuffer handle must be an X Drawable because that's what 2528 * glXMakeCurrent takes. 2529 */ 2530 return (GLXPbuffer) xmbuf->frontxrb->pixmap; 2531 } 2532 2533 2534 static void 2535 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) 2536 { 2537 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2538 if (xmbuf) { 2539 XMesaDestroyBuffer(xmbuf); 2540 } 2541 } 2542 2543 2544 static int 2545 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) 2546 { 2547 const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2548 2549 if (!xmbuf) { 2550 /* Generate GLXBadPbufferSGIX for bad pbuffer */ 2551 return 0; 2552 } 2553 2554 switch (attribute) { 2555 case GLX_PRESERVED_CONTENTS_SGIX: 2556 *value = xmbuf->preservedContents; 2557 break; 2558 case GLX_LARGEST_PBUFFER_SGIX: 2559 *value = xmbuf->largestPbuffer; 2560 break; 2561 case GLX_WIDTH_SGIX: 2562 *value = xmbuf->mesa_buffer.Width; 2563 break; 2564 case GLX_HEIGHT_SGIX: 2565 *value = xmbuf->mesa_buffer.Height; 2566 break; 2567 case GLX_EVENT_MASK_SGIX: 2568 *value = 0; /* XXX might be wrong */ 2569 break; 2570 default: 2571 *value = 0; 2572 } 2573 return 0; 2574 } 2575 2576 2577 static void 2578 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) 2579 { 2580 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2581 if (xmbuf) { 2582 /* Note: we'll never generate clobber events */ 2583 xmbuf->selectedEvents = mask; 2584 } 2585 } 2586 2587 2588 static void 2589 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) 2590 { 2591 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2592 if (xmbuf) { 2593 *mask = xmbuf->selectedEvents; 2594 } 2595 else { 2596 *mask = 0; 2597 } 2598 } 2599 2600 2601 2602 /*** GLX_SGI_cushion ***/ 2603 2604 static void 2605 Fake_glXCushionSGI(Display *dpy, Window win, float cushion) 2606 { 2607 (void) dpy; 2608 (void) win; 2609 (void) cushion; 2610 } 2611 2612 2613 2614 /*** GLX_SGIX_video_resize ***/ 2615 2616 static int 2617 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) 2618 { 2619 (void) dpy; 2620 (void) screen; 2621 (void) channel; 2622 (void) window; 2623 return 0; 2624 } 2625 2626 static int 2627 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) 2628 { 2629 (void) dpy; 2630 (void) screen; 2631 (void) channel; 2632 (void) x; 2633 (void) y; 2634 (void) w; 2635 (void) h; 2636 return 0; 2637 } 2638 2639 static int 2640 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) 2641 { 2642 (void) dpy; 2643 (void) screen; 2644 (void) channel; 2645 (void) x; 2646 (void) y; 2647 (void) w; 2648 (void) h; 2649 return 0; 2650 } 2651 2652 static int 2653 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) 2654 { 2655 (void) dpy; 2656 (void) screen; 2657 (void) channel; 2658 (void) dx; 2659 (void) dy; 2660 (void) dw; 2661 (void) dh; 2662 return 0; 2663 } 2664 2665 static int 2666 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) 2667 { 2668 (void) dpy; 2669 (void) screen; 2670 (void) channel; 2671 (void) synctype; 2672 return 0; 2673 } 2674 2675 2676 2677 /*** GLX_SGIX_dmbuffer **/ 2678 2679 #if defined(_DM_BUFFER_H_) 2680 static Bool 2681 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) 2682 { 2683 (void) dpy; 2684 (void) pbuffer; 2685 (void) params; 2686 (void) dmbuffer; 2687 return False; 2688 } 2689 #endif 2690 2691 2692 /*** GLX_SGIX_swap_group ***/ 2693 2694 static void 2695 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) 2696 { 2697 (void) dpy; 2698 (void) drawable; 2699 (void) member; 2700 } 2701 2702 2703 2704 /*** GLX_SGIX_swap_barrier ***/ 2705 2706 static void 2707 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) 2708 { 2709 (void) dpy; 2710 (void) drawable; 2711 (void) barrier; 2712 } 2713 2714 static Bool 2715 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) 2716 { 2717 (void) dpy; 2718 (void) screen; 2719 (void) max; 2720 return False; 2721 } 2722 2723 2724 2725 /*** GLX_SUN_get_transparent_index ***/ 2726 2727 static Status 2728 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) 2729 { 2730 (void) dpy; 2731 (void) overlay; 2732 (void) underlay; 2733 (void) pTransparent; 2734 return 0; 2735 } 2736 2737 2738 2739 /*** GLX_MESA_release_buffers ***/ 2740 2741 /* 2742 * Release the depth, stencil, accum buffers attached to a GLXDrawable 2743 * (a window or pixmap) prior to destroying the GLXDrawable. 2744 */ 2745 static Bool 2746 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) 2747 { 2748 XMesaBuffer b = XMesaFindBuffer(dpy, d); 2749 if (b) { 2750 XMesaDestroyBuffer(b); 2751 return True; 2752 } 2753 return False; 2754 } 2755 2756 2757 2758 /*** GLX_MESA_set_3dfx_mode ***/ 2759 2760 static Bool 2761 Fake_glXSet3DfxModeMESA( int mode ) 2762 { 2763 return XMesaSetFXmode( mode ); 2764 } 2765 2766 2767 2768 /*** GLX_NV_vertex_array range ***/ 2769 static void * 2770 Fake_glXAllocateMemoryNV( GLsizei size, 2771 GLfloat readFrequency, 2772 GLfloat writeFrequency, 2773 GLfloat priority ) 2774 { 2775 (void) size; 2776 (void) readFrequency; 2777 (void) writeFrequency; 2778 (void) priority; 2779 return NULL; 2780 } 2781 2782 2783 static void 2784 Fake_glXFreeMemoryNV( GLvoid *pointer ) 2785 { 2786 (void) pointer; 2787 } 2788 2789 2790 /*** GLX_MESA_agp_offset ***/ 2791 2792 static GLuint 2793 Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) 2794 { 2795 (void) pointer; 2796 return ~0; 2797 } 2798 2799 2800 /*** GLX_EXT_texture_from_pixmap ***/ 2801 2802 static void 2803 Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, 2804 const int *attrib_list) 2805 { 2806 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2807 if (b) 2808 XMesaBindTexImage(dpy, b, buffer, attrib_list); 2809 } 2810 2811 static void 2812 Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) 2813 { 2814 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2815 if (b) 2816 XMesaReleaseTexImage(dpy, b, buffer); 2817 } 2818 2819 2820 static GLXContext 2821 Fake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config, 2822 GLXContext share_context, Bool direct, 2823 const int *attrib_list) 2824 { 2825 XMesaContext xmCtx; 2826 XMesaVisual xmvis = (XMesaVisual) config; 2827 int i; 2828 int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0; 2829 2830 for (i = 0; attrib_list[i]; i += 2) { 2831 switch (attrib_list[i]) { 2832 case GLX_CONTEXT_MAJOR_VERSION_ARB: 2833 major = attrib_list[i + 1]; 2834 break; 2835 case GLX_CONTEXT_MINOR_VERSION_ARB: 2836 minor = attrib_list[i + 1]; 2837 break; 2838 case GLX_CONTEXT_FLAGS_ARB: 2839 ctxFlags = attrib_list[i + 1]; 2840 break; 2841 case GLX_CONTEXT_PROFILE_MASK_ARB: 2842 profileFlags = attrib_list[i + 1]; 2843 break; 2844 default: 2845 fprintf(stderr, "Bad attribute in glXCreateContextAttribs()\n"); 2846 return 0; 2847 } 2848 } 2849 2850 if (major * 10 + minor > 21) { 2851 /* swrast only supports GL 2.1 and earlier */ 2852 return 0; 2853 } 2854 2855 /* These are ignored for now. We'd have to enhance XMesaCreateContext 2856 * to take these flags and the version, at least. 2857 */ 2858 (void) ctxFlags; 2859 (void) profileFlags; 2860 2861 /* deallocate unused windows/buffers */ 2862 XMesaGarbageCollect(dpy); 2863 2864 xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context); 2865 2866 return (GLXContext) xmCtx; 2867 } 2868 2869 2870 /* silence warning */ 2871 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); 2872 2873 2874 /** 2875 * Create a new GLX API dispatch table with its function pointers 2876 * initialized to point to Mesa's "fake" GLX API functions. 2877 * Note: there's a similar function (_real_GetGLXDispatchTable) that 2878 * returns a new dispatch table with all pointers initalized to point 2879 * to "real" GLX functions (which understand GLX wire protocol, etc). 2880 */ 2881 struct _glxapi_table * 2882 _mesa_GetGLXDispatchTable(void) 2883 { 2884 static struct _glxapi_table glx; 2885 2886 /* be sure our dispatch table size <= libGL's table */ 2887 { 2888 GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); 2889 (void) size; 2890 assert(_glxapi_get_dispatch_table_size() >= size); 2891 } 2892 2893 /* initialize the whole table to no-ops */ 2894 _glxapi_set_no_op_table(&glx); 2895 2896 /* now initialize the table with the functions I implement */ 2897 glx.ChooseVisual = Fake_glXChooseVisual; 2898 glx.CopyContext = Fake_glXCopyContext; 2899 glx.CreateContext = Fake_glXCreateContext; 2900 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; 2901 glx.DestroyContext = Fake_glXDestroyContext; 2902 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; 2903 glx.GetConfig = Fake_glXGetConfig; 2904 glx.GetCurrentContext = Fake_glXGetCurrentContext; 2905 /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ 2906 glx.IsDirect = Fake_glXIsDirect; 2907 glx.MakeCurrent = Fake_glXMakeCurrent; 2908 glx.QueryExtension = Fake_glXQueryExtension; 2909 glx.QueryVersion = Fake_glXQueryVersion; 2910 glx.SwapBuffers = Fake_glXSwapBuffers; 2911 glx.UseXFont = Fake_glXUseXFont; 2912 glx.WaitGL = Fake_glXWaitGL; 2913 glx.WaitX = Fake_glXWaitX; 2914 2915 /*** GLX_VERSION_1_1 ***/ 2916 glx.GetClientString = Fake_glXGetClientString; 2917 glx.QueryExtensionsString = Fake_glXQueryExtensionsString; 2918 glx.QueryServerString = Fake_glXQueryServerString; 2919 2920 /*** GLX_VERSION_1_2 ***/ 2921 /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ 2922 2923 /*** GLX_VERSION_1_3 ***/ 2924 glx.ChooseFBConfig = Fake_glXChooseFBConfig; 2925 glx.CreateNewContext = Fake_glXCreateNewContext; 2926 glx.CreatePbuffer = Fake_glXCreatePbuffer; 2927 glx.CreatePixmap = Fake_glXCreatePixmap; 2928 glx.CreateWindow = Fake_glXCreateWindow; 2929 glx.DestroyPbuffer = Fake_glXDestroyPbuffer; 2930 glx.DestroyPixmap = Fake_glXDestroyPixmap; 2931 glx.DestroyWindow = Fake_glXDestroyWindow; 2932 /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ 2933 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; 2934 glx.GetFBConfigs = Fake_glXGetFBConfigs; 2935 glx.GetSelectedEvent = Fake_glXGetSelectedEvent; 2936 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; 2937 glx.MakeContextCurrent = Fake_glXMakeContextCurrent; 2938 glx.QueryContext = Fake_glXQueryContext; 2939 glx.QueryDrawable = Fake_glXQueryDrawable; 2940 glx.SelectEvent = Fake_glXSelectEvent; 2941 2942 /*** GLX_SGI_swap_control ***/ 2943 glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; 2944 2945 /*** GLX_SGI_video_sync ***/ 2946 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; 2947 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; 2948 2949 /*** GLX_SGI_make_current_read ***/ 2950 glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; 2951 /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ 2952 2953 /*** GLX_SGIX_video_source ***/ 2954 #if defined(_VL_H) 2955 glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; 2956 glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; 2957 #endif 2958 2959 /*** GLX_EXT_import_context ***/ 2960 glx.FreeContextEXT = Fake_glXFreeContextEXT; 2961 glx.GetContextIDEXT = Fake_glXGetContextIDEXT; 2962 /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ 2963 glx.ImportContextEXT = Fake_glXImportContextEXT; 2964 glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; 2965 2966 /*** GLX_SGIX_fbconfig ***/ 2967 glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; 2968 glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; 2969 glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; 2970 glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; 2971 glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; 2972 glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; 2973 2974 /*** GLX_SGIX_pbuffer ***/ 2975 glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; 2976 glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; 2977 glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; 2978 glx.SelectEventSGIX = Fake_glXSelectEventSGIX; 2979 glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; 2980 2981 /*** GLX_SGI_cushion ***/ 2982 glx.CushionSGI = Fake_glXCushionSGI; 2983 2984 /*** GLX_SGIX_video_resize ***/ 2985 glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; 2986 glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; 2987 glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; 2988 glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; 2989 glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; 2990 2991 /*** GLX_SGIX_dmbuffer **/ 2992 #if defined(_DM_BUFFER_H_) 2993 glx.AssociateDMPbufferSGIX = NULL; 2994 #endif 2995 2996 /*** GLX_SGIX_swap_group ***/ 2997 glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; 2998 2999 /*** GLX_SGIX_swap_barrier ***/ 3000 glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; 3001 glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; 3002 3003 /*** GLX_SUN_get_transparent_index ***/ 3004 glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; 3005 3006 /*** GLX_MESA_copy_sub_buffer ***/ 3007 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; 3008 3009 /*** GLX_MESA_release_buffers ***/ 3010 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; 3011 3012 /*** GLX_MESA_pixmap_colormap ***/ 3013 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; 3014 3015 /*** GLX_MESA_set_3dfx_mode ***/ 3016 glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; 3017 3018 /*** GLX_NV_vertex_array_range ***/ 3019 glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; 3020 glx.FreeMemoryNV = Fake_glXFreeMemoryNV; 3021 3022 /*** GLX_MESA_agp_offset ***/ 3023 glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; 3024 3025 /*** GLX_EXT_texture_from_pixmap ***/ 3026 glx.BindTexImageEXT = Fake_glXBindTexImageEXT; 3027 glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; 3028 3029 glx.CreateContextAttribs = Fake_glXCreateContextAttribs; 3030 return &glx; 3031 } 3032