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