glx_api.c revision 85ee0ef9a72e4ffd6ed0a2442b1272a43508d257
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.6 4 * 5 * Copyright (C) 1999-2007 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 * "Fake" GLX API implemented in terms of the XMesa*() functions. 29 */ 30 31 32 33#define GLX_GLXEXT_PROTOTYPES 34#include "GL/glx.h" 35 36#include "xm_api.h" 37#include "main/context.h" 38#include "main/config.h" 39#include "main/macros.h" 40#include "main/imports.h" 41#include "main/version.h" 42#include "state_tracker/st_context.h" 43#include "state_tracker/st_public.h" 44 45 46/* This indicates the client-side GLX API and GLX encoder version. */ 47#define CLIENT_MAJOR_VERSION 1 48#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ 49 50/* This indicates the server-side GLX decoder version. 51 * GLX 1.4 indicates OpenGL 1.3 support 52 */ 53#define SERVER_MAJOR_VERSION 1 54#define SERVER_MINOR_VERSION 4 55 56/* This is appended onto the glXGetClient/ServerString version strings. */ 57#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING 58 59/* Who implemented this GLX? */ 60#define VENDOR "Brian Paul" 61 62#define EXTENSIONS \ 63 "GLX_MESA_copy_sub_buffer " \ 64 "GLX_MESA_pixmap_colormap " \ 65 "GLX_MESA_release_buffers " \ 66 "GLX_ARB_get_proc_address " \ 67 "GLX_EXT_texture_from_pixmap " \ 68 "GLX_EXT_visual_info " \ 69 "GLX_EXT_visual_rating " \ 70 /*"GLX_SGI_video_sync "*/ \ 71 "GLX_SGIX_fbconfig " \ 72 "GLX_SGIX_pbuffer " 73 74#define DEFAULT_DIRECT GL_TRUE 75 76 77 78/** 79 * The GLXContext typedef is defined as a pointer to this structure. 80 */ 81struct __GLXcontextRec 82{ 83 Display *currentDpy; 84 GLboolean isDirect; 85 GLXDrawable currentDrawable; 86 GLXDrawable currentReadable; 87 XID xid; 88 89 XMesaContext xmesaContext; 90}; 91 92 93 94static pipe_tsd ContextTSD; 95 96/** Set current context for calling thread */ 97static void 98SetCurrentContext(GLXContext c) 99{ 100 pipe_tsd_set(&ContextTSD, c); 101} 102 103/** Get current context for calling thread */ 104static GLXContext 105GetCurrentContext(void) 106{ 107 return pipe_tsd_get(&ContextTSD); 108} 109 110 111 112/**********************************************************************/ 113/*** GLX Visual Code ***/ 114/**********************************************************************/ 115 116#define DONT_CARE -1 117 118 119static XMesaVisual *VisualTable = NULL; 120static int NumVisuals = 0; 121 122 123 124/* Macro to handle c_class vs class field name in XVisualInfo struct */ 125#if defined(__cplusplus) || defined(c_plusplus) 126#define CLASS c_class 127#else 128#define CLASS class 129#endif 130 131 132 133/* 134 * Test if the given XVisualInfo is usable for Mesa rendering. 135 */ 136static GLboolean 137is_usable_visual( XVisualInfo *vinfo ) 138{ 139 switch (vinfo->CLASS) { 140 case StaticGray: 141 case GrayScale: 142 /* Any StaticGray/GrayScale visual works in RGB or CI mode */ 143 return GL_TRUE; 144 case StaticColor: 145 case PseudoColor: 146 /* Any StaticColor/PseudoColor visual of at least 4 bits */ 147 if (vinfo->depth>=4) { 148 return GL_TRUE; 149 } 150 else { 151 return GL_FALSE; 152 } 153 case TrueColor: 154 case DirectColor: 155 /* Any depth of TrueColor or DirectColor works in RGB mode */ 156 return GL_TRUE; 157 default: 158 /* This should never happen */ 159 return GL_FALSE; 160 } 161} 162 163 164/* 165 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the 166 * configuration in our list of GLX visuals. 167 */ 168static XMesaVisual 169save_glx_visual( Display *dpy, XVisualInfo *vinfo, 170 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag, 171 GLboolean stereoFlag, 172 GLint depth_size, GLint stencil_size, 173 GLint accumRedSize, GLint accumGreenSize, 174 GLint accumBlueSize, GLint accumAlphaSize, 175 GLint level, GLint numAuxBuffers ) 176{ 177 GLboolean ximageFlag = GL_TRUE; 178 XMesaVisual xmvis; 179 GLint i; 180 GLboolean comparePointers; 181 182 if (dbFlag) { 183 /* Check if the MESA_BACK_BUFFER env var is set */ 184 char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER"); 185 if (backbuffer) { 186 if (backbuffer[0]=='p' || backbuffer[0]=='P') { 187 ximageFlag = GL_FALSE; 188 } 189 else if (backbuffer[0]=='x' || backbuffer[0]=='X') { 190 ximageFlag = GL_TRUE; 191 } 192 else { 193 _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); 194 } 195 } 196 } 197 198 if (stereoFlag) { 199 /* stereo not supported */ 200 return NULL; 201 } 202 203 if (stencil_size > 0 && depth_size > 0) 204 depth_size = 24; 205 206 /* Comparing IDs uses less memory but sometimes fails. */ 207 /* XXX revisit this after 3.0 is finished. */ 208 if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) 209 comparePointers = GL_TRUE; 210 else 211 comparePointers = GL_FALSE; 212 213 /* Force the visual to have an alpha channel */ 214 if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) 215 alphaFlag = GL_TRUE; 216 217 /* First check if a matching visual is already in the list */ 218 for (i=0; i<NumVisuals; i++) { 219 XMesaVisual v = VisualTable[i]; 220 if (v->display == dpy 221 && v->mesa_visual.level == level 222 && v->mesa_visual.numAuxBuffers == numAuxBuffers 223 && v->ximage_flag == ximageFlag 224 && v->mesa_visual.rgbMode == rgbFlag 225 && v->mesa_visual.doubleBufferMode == dbFlag 226 && v->mesa_visual.stereoMode == stereoFlag 227 && (v->mesa_visual.alphaBits > 0) == alphaFlag 228 && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) 229 && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) 230 && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) 231 && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) 232 && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) 233 && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { 234 /* now either compare XVisualInfo pointers or visual IDs */ 235 if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) 236 || (comparePointers && v->vishandle == vinfo)) { 237 return v; 238 } 239 } 240 } 241 242 /* Create a new visual and add it to the list. */ 243 244 xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, 245 stereoFlag, ximageFlag, 246 depth_size, stencil_size, 247 accumRedSize, accumBlueSize, 248 accumBlueSize, accumAlphaSize, 0, level, 249 GLX_NONE_EXT ); 250 if (xmvis) { 251 /* Save a copy of the pointer now so we can find this visual again 252 * if we need to search for it in find_glx_visual(). 253 */ 254 xmvis->vishandle = vinfo; 255 /* Allocate more space for additional visual */ 256 VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, 257 sizeof(XMesaVisual) * NumVisuals, 258 sizeof(XMesaVisual) * (NumVisuals + 1)); 259 /* add xmvis to the list */ 260 VisualTable[NumVisuals] = xmvis; 261 NumVisuals++; 262 /* XXX minor hack, because XMesaCreateVisual doesn't support an 263 * aux buffers parameter. 264 */ 265 xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; 266 } 267 return xmvis; 268} 269 270 271/** 272 * Return the default number of bits for the Z buffer. 273 * If defined, use the MESA_GLX_DEPTH_BITS env var value. 274 * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. 275 * XXX probably do the same thing for stencil, accum, etc. 276 */ 277static GLint 278default_depth_bits(void) 279{ 280 int zBits; 281 const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); 282 if (zEnv) 283 zBits = _mesa_atoi(zEnv); 284 else 285 zBits = DEFAULT_SOFTWARE_DEPTH_BITS; 286 return zBits; 287} 288 289static GLint 290default_alpha_bits(void) 291{ 292 int aBits; 293 const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); 294 if (aEnv) 295 aBits = _mesa_atoi(aEnv); 296 else 297 aBits = 0; 298 return aBits; 299} 300 301static GLint 302default_accum_bits(void) 303{ 304 return 16; 305} 306 307 308 309/* 310 * Create a GLX visual from a regular XVisualInfo. 311 * This is called when Fake GLX is given an XVisualInfo which wasn't 312 * returned by glXChooseVisual. Since this is the first time we're 313 * considering this visual we'll take a guess at reasonable values 314 * for depth buffer size, stencil size, accum size, etc. 315 * This is the best we can do with a client-side emulation of GLX. 316 */ 317static XMesaVisual 318create_glx_visual( Display *dpy, XVisualInfo *visinfo ) 319{ 320 GLint zBits = default_depth_bits(); 321 GLint accBits = default_accum_bits(); 322 GLboolean alphaFlag = default_alpha_bits() > 0; 323 324 if (is_usable_visual( visinfo )) { 325 /* Configure this visual as RGB, double-buffered, depth-buffered. */ 326 /* This is surely wrong for some people's needs but what else */ 327 /* can be done? They should use glXChooseVisual(). */ 328 return save_glx_visual( dpy, visinfo, 329 GL_TRUE, /* rgb */ 330 alphaFlag, /* alpha */ 331 GL_TRUE, /* double */ 332 GL_FALSE, /* stereo */ 333 zBits, 334 STENCIL_BITS, 335 accBits, /* r */ 336 accBits, /* g */ 337 accBits, /* b */ 338 accBits, /* a */ 339 0, /* level */ 340 0 /* numAux */ 341 ); 342 } 343 else { 344 _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); 345 return NULL; 346 } 347} 348 349 350 351/* 352 * Find the GLX visual associated with an XVisualInfo. 353 */ 354static XMesaVisual 355find_glx_visual( Display *dpy, XVisualInfo *vinfo ) 356{ 357 int i; 358 359 /* try to match visual id */ 360 for (i=0;i<NumVisuals;i++) { 361 if (VisualTable[i]->display==dpy 362 && VisualTable[i]->visinfo->visualid == vinfo->visualid) { 363 return VisualTable[i]; 364 } 365 } 366 367 /* if that fails, try to match pointers */ 368 for (i=0;i<NumVisuals;i++) { 369 if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) { 370 return VisualTable[i]; 371 } 372 } 373 374 return NULL; 375} 376 377 378/** 379 * Try to get an X visual which matches the given arguments. 380 */ 381static XVisualInfo * 382get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) 383{ 384 XVisualInfo temp, *vis; 385 long mask; 386 int n; 387 unsigned int default_depth; 388 int default_class; 389 390 mask = VisualScreenMask | VisualDepthMask | VisualClassMask; 391 temp.screen = scr; 392 temp.depth = depth; 393 temp.CLASS = xclass; 394 395 default_depth = DefaultDepth(dpy,scr); 396 default_class = DefaultVisual(dpy,scr)->CLASS; 397 398 if (depth==default_depth && xclass==default_class) { 399 /* try to get root window's visual */ 400 temp.visualid = DefaultVisual(dpy,scr)->visualid; 401 mask |= VisualIDMask; 402 } 403 404 vis = XGetVisualInfo( dpy, mask, &temp, &n ); 405 406 /* In case bits/pixel > 24, make sure color channels are still <=8 bits. 407 * An SGI Infinite Reality system, for example, can have 30bpp pixels: 408 * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. 409 */ 410 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { 411 if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && 412 _mesa_bitcount((GLuint) vis->green_mask) <= 8 && 413 _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { 414 return vis; 415 } 416 else { 417 XFree((void *) vis); 418 return NULL; 419 } 420 } 421 422 return vis; 423} 424 425 426/* 427 * Retrieve the value of the given environment variable and find 428 * the X visual which matches it. 429 * Input: dpy - the display 430 * screen - the screen number 431 * varname - the name of the environment variable 432 * Return: an XVisualInfo pointer to NULL if error. 433 */ 434static XVisualInfo * 435get_env_visual(Display *dpy, int scr, const char *varname) 436{ 437 char value[100], type[100]; 438 int depth, xclass = -1; 439 XVisualInfo *vis; 440 441 if (!_mesa_getenv( varname )) { 442 return NULL; 443 } 444 445 _mesa_strncpy( value, _mesa_getenv(varname), 100 ); 446 value[99] = 0; 447 448 sscanf( value, "%s %d", type, &depth ); 449 450 if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; 451 else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; 452 else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; 453 else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; 454 else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; 455 else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; 456 457 if (xclass>-1 && depth>0) { 458 vis = get_visual( dpy, scr, depth, xclass ); 459 if (vis) { 460 return vis; 461 } 462 } 463 464 _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", 465 type, depth); 466 467 return NULL; 468} 469 470 471 472/* 473 * Select an X visual which satisfies the RGBA flag and minimum depth. 474 * Input: dpy, 475 * screen - X display and screen number 476 * min_depth - minimum visual depth 477 * preferred_class - preferred GLX visual class or DONT_CARE 478 * Return: pointer to an XVisualInfo or NULL. 479 */ 480static XVisualInfo * 481choose_x_visual( Display *dpy, int screen, int min_depth, 482 int preferred_class ) 483{ 484 XVisualInfo *vis; 485 int xclass, visclass = 0; 486 int depth; 487 488 /* First see if the MESA_RGB_VISUAL env var is defined */ 489 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); 490 if (vis) { 491 return vis; 492 } 493 /* Otherwise, search for a suitable visual */ 494 if (preferred_class==DONT_CARE) { 495 for (xclass=0;xclass<6;xclass++) { 496 switch (xclass) { 497 case 0: visclass = TrueColor; break; 498 case 1: visclass = DirectColor; break; 499 case 2: visclass = PseudoColor; break; 500 case 3: visclass = StaticColor; break; 501 case 4: visclass = GrayScale; break; 502 case 5: visclass = StaticGray; break; 503 } 504 if (min_depth==0) { 505 /* start with shallowest */ 506 for (depth=0;depth<=32;depth++) { 507 if (visclass==TrueColor && depth==8) { 508 /* Special case: try to get 8-bit PseudoColor before */ 509 /* 8-bit TrueColor */ 510 vis = get_visual( dpy, screen, 8, PseudoColor ); 511 if (vis) { 512 return vis; 513 } 514 } 515 vis = get_visual( dpy, screen, depth, visclass ); 516 if (vis) { 517 return vis; 518 } 519 } 520 } 521 else { 522 /* start with deepest */ 523 for (depth=32;depth>=min_depth;depth--) { 524 if (visclass==TrueColor && depth==8) { 525 /* Special case: try to get 8-bit PseudoColor before */ 526 /* 8-bit TrueColor */ 527 vis = get_visual( dpy, screen, 8, PseudoColor ); 528 if (vis) { 529 return vis; 530 } 531 } 532 vis = get_visual( dpy, screen, depth, visclass ); 533 if (vis) { 534 return vis; 535 } 536 } 537 } 538 } 539 } 540 else { 541 /* search for a specific visual class */ 542 switch (preferred_class) { 543 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; 544 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; 545 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; 546 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; 547 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; 548 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; 549 default: return NULL; 550 } 551 if (min_depth==0) { 552 /* start with shallowest */ 553 for (depth=0;depth<=32;depth++) { 554 vis = get_visual( dpy, screen, depth, visclass ); 555 if (vis) { 556 return vis; 557 } 558 } 559 } 560 else { 561 /* start with deepest */ 562 for (depth=32;depth>=min_depth;depth--) { 563 vis = get_visual( dpy, screen, depth, visclass ); 564 if (vis) { 565 return vis; 566 } 567 } 568 } 569 } 570 571 /* didn't find a visual */ 572 return NULL; 573} 574 575 576 577 578/**********************************************************************/ 579/*** Display-related functions ***/ 580/**********************************************************************/ 581 582 583/** 584 * Free all XMesaVisuals which are associated with the given display. 585 */ 586static void 587destroy_visuals_on_display(Display *dpy) 588{ 589 int i; 590 for (i = 0; i < NumVisuals; i++) { 591 if (VisualTable[i]->display == dpy) { 592 /* remove this visual */ 593 int j; 594 free(VisualTable[i]); 595 for (j = i; j < NumVisuals - 1; j++) 596 VisualTable[j] = VisualTable[j + 1]; 597 NumVisuals--; 598 } 599 } 600} 601 602 603/** 604 * Called from XCloseDisplay() to let us free our display-related data. 605 */ 606static int 607close_display_callback(Display *dpy, XExtCodes *codes) 608{ 609 destroy_visuals_on_display(dpy); 610 xmesa_destroy_buffers_on_display(dpy); 611 return 0; 612} 613 614 615/** 616 * Look for the named extension on given display and return a pointer 617 * to the _XExtension data, or NULL if extension not found. 618 */ 619static _XExtension * 620lookup_extension(Display *dpy, const char *extName) 621{ 622 _XExtension *ext; 623 for (ext = dpy->ext_procs; ext; ext = ext->next) { 624 if (ext->name && strcmp(ext->name, extName) == 0) { 625 return ext; 626 } 627 } 628 return NULL; 629} 630 631 632/** 633 * Whenever we're given a new Display pointer, call this function to 634 * register our close_display_callback function. 635 */ 636static void 637register_with_display(Display *dpy) 638{ 639 const char *extName = "MesaGLX"; 640 _XExtension *ext; 641 642 ext = lookup_extension(dpy, extName); 643 if (!ext) { 644 XExtCodes *c = XAddExtension(dpy); 645 ext = dpy->ext_procs; /* new extension is at head of list */ 646 assert(c->extension == ext->codes.extension); 647 ext->name = _mesa_strdup(extName); 648 ext->close_display = close_display_callback; 649 } 650} 651 652 653/**********************************************************************/ 654/*** Begin Fake GLX API Functions ***/ 655/**********************************************************************/ 656 657 658/** 659 * Helper used by glXChooseVisual and glXChooseFBConfig. 660 * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for 661 * the later. 662 * In either case, the attribute list is terminated with the value 'None'. 663 */ 664static XMesaVisual 665choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) 666{ 667 const GLboolean rgbModeDefault = fbConfig; 668 const int *parselist; 669 XVisualInfo *vis; 670 int min_ci = 0; 671 int min_red=0, min_green=0, min_blue=0; 672 GLboolean rgb_flag = rgbModeDefault; 673 GLboolean alpha_flag = GL_FALSE; 674 GLboolean double_flag = GL_FALSE; 675 GLboolean stereo_flag = GL_FALSE; 676 GLint depth_size = 0; 677 GLint stencil_size = 0; 678 GLint accumRedSize = 0; 679 GLint accumGreenSize = 0; 680 GLint accumBlueSize = 0; 681 GLint accumAlphaSize = 0; 682 int level = 0; 683 int visual_type = DONT_CARE; 684 int trans_type = DONT_CARE; 685 int trans_value = DONT_CARE; 686 GLint caveat = DONT_CARE; 687 XMesaVisual xmvis = NULL; 688 int desiredVisualID = -1; 689 int numAux = 0; 690 691 parselist = list; 692 693 while (*parselist) { 694 695 switch (*parselist) { 696 case GLX_USE_GL: 697 if (fbConfig) { 698 /* invalid token */ 699 return NULL; 700 } 701 else { 702 /* skip */ 703 parselist++; 704 } 705 break; 706 case GLX_BUFFER_SIZE: 707 parselist++; 708 min_ci = *parselist++; 709 break; 710 case GLX_LEVEL: 711 parselist++; 712 level = *parselist++; 713 break; 714 case GLX_RGBA: 715 if (fbConfig) { 716 /* invalid token */ 717 return NULL; 718 } 719 else { 720 rgb_flag = GL_TRUE; 721 parselist++; 722 } 723 break; 724 case GLX_DOUBLEBUFFER: 725 parselist++; 726 if (fbConfig) { 727 double_flag = *parselist++; 728 } 729 else { 730 double_flag = GL_TRUE; 731 } 732 break; 733 case GLX_STEREO: 734 parselist++; 735 if (fbConfig) { 736 stereo_flag = *parselist++; 737 } 738 else { 739 stereo_flag = GL_TRUE; 740 } 741 break; 742 case GLX_AUX_BUFFERS: 743 parselist++; 744 numAux = *parselist++; 745 if (numAux > MAX_AUX_BUFFERS) 746 return NULL; 747 break; 748 case GLX_RED_SIZE: 749 parselist++; 750 min_red = *parselist++; 751 break; 752 case GLX_GREEN_SIZE: 753 parselist++; 754 min_green = *parselist++; 755 break; 756 case GLX_BLUE_SIZE: 757 parselist++; 758 min_blue = *parselist++; 759 break; 760 case GLX_ALPHA_SIZE: 761 parselist++; 762 { 763 GLint size = *parselist++; 764 alpha_flag = size ? GL_TRUE : GL_FALSE; 765 } 766 break; 767 case GLX_DEPTH_SIZE: 768 parselist++; 769 depth_size = *parselist++; 770 break; 771 case GLX_STENCIL_SIZE: 772 parselist++; 773 stencil_size = *parselist++; 774 break; 775 case GLX_ACCUM_RED_SIZE: 776 parselist++; 777 { 778 GLint size = *parselist++; 779 accumRedSize = MAX2( accumRedSize, size ); 780 } 781 break; 782 case GLX_ACCUM_GREEN_SIZE: 783 parselist++; 784 { 785 GLint size = *parselist++; 786 accumGreenSize = MAX2( accumGreenSize, size ); 787 } 788 break; 789 case GLX_ACCUM_BLUE_SIZE: 790 parselist++; 791 { 792 GLint size = *parselist++; 793 accumBlueSize = MAX2( accumBlueSize, size ); 794 } 795 break; 796 case GLX_ACCUM_ALPHA_SIZE: 797 parselist++; 798 { 799 GLint size = *parselist++; 800 accumAlphaSize = MAX2( accumAlphaSize, size ); 801 } 802 break; 803 804 /* 805 * GLX_EXT_visual_info extension 806 */ 807 case GLX_X_VISUAL_TYPE_EXT: 808 parselist++; 809 visual_type = *parselist++; 810 break; 811 case GLX_TRANSPARENT_TYPE_EXT: 812 parselist++; 813 trans_type = *parselist++; 814 break; 815 case GLX_TRANSPARENT_INDEX_VALUE_EXT: 816 parselist++; 817 trans_value = *parselist++; 818 break; 819 case GLX_TRANSPARENT_RED_VALUE_EXT: 820 case GLX_TRANSPARENT_GREEN_VALUE_EXT: 821 case GLX_TRANSPARENT_BLUE_VALUE_EXT: 822 case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 823 /* ignore */ 824 parselist++; 825 parselist++; 826 break; 827 828 /* 829 * GLX_EXT_visual_info extension 830 */ 831 case GLX_VISUAL_CAVEAT_EXT: 832 parselist++; 833 caveat = *parselist++; /* ignored for now */ 834 break; 835 836 /* 837 * GLX_ARB_multisample 838 */ 839 case GLX_SAMPLE_BUFFERS_ARB: 840 /* ms not supported */ 841 return NULL; 842 case GLX_SAMPLES_ARB: 843 /* ms not supported */ 844 return NULL; 845 846 /* 847 * FBConfig attribs. 848 */ 849 case GLX_RENDER_TYPE: 850 if (!fbConfig) 851 return NULL; 852 parselist++; 853 if (*parselist & GLX_RGBA_BIT) { 854 rgb_flag = GL_TRUE; 855 } 856 else if (*parselist & GLX_COLOR_INDEX_BIT) { 857 rgb_flag = GL_FALSE; 858 } 859 else if (*parselist == 0) { 860 rgb_flag = GL_TRUE; 861 } 862 parselist++; 863 break; 864 case GLX_DRAWABLE_TYPE: 865 if (!fbConfig) 866 return NULL; 867 parselist++; 868 if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { 869 return NULL; /* bad bit */ 870 } 871 parselist++; 872 break; 873 case GLX_FBCONFIG_ID: 874 if (!fbConfig) 875 return NULL; 876 parselist++; 877 desiredVisualID = *parselist++; 878 break; 879 case GLX_X_RENDERABLE: 880 if (!fbConfig) 881 return NULL; 882 parselist += 2; 883 /* ignore */ 884 break; 885 886#ifdef GLX_EXT_texture_from_pixmap 887 case GLX_BIND_TO_TEXTURE_RGB_EXT: 888 parselist++; /*skip*/ 889 break; 890 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 891 parselist++; /*skip*/ 892 break; 893 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 894 parselist++; /*skip*/ 895 break; 896 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 897 parselist++; 898 if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | 899 GLX_TEXTURE_2D_BIT_EXT | 900 GLX_TEXTURE_RECTANGLE_BIT_EXT)) { 901 /* invalid bit */ 902 return NULL; 903 } 904 break; 905 case GLX_Y_INVERTED_EXT: 906 parselist++; /*skip*/ 907 break; 908#endif 909 910 case None: 911 /* end of list */ 912 break; 913 914 default: 915 /* undefined attribute */ 916 _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", 917 *parselist); 918 return NULL; 919 } 920 } 921 922 (void) caveat; 923 924 925 /* 926 * Since we're only simulating the GLX extension this function will never 927 * find any real GL visuals. Instead, all we can do is try to find an RGB 928 * or CI visual of appropriate depth. Other requested attributes such as 929 * double buffering, depth buffer, etc. will be associated with the X 930 * visual and stored in the VisualTable[]. 931 */ 932 if (desiredVisualID != -1) { 933 /* try to get a specific visual, by visualID */ 934 XVisualInfo temp; 935 int n; 936 temp.visualid = desiredVisualID; 937 temp.screen = screen; 938 vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); 939 if (vis) { 940 /* give the visual some useful GLX attributes */ 941 double_flag = GL_TRUE; 942 rgb_flag = GL_TRUE; 943 depth_size = default_depth_bits(); 944 stencil_size = STENCIL_BITS; 945 /* XXX accum??? */ 946 } 947 } 948 else if (level==0) { 949 /* normal color planes */ 950 /* Get an RGB visual */ 951 int min_rgb = min_red + min_green + min_blue; 952 if (min_rgb>1 && min_rgb<8) { 953 /* a special case to be sure we can get a monochrome visual */ 954 min_rgb = 1; 955 } 956 vis = choose_x_visual( dpy, screen, min_rgb, visual_type ); 957 } 958 else { 959 _mesa_warning(NULL, "overlay not supported"); 960 return NULL; 961 } 962 963 if (vis) { 964 /* Note: we're not exactly obeying the glXChooseVisual rules here. 965 * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the 966 * largest depth buffer size, which is 32bits/value. Instead, we 967 * return 16 to maintain performance with earlier versions of Mesa. 968 */ 969 if (stencil_size > 0) 970 depth_size = 24; /* if Z and stencil, always use 24+8 format */ 971 else if (depth_size > 24) 972 depth_size = 32; 973 else if (depth_size > 16) 974 depth_size = 24; 975 else if (depth_size > 0) { 976 depth_size = default_depth_bits(); 977 } 978 979 if (!alpha_flag) { 980 alpha_flag = default_alpha_bits() > 0; 981 } 982 983 /* we only support one size of stencil and accum buffers. */ 984 if (stencil_size > 0) 985 stencil_size = STENCIL_BITS; 986 987 if (accumRedSize > 0 || 988 accumGreenSize > 0 || 989 accumBlueSize > 0 || 990 accumAlphaSize > 0) { 991 992 accumRedSize = 993 accumGreenSize = 994 accumBlueSize = default_accum_bits(); 995 996 accumAlphaSize = alpha_flag ? accumRedSize : 0; 997 } 998 999 xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, 1000 stereo_flag, depth_size, stencil_size, 1001 accumRedSize, accumGreenSize, 1002 accumBlueSize, accumAlphaSize, level, numAux ); 1003 } 1004 1005 return xmvis; 1006} 1007 1008 1009XVisualInfo * 1010glXChooseVisual( Display *dpy, int screen, int *list ) 1011{ 1012 XMesaVisual xmvis; 1013 1014 /* register ourselves as an extension on this display */ 1015 register_with_display(dpy); 1016 1017 xmvis = choose_visual(dpy, screen, list, GL_FALSE); 1018 if (xmvis) { 1019 /* create a new vishandle - the cached one may be stale */ 1020 xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); 1021 if (xmvis->vishandle) { 1022 _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); 1023 } 1024 return xmvis->vishandle; 1025 } 1026 else 1027 return NULL; 1028} 1029 1030 1031GLXContext 1032glXCreateContext( Display *dpy, XVisualInfo *visinfo, 1033 GLXContext share_list, Bool direct ) 1034{ 1035 XMesaVisual xmvis; 1036 GLXContext glxCtx; 1037 GLXContext shareCtx = share_list; 1038 1039 if (!dpy || !visinfo) 1040 return 0; 1041 1042 glxCtx = CALLOC_STRUCT(__GLXcontextRec); 1043 if (!glxCtx) 1044 return 0; 1045 1046 /* deallocate unused windows/buffers */ 1047#if 0 1048 XMesaGarbageCollect(); 1049#endif 1050 1051 xmvis = find_glx_visual( dpy, visinfo ); 1052 if (!xmvis) { 1053 /* This visual wasn't found with glXChooseVisual() */ 1054 xmvis = create_glx_visual( dpy, visinfo ); 1055 if (!xmvis) { 1056 /* unusable visual */ 1057 _mesa_free(glxCtx); 1058 return NULL; 1059 } 1060 } 1061 1062 glxCtx->xmesaContext = XMesaCreateContext(xmvis, 1063 shareCtx ? shareCtx->xmesaContext : NULL); 1064 if (!glxCtx->xmesaContext) { 1065 _mesa_free(glxCtx); 1066 return NULL; 1067 } 1068 1069 glxCtx->isDirect = DEFAULT_DIRECT; 1070 glxCtx->currentDpy = dpy; 1071 glxCtx->xid = (XID) glxCtx; /* self pointer */ 1072 1073 return glxCtx; 1074} 1075 1076 1077/* XXX these may have to be removed due to thread-safety issues. */ 1078static GLXContext MakeCurrent_PrevContext = 0; 1079static GLXDrawable MakeCurrent_PrevDrawable = 0; 1080static GLXDrawable MakeCurrent_PrevReadable = 0; 1081static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; 1082static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; 1083 1084 1085/* GLX 1.3 and later */ 1086Bool 1087glXMakeContextCurrent( Display *dpy, GLXDrawable draw, 1088 GLXDrawable read, GLXContext ctx ) 1089{ 1090 GLXContext glxCtx = ctx; 1091 static boolean firsttime = 1, no_rast = 0; 1092 1093 if (firsttime) { 1094 no_rast = getenv("SP_NO_RAST") != NULL; 1095 firsttime = 0; 1096 } 1097 1098 if (ctx && draw && read) { 1099 XMesaBuffer drawBuffer, readBuffer; 1100 XMesaContext xmctx = glxCtx->xmesaContext; 1101 1102 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ 1103 if (ctx == MakeCurrent_PrevContext 1104 && draw == MakeCurrent_PrevDrawable) { 1105 drawBuffer = MakeCurrent_PrevDrawBuffer; 1106 } 1107 else { 1108 drawBuffer = XMesaFindBuffer( dpy, draw ); 1109 } 1110 if (!drawBuffer) { 1111 /* drawable must be a new window! */ 1112 drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); 1113 if (!drawBuffer) { 1114 /* Out of memory, or context/drawable depth mismatch */ 1115 return False; 1116 } 1117 } 1118 1119 /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ 1120 if (ctx == MakeCurrent_PrevContext 1121 && read == MakeCurrent_PrevReadable) { 1122 readBuffer = MakeCurrent_PrevReadBuffer; 1123 } 1124 else { 1125 readBuffer = XMesaFindBuffer( dpy, read ); 1126 } 1127 if (!readBuffer) { 1128 /* drawable must be a new window! */ 1129 readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); 1130 if (!readBuffer) { 1131 /* Out of memory, or context/drawable depth mismatch */ 1132 return False; 1133 } 1134 } 1135 1136 if (no_rast && 1137 MakeCurrent_PrevContext == ctx && 1138 MakeCurrent_PrevDrawable == draw && 1139 MakeCurrent_PrevReadable == read && 1140 MakeCurrent_PrevDrawBuffer == drawBuffer && 1141 MakeCurrent_PrevReadBuffer == readBuffer) 1142 return True; 1143 1144 MakeCurrent_PrevContext = ctx; 1145 MakeCurrent_PrevDrawable = draw; 1146 MakeCurrent_PrevReadable = read; 1147 MakeCurrent_PrevDrawBuffer = drawBuffer; 1148 MakeCurrent_PrevReadBuffer = readBuffer; 1149 1150 /* Now make current! */ 1151 if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { 1152 ctx->currentDpy = dpy; 1153 ctx->currentDrawable = draw; 1154 ctx->currentReadable = read; 1155 SetCurrentContext(ctx); 1156 return True; 1157 } 1158 else { 1159 return False; 1160 } 1161 } 1162 else if (!ctx && !draw && !read) { 1163 /* release current context w/out assigning new one. */ 1164 XMesaMakeCurrent2( NULL, NULL, NULL ); 1165 MakeCurrent_PrevContext = 0; 1166 MakeCurrent_PrevDrawable = 0; 1167 MakeCurrent_PrevReadable = 0; 1168 MakeCurrent_PrevDrawBuffer = 0; 1169 MakeCurrent_PrevReadBuffer = 0; 1170 SetCurrentContext(NULL); 1171 return True; 1172 } 1173 else { 1174 /* The args must either all be non-zero or all zero. 1175 * This is an error. 1176 */ 1177 return False; 1178 } 1179} 1180 1181 1182Bool 1183glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) 1184{ 1185 return glXMakeContextCurrent( dpy, drawable, drawable, ctx ); 1186} 1187 1188 1189GLXContext 1190glXGetCurrentContext(void) 1191{ 1192 return GetCurrentContext(); 1193} 1194 1195 1196Display * 1197glXGetCurrentDisplay(void) 1198{ 1199 GLXContext glxCtx = glXGetCurrentContext(); 1200 1201 return glxCtx ? glxCtx->currentDpy : NULL; 1202} 1203 1204 1205Display * 1206glXGetCurrentDisplayEXT(void) 1207{ 1208 return glXGetCurrentDisplay(); 1209} 1210 1211 1212GLXDrawable 1213glXGetCurrentDrawable(void) 1214{ 1215 GLXContext gc = glXGetCurrentContext(); 1216 return gc ? gc->currentDrawable : 0; 1217} 1218 1219 1220GLXDrawable 1221glXGetCurrentReadDrawable(void) 1222{ 1223 GLXContext gc = glXGetCurrentContext(); 1224 return gc ? gc->currentReadable : 0; 1225} 1226 1227 1228GLXDrawable 1229glXGetCurrentReadDrawableSGI(void) 1230{ 1231 return glXGetCurrentReadDrawable(); 1232} 1233 1234 1235GLXPixmap 1236glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) 1237{ 1238 XMesaVisual v; 1239 XMesaBuffer b; 1240 1241 v = find_glx_visual( dpy, visinfo ); 1242 if (!v) { 1243 v = create_glx_visual( dpy, visinfo ); 1244 if (!v) { 1245 /* unusable visual */ 1246 return 0; 1247 } 1248 } 1249 1250 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 1251 if (!b) { 1252 return 0; 1253 } 1254 return b->drawable; 1255} 1256 1257 1258/*** GLX_MESA_pixmap_colormap ***/ 1259 1260GLXPixmap 1261glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, 1262 Pixmap pixmap, Colormap cmap ) 1263{ 1264 XMesaVisual v; 1265 XMesaBuffer b; 1266 1267 v = find_glx_visual( dpy, visinfo ); 1268 if (!v) { 1269 v = create_glx_visual( dpy, visinfo ); 1270 if (!v) { 1271 /* unusable visual */ 1272 return 0; 1273 } 1274 } 1275 1276 b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); 1277 if (!b) { 1278 return 0; 1279 } 1280 return b->drawable; 1281} 1282 1283 1284void 1285glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) 1286{ 1287 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); 1288 if (b) { 1289 XMesaDestroyBuffer(b); 1290 } 1291 else if (_mesa_getenv("MESA_DEBUG")) { 1292 _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); 1293 } 1294} 1295 1296 1297void 1298glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, 1299 unsigned long mask ) 1300{ 1301 XMesaContext xm_src = src->xmesaContext; 1302 XMesaContext xm_dst = dst->xmesaContext; 1303 (void) dpy; 1304 if (MakeCurrent_PrevContext == src) { 1305 _mesa_Flush(); 1306 } 1307 st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask ); 1308} 1309 1310 1311Bool 1312glXQueryExtension( Display *dpy, int *errorb, int *event ) 1313{ 1314 /* Mesa's GLX isn't really an X extension but we try to act like one. */ 1315 (void) dpy; 1316 (void) errorb; 1317 (void) event; 1318 return True; 1319} 1320 1321 1322void 1323glXDestroyContext( Display *dpy, GLXContext ctx ) 1324{ 1325 GLXContext glxCtx = ctx; 1326 (void) dpy; 1327 MakeCurrent_PrevContext = 0; 1328 MakeCurrent_PrevDrawable = 0; 1329 MakeCurrent_PrevReadable = 0; 1330 MakeCurrent_PrevDrawBuffer = 0; 1331 MakeCurrent_PrevReadBuffer = 0; 1332 XMesaDestroyContext( glxCtx->xmesaContext ); 1333 XMesaGarbageCollect(); 1334 _mesa_free(glxCtx); 1335} 1336 1337 1338Bool 1339glXIsDirect( Display *dpy, GLXContext ctx ) 1340{ 1341 GLXContext glxCtx = ctx; 1342 (void) ctx; 1343 return glxCtx->isDirect; 1344} 1345 1346 1347 1348void 1349glXSwapBuffers( Display *dpy, GLXDrawable drawable ) 1350{ 1351 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1352 static boolean firsttime = 1, no_rast = 0; 1353 1354 if (firsttime) { 1355 no_rast = getenv("SP_NO_RAST") != NULL; 1356 firsttime = 0; 1357 } 1358 1359 if (no_rast) 1360 return; 1361 1362 if (buffer) { 1363 XMesaSwapBuffers(buffer); 1364 } 1365 else if (_mesa_getenv("MESA_DEBUG")) { 1366 _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", 1367 (int) drawable); 1368 } 1369} 1370 1371 1372 1373/*** GLX_MESA_copy_sub_buffer ***/ 1374 1375void 1376glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, 1377 int x, int y, int width, int height ) 1378{ 1379 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); 1380 if (buffer) { 1381 XMesaCopySubBuffer(buffer, x, y, width, height); 1382 } 1383 else if (_mesa_getenv("MESA_DEBUG")) { 1384 _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); 1385 } 1386} 1387 1388 1389Bool 1390glXQueryVersion( Display *dpy, int *maj, int *min ) 1391{ 1392 (void) dpy; 1393 /* Return GLX version, not Mesa version */ 1394 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); 1395 *maj = CLIENT_MAJOR_VERSION; 1396 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); 1397 return True; 1398} 1399 1400 1401/* 1402 * Query the GLX attributes of the given XVisualInfo. 1403 */ 1404static int 1405get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) 1406{ 1407 ASSERT(xmvis); 1408 switch(attrib) { 1409 case GLX_USE_GL: 1410 if (fbconfig) 1411 return GLX_BAD_ATTRIBUTE; 1412 *value = (int) True; 1413 return 0; 1414 case GLX_BUFFER_SIZE: 1415 *value = xmvis->visinfo->depth; 1416 return 0; 1417 case GLX_LEVEL: 1418 *value = xmvis->mesa_visual.level; 1419 return 0; 1420 case GLX_RGBA: 1421 if (fbconfig) 1422 return GLX_BAD_ATTRIBUTE; 1423 if (xmvis->mesa_visual.rgbMode) { 1424 *value = True; 1425 } 1426 else { 1427 *value = False; 1428 } 1429 return 0; 1430 case GLX_DOUBLEBUFFER: 1431 *value = (int) xmvis->mesa_visual.doubleBufferMode; 1432 return 0; 1433 case GLX_STEREO: 1434 *value = (int) xmvis->mesa_visual.stereoMode; 1435 return 0; 1436 case GLX_AUX_BUFFERS: 1437 *value = xmvis->mesa_visual.numAuxBuffers; 1438 return 0; 1439 case GLX_RED_SIZE: 1440 *value = xmvis->mesa_visual.redBits; 1441 return 0; 1442 case GLX_GREEN_SIZE: 1443 *value = xmvis->mesa_visual.greenBits; 1444 return 0; 1445 case GLX_BLUE_SIZE: 1446 *value = xmvis->mesa_visual.blueBits; 1447 return 0; 1448 case GLX_ALPHA_SIZE: 1449 *value = xmvis->mesa_visual.alphaBits; 1450 return 0; 1451 case GLX_DEPTH_SIZE: 1452 *value = xmvis->mesa_visual.depthBits; 1453 return 0; 1454 case GLX_STENCIL_SIZE: 1455 *value = xmvis->mesa_visual.stencilBits; 1456 return 0; 1457 case GLX_ACCUM_RED_SIZE: 1458 *value = xmvis->mesa_visual.accumRedBits; 1459 return 0; 1460 case GLX_ACCUM_GREEN_SIZE: 1461 *value = xmvis->mesa_visual.accumGreenBits; 1462 return 0; 1463 case GLX_ACCUM_BLUE_SIZE: 1464 *value = xmvis->mesa_visual.accumBlueBits; 1465 return 0; 1466 case GLX_ACCUM_ALPHA_SIZE: 1467 *value = xmvis->mesa_visual.accumAlphaBits; 1468 return 0; 1469 1470 /* 1471 * GLX_EXT_visual_info extension 1472 */ 1473 case GLX_X_VISUAL_TYPE_EXT: 1474 switch (xmvis->visinfo->CLASS) { 1475 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; 1476 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; 1477 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; 1478 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; 1479 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; 1480 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; 1481 } 1482 return 0; 1483 case GLX_TRANSPARENT_TYPE_EXT: 1484 /* normal planes */ 1485 *value = GLX_NONE_EXT; 1486 return 0; 1487 case GLX_TRANSPARENT_INDEX_VALUE_EXT: 1488 /* undefined */ 1489 return 0; 1490 case GLX_TRANSPARENT_RED_VALUE_EXT: 1491 /* undefined */ 1492 return 0; 1493 case GLX_TRANSPARENT_GREEN_VALUE_EXT: 1494 /* undefined */ 1495 return 0; 1496 case GLX_TRANSPARENT_BLUE_VALUE_EXT: 1497 /* undefined */ 1498 return 0; 1499 case GLX_TRANSPARENT_ALPHA_VALUE_EXT: 1500 /* undefined */ 1501 return 0; 1502 1503 /* 1504 * GLX_EXT_visual_info extension 1505 */ 1506 case GLX_VISUAL_CAVEAT_EXT: 1507 /* test for zero, just in case */ 1508 if (xmvis->mesa_visual.visualRating > 0) 1509 *value = xmvis->mesa_visual.visualRating; 1510 else 1511 *value = GLX_NONE_EXT; 1512 return 0; 1513 1514 /* 1515 * GLX_ARB_multisample 1516 */ 1517 case GLX_SAMPLE_BUFFERS_ARB: 1518 *value = 0; 1519 return 0; 1520 case GLX_SAMPLES_ARB: 1521 *value = 0; 1522 return 0; 1523 1524 /* 1525 * For FBConfigs: 1526 */ 1527 case GLX_SCREEN_EXT: 1528 if (!fbconfig) 1529 return GLX_BAD_ATTRIBUTE; 1530 *value = xmvis->visinfo->screen; 1531 break; 1532 case GLX_DRAWABLE_TYPE: /*SGIX too */ 1533 if (!fbconfig) 1534 return GLX_BAD_ATTRIBUTE; 1535 *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; 1536 break; 1537 case GLX_RENDER_TYPE_SGIX: 1538 if (!fbconfig) 1539 return GLX_BAD_ATTRIBUTE; 1540 if (xmvis->mesa_visual.rgbMode) 1541 *value = GLX_RGBA_BIT; 1542 else 1543 *value = GLX_COLOR_INDEX_BIT; 1544 break; 1545 case GLX_X_RENDERABLE_SGIX: 1546 if (!fbconfig) 1547 return GLX_BAD_ATTRIBUTE; 1548 *value = True; /* XXX really? */ 1549 break; 1550 case GLX_FBCONFIG_ID_SGIX: 1551 if (!fbconfig) 1552 return GLX_BAD_ATTRIBUTE; 1553 *value = xmvis->visinfo->visualid; 1554 break; 1555 case GLX_MAX_PBUFFER_WIDTH: 1556 if (!fbconfig) 1557 return GLX_BAD_ATTRIBUTE; 1558 /* XXX or MAX_WIDTH? */ 1559 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); 1560 break; 1561 case GLX_MAX_PBUFFER_HEIGHT: 1562 if (!fbconfig) 1563 return GLX_BAD_ATTRIBUTE; 1564 *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1565 break; 1566 case GLX_MAX_PBUFFER_PIXELS: 1567 if (!fbconfig) 1568 return GLX_BAD_ATTRIBUTE; 1569 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * 1570 DisplayHeight(xmvis->display, xmvis->visinfo->screen); 1571 break; 1572 case GLX_VISUAL_ID: 1573 if (!fbconfig) 1574 return GLX_BAD_ATTRIBUTE; 1575 *value = xmvis->visinfo->visualid; 1576 break; 1577 1578#ifdef GLX_EXT_texture_from_pixmap 1579 case GLX_BIND_TO_TEXTURE_RGB_EXT: 1580 *value = True; /*XXX*/ 1581 break; 1582 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 1583 /* XXX review */ 1584 *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; 1585 break; 1586 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 1587 *value = True; /*XXX*/ 1588 break; 1589 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 1590 *value = (GLX_TEXTURE_1D_BIT_EXT | 1591 GLX_TEXTURE_2D_BIT_EXT | 1592 GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ 1593 break; 1594 case GLX_Y_INVERTED_EXT: 1595 *value = True; /*XXX*/ 1596 break; 1597#endif 1598 1599 default: 1600 return GLX_BAD_ATTRIBUTE; 1601 } 1602 return Success; 1603} 1604 1605 1606int 1607glXGetConfig( Display *dpy, XVisualInfo *visinfo, 1608 int attrib, int *value ) 1609{ 1610 XMesaVisual xmvis; 1611 int k; 1612 if (!dpy || !visinfo) 1613 return GLX_BAD_ATTRIBUTE; 1614 1615 xmvis = find_glx_visual( dpy, visinfo ); 1616 if (!xmvis) { 1617 /* this visual wasn't obtained with glXChooseVisual */ 1618 xmvis = create_glx_visual( dpy, visinfo ); 1619 if (!xmvis) { 1620 /* this visual can't be used for GL rendering */ 1621 if (attrib==GLX_USE_GL) { 1622 *value = (int) False; 1623 return 0; 1624 } 1625 else { 1626 return GLX_BAD_VISUAL; 1627 } 1628 } 1629 } 1630 1631 k = get_config(xmvis, attrib, value, GL_FALSE); 1632 return k; 1633} 1634 1635 1636void 1637glXWaitGL( void ) 1638{ 1639 XMesaContext xmesa = XMesaGetCurrentContext(); 1640 XMesaFlush( xmesa ); 1641} 1642 1643 1644 1645void 1646glXWaitX( void ) 1647{ 1648 XMesaContext xmesa = XMesaGetCurrentContext(); 1649 XMesaFlush( xmesa ); 1650} 1651 1652 1653static const char * 1654get_extensions( void ) 1655{ 1656 return EXTENSIONS; 1657} 1658 1659 1660 1661/* GLX 1.1 and later */ 1662const char * 1663glXQueryExtensionsString( Display *dpy, int screen ) 1664{ 1665 (void) dpy; 1666 (void) screen; 1667 return get_extensions(); 1668} 1669 1670 1671 1672/* GLX 1.1 and later */ 1673const char * 1674glXQueryServerString( Display *dpy, int screen, int name ) 1675{ 1676 static char version[1000]; 1677 _mesa_sprintf(version, "%d.%d %s", 1678 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); 1679 1680 (void) dpy; 1681 (void) screen; 1682 1683 switch (name) { 1684 case GLX_EXTENSIONS: 1685 return get_extensions(); 1686 case GLX_VENDOR: 1687 return VENDOR; 1688 case GLX_VERSION: 1689 return version; 1690 default: 1691 return NULL; 1692 } 1693} 1694 1695 1696 1697/* GLX 1.1 and later */ 1698const char * 1699glXGetClientString( Display *dpy, int name ) 1700{ 1701 static char version[1000]; 1702 _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, 1703 CLIENT_MINOR_VERSION, MESA_GLX_VERSION); 1704 1705 (void) dpy; 1706 1707 switch (name) { 1708 case GLX_EXTENSIONS: 1709 return get_extensions(); 1710 case GLX_VENDOR: 1711 return VENDOR; 1712 case GLX_VERSION: 1713 return version; 1714 default: 1715 return NULL; 1716 } 1717} 1718 1719 1720 1721/* 1722 * GLX 1.3 and later 1723 */ 1724 1725 1726int 1727glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, 1728 int attribute, int *value ) 1729{ 1730 XMesaVisual v = (XMesaVisual) config; 1731 (void) dpy; 1732 (void) config; 1733 1734 if (!dpy || !config || !value) 1735 return -1; 1736 1737 return get_config(v, attribute, value, GL_TRUE); 1738} 1739 1740 1741GLXFBConfig * 1742glXGetFBConfigs( Display *dpy, int screen, int *nelements ) 1743{ 1744 XVisualInfo *visuals, visTemplate; 1745 const long visMask = VisualScreenMask; 1746 int i; 1747 1748 /* Get list of all X visuals */ 1749 visTemplate.screen = screen; 1750 visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); 1751 if (*nelements > 0) { 1752 XMesaVisual *results; 1753 results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); 1754 if (!results) { 1755 *nelements = 0; 1756 return NULL; 1757 } 1758 for (i = 0; i < *nelements; i++) { 1759 results[i] = create_glx_visual(dpy, visuals + i); 1760 } 1761 return (GLXFBConfig *) results; 1762 } 1763 return NULL; 1764} 1765 1766 1767GLXFBConfig * 1768glXChooseFBConfig( Display *dpy, int screen, 1769 const int *attribList, int *nitems ) 1770{ 1771 XMesaVisual xmvis; 1772 1773 if (!attribList || !attribList[0]) { 1774 /* return list of all configs (per GLX_SGIX_fbconfig spec) */ 1775 return glXGetFBConfigs(dpy, screen, nitems); 1776 } 1777 1778 xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); 1779 if (xmvis) { 1780 GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); 1781 if (!config) { 1782 *nitems = 0; 1783 return NULL; 1784 } 1785 *nitems = 1; 1786 config[0] = (GLXFBConfig) xmvis; 1787 return (GLXFBConfig *) config; 1788 } 1789 else { 1790 *nitems = 0; 1791 return NULL; 1792 } 1793} 1794 1795 1796XVisualInfo * 1797glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) 1798{ 1799 if (dpy && config) { 1800 XMesaVisual xmvis = (XMesaVisual) config; 1801#if 0 1802 return xmvis->vishandle; 1803#else 1804 /* create a new vishandle - the cached one may be stale */ 1805 xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); 1806 if (xmvis->vishandle) { 1807 _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); 1808 } 1809 return xmvis->vishandle; 1810#endif 1811 } 1812 else { 1813 return NULL; 1814 } 1815} 1816 1817 1818GLXWindow 1819glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, 1820 const int *attribList ) 1821{ 1822 XMesaVisual xmvis = (XMesaVisual) config; 1823 XMesaBuffer xmbuf; 1824 if (!xmvis) 1825 return 0; 1826 1827 xmbuf = XMesaCreateWindowBuffer(xmvis, win); 1828 if (!xmbuf) 1829 return 0; 1830 1831 (void) dpy; 1832 (void) attribList; /* Ignored in GLX 1.3 */ 1833 1834 return win; /* A hack for now */ 1835} 1836 1837 1838void 1839glXDestroyWindow( Display *dpy, GLXWindow window ) 1840{ 1841 XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window); 1842 if (b) 1843 XMesaDestroyBuffer(b); 1844 /* don't destroy X window */ 1845} 1846 1847 1848/* XXX untested */ 1849GLXPixmap 1850glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, 1851 const int *attribList ) 1852{ 1853 XMesaVisual v = (XMesaVisual) config; 1854 XMesaBuffer b; 1855 const int *attr; 1856 int target = 0, format = 0, mipmap = 0; 1857 int value; 1858 1859 if (!dpy || !config || !pixmap) 1860 return 0; 1861 1862 for (attr = attribList; attr && *attr; attr++) { 1863 switch (*attr) { 1864 case GLX_TEXTURE_FORMAT_EXT: 1865 attr++; 1866 switch (*attr) { 1867 case GLX_TEXTURE_FORMAT_NONE_EXT: 1868 case GLX_TEXTURE_FORMAT_RGB_EXT: 1869 case GLX_TEXTURE_FORMAT_RGBA_EXT: 1870 format = *attr; 1871 break; 1872 default: 1873 /* error */ 1874 return 0; 1875 } 1876 break; 1877 case GLX_TEXTURE_TARGET_EXT: 1878 attr++; 1879 switch (*attr) { 1880 case GLX_TEXTURE_1D_EXT: 1881 case GLX_TEXTURE_2D_EXT: 1882 case GLX_TEXTURE_RECTANGLE_EXT: 1883 target = *attr; 1884 break; 1885 default: 1886 /* error */ 1887 return 0; 1888 } 1889 break; 1890 case GLX_MIPMAP_TEXTURE_EXT: 1891 attr++; 1892 if (*attr) 1893 mipmap = 1; 1894 break; 1895 default: 1896 /* error */ 1897 return 0; 1898 } 1899 } 1900 1901 if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { 1902 if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, 1903 &value, GL_TRUE) != Success 1904 || !value) { 1905 return 0; /* error! */ 1906 } 1907 } 1908 else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { 1909 if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, 1910 &value, GL_TRUE) != Success 1911 || !value) { 1912 return 0; /* error! */ 1913 } 1914 } 1915 if (mipmap) { 1916 if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, 1917 &value, GL_TRUE) != Success 1918 || !value) { 1919 return 0; /* error! */ 1920 } 1921 } 1922 if (target == GLX_TEXTURE_1D_EXT) { 1923 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 1924 &value, GL_TRUE) != Success 1925 || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { 1926 return 0; /* error! */ 1927 } 1928 } 1929 else if (target == GLX_TEXTURE_2D_EXT) { 1930 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 1931 &value, GL_TRUE) != Success 1932 || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { 1933 return 0; /* error! */ 1934 } 1935 } 1936 if (target == GLX_TEXTURE_RECTANGLE_EXT) { 1937 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, 1938 &value, GL_TRUE) != Success 1939 || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { 1940 return 0; /* error! */ 1941 } 1942 } 1943 1944 if (format || target || mipmap) { 1945 /* texture from pixmap */ 1946 b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); 1947 } 1948 else { 1949 b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); 1950 } 1951 if (!b) { 1952 return 0; 1953 } 1954 1955 return pixmap; 1956} 1957 1958 1959void 1960glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) 1961{ 1962 XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap); 1963 if (b) 1964 XMesaDestroyBuffer(b); 1965 /* don't destroy X pixmap */ 1966} 1967 1968 1969GLXPbuffer 1970glXCreatePbuffer( Display *dpy, GLXFBConfig config, 1971 const int *attribList ) 1972{ 1973 XMesaVisual xmvis = (XMesaVisual) config; 1974 XMesaBuffer xmbuf; 1975 const int *attrib; 1976 int width = 0, height = 0; 1977 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 1978 1979 (void) dpy; 1980 1981 for (attrib = attribList; *attrib; attrib++) { 1982 switch (*attrib) { 1983 case GLX_PBUFFER_WIDTH: 1984 attrib++; 1985 width = *attrib; 1986 break; 1987 case GLX_PBUFFER_HEIGHT: 1988 attrib++; 1989 height = *attrib; 1990 break; 1991 case GLX_PRESERVED_CONTENTS: 1992 attrib++; 1993 preserveContents = *attrib; /* ignored */ 1994 break; 1995 case GLX_LARGEST_PBUFFER: 1996 attrib++; 1997 useLargest = *attrib; /* ignored */ 1998 break; 1999 default: 2000 return 0; 2001 } 2002 } 2003 2004 /* not used at this time */ 2005 (void) useLargest; 2006 (void) preserveContents; 2007 2008 if (width == 0 || height == 0) 2009 return 0; 2010 2011 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2012 /* A GLXPbuffer handle must be an X Drawable because that's what 2013 * glXMakeCurrent takes. 2014 */ 2015 if (xmbuf) 2016 return (GLXPbuffer) xmbuf->drawable; 2017 else 2018 return 0; 2019} 2020 2021 2022void 2023glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) 2024{ 2025 XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); 2026 if (b) { 2027 XMesaDestroyBuffer(b); 2028 } 2029} 2030 2031 2032void 2033glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, 2034 unsigned int *value ) 2035{ 2036 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); 2037 if (!xmbuf) 2038 return; 2039 2040 switch (attribute) { 2041 case GLX_WIDTH: 2042 *value = xmesa_buffer_width(xmbuf); 2043 break; 2044 case GLX_HEIGHT: 2045 *value = xmesa_buffer_width(xmbuf); 2046 break; 2047 case GLX_PRESERVED_CONTENTS: 2048 *value = True; 2049 break; 2050 case GLX_LARGEST_PBUFFER: 2051 *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); 2052 break; 2053 case GLX_FBCONFIG_ID: 2054 *value = xmbuf->xm_visual->visinfo->visualid; 2055 return; 2056#ifdef GLX_EXT_texture_from_pixmap 2057 case GLX_TEXTURE_FORMAT_EXT: 2058 *value = xmbuf->TextureFormat; 2059 break; 2060 case GLX_TEXTURE_TARGET_EXT: 2061 *value = xmbuf->TextureTarget; 2062 break; 2063 case GLX_MIPMAP_TEXTURE_EXT: 2064 *value = xmbuf->TextureMipmap; 2065 break; 2066#endif 2067 2068 default: 2069 return; /* raise BadValue error */ 2070 } 2071} 2072 2073 2074GLXContext 2075glXCreateNewContext( Display *dpy, GLXFBConfig config, 2076 int renderType, GLXContext shareList, Bool direct ) 2077{ 2078 GLXContext glxCtx; 2079 GLXContext shareCtx = shareList; 2080 XMesaVisual xmvis = (XMesaVisual) config; 2081 2082 if (!dpy || !config || 2083 (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) 2084 return 0; 2085 2086 glxCtx = CALLOC_STRUCT(__GLXcontextRec); 2087 if (!glxCtx) 2088 return 0; 2089 2090 /* deallocate unused windows/buffers */ 2091 XMesaGarbageCollect(); 2092 2093 glxCtx->xmesaContext = XMesaCreateContext(xmvis, 2094 shareCtx ? shareCtx->xmesaContext : NULL); 2095 if (!glxCtx->xmesaContext) { 2096 _mesa_free(glxCtx); 2097 return NULL; 2098 } 2099 2100 glxCtx->isDirect = DEFAULT_DIRECT; 2101 glxCtx->currentDpy = dpy; 2102 glxCtx->xid = (XID) glxCtx; /* self pointer */ 2103 2104 return glxCtx; 2105} 2106 2107 2108int 2109glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) 2110{ 2111 GLXContext glxCtx = ctx; 2112 XMesaContext xmctx = glxCtx->xmesaContext; 2113 2114 (void) dpy; 2115 (void) ctx; 2116 2117 switch (attribute) { 2118 case GLX_FBCONFIG_ID: 2119 *value = xmctx->xm_visual->visinfo->visualid; 2120 break; 2121 case GLX_RENDER_TYPE: 2122 if (xmctx->xm_visual->mesa_visual.rgbMode) 2123 *value = GLX_RGBA_TYPE; 2124 else 2125 *value = GLX_COLOR_INDEX_TYPE; 2126 break; 2127 case GLX_SCREEN: 2128 *value = 0; 2129 return Success; 2130 default: 2131 return GLX_BAD_ATTRIBUTE; 2132 } 2133 return 0; 2134} 2135 2136 2137void 2138glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) 2139{ 2140 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2141 if (xmbuf) 2142 xmbuf->selectedEvents = mask; 2143} 2144 2145 2146void 2147glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, 2148 unsigned long *mask ) 2149{ 2150 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2151 if (xmbuf) 2152 *mask = xmbuf->selectedEvents; 2153 else 2154 *mask = 0; 2155} 2156 2157 2158 2159/*** GLX_SGI_swap_control ***/ 2160 2161int 2162glXSwapIntervalSGI(int interval) 2163{ 2164 (void) interval; 2165 return 0; 2166} 2167 2168 2169 2170/*** GLX_SGI_video_sync ***/ 2171 2172static unsigned int FrameCounter = 0; 2173 2174int 2175glXGetVideoSyncSGI(unsigned int *count) 2176{ 2177 /* this is a bogus implementation */ 2178 *count = FrameCounter++; 2179 return 0; 2180} 2181 2182int 2183glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 2184{ 2185 if (divisor <= 0 || remainder < 0) 2186 return GLX_BAD_VALUE; 2187 /* this is a bogus implementation */ 2188 FrameCounter++; 2189 while (FrameCounter % divisor != remainder) 2190 FrameCounter++; 2191 *count = FrameCounter; 2192 return 0; 2193} 2194 2195 2196 2197/*** GLX_SGI_make_current_read ***/ 2198 2199Bool 2200glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) 2201{ 2202 return glXMakeContextCurrent( dpy, draw, read, ctx ); 2203} 2204 2205/* not used 2206static GLXDrawable 2207glXGetCurrentReadDrawableSGI(void) 2208{ 2209 return 0; 2210} 2211*/ 2212 2213 2214/*** GLX_SGIX_video_source ***/ 2215#if defined(_VL_H) 2216 2217GLXVideoSourceSGIX 2218glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) 2219{ 2220 (void) dpy; 2221 (void) screen; 2222 (void) server; 2223 (void) path; 2224 (void) nodeClass; 2225 (void) drainNode; 2226 return 0; 2227} 2228 2229void 2230glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) 2231{ 2232 (void) dpy; 2233 (void) src; 2234} 2235 2236#endif 2237 2238 2239/*** GLX_EXT_import_context ***/ 2240 2241void 2242glXFreeContextEXT(Display *dpy, GLXContext context) 2243{ 2244 (void) dpy; 2245 (void) context; 2246} 2247 2248GLXContextID 2249glXGetContextIDEXT(const GLXContext context) 2250{ 2251 (void) context; 2252 return 0; 2253} 2254 2255GLXContext 2256glXImportContextEXT(Display *dpy, GLXContextID contextID) 2257{ 2258 (void) dpy; 2259 (void) contextID; 2260 return 0; 2261} 2262 2263int 2264glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) 2265{ 2266 (void) dpy; 2267 (void) context; 2268 (void) attribute; 2269 (void) value; 2270 return 0; 2271} 2272 2273 2274 2275/*** GLX_SGIX_fbconfig ***/ 2276 2277int 2278glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) 2279{ 2280 return glXGetFBConfigAttrib(dpy, config, attribute, value); 2281} 2282 2283GLXFBConfigSGIX * 2284glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) 2285{ 2286 return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements); 2287} 2288 2289 2290GLXPixmap 2291glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) 2292{ 2293 XMesaVisual xmvis = (XMesaVisual) config; 2294 XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); 2295 return xmbuf->drawable; /* need to return an X ID */ 2296} 2297 2298 2299GLXContext 2300glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) 2301{ 2302 XMesaVisual xmvis = (XMesaVisual) config; 2303 GLXContext glxCtx; 2304 GLXContext shareCtx = share_list; 2305 2306 glxCtx = CALLOC_STRUCT(__GLXcontextRec); 2307 if (!glxCtx) 2308 return 0; 2309 2310 /* deallocate unused windows/buffers */ 2311 XMesaGarbageCollect(); 2312 2313 glxCtx->xmesaContext = XMesaCreateContext(xmvis, 2314 shareCtx ? shareCtx->xmesaContext : NULL); 2315 if (!glxCtx->xmesaContext) { 2316 _mesa_free(glxCtx); 2317 return NULL; 2318 } 2319 2320 glxCtx->isDirect = DEFAULT_DIRECT; 2321 glxCtx->currentDpy = dpy; 2322 glxCtx->xid = (XID) glxCtx; /* self pointer */ 2323 2324 return glxCtx; 2325} 2326 2327 2328XVisualInfo * 2329glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) 2330{ 2331 return glXGetVisualFromFBConfig(dpy, config); 2332} 2333 2334 2335GLXFBConfigSGIX 2336glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) 2337{ 2338 XMesaVisual xmvis = find_glx_visual(dpy, vis); 2339 if (!xmvis) { 2340 /* This visual wasn't found with glXChooseVisual() */ 2341 xmvis = create_glx_visual(dpy, vis); 2342 } 2343 2344 return (GLXFBConfigSGIX) xmvis; 2345} 2346 2347 2348 2349/*** GLX_SGIX_pbuffer ***/ 2350 2351GLXPbufferSGIX 2352glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, 2353 unsigned int width, unsigned int height, 2354 int *attribList) 2355{ 2356 XMesaVisual xmvis = (XMesaVisual) config; 2357 XMesaBuffer xmbuf; 2358 const int *attrib; 2359 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; 2360 2361 (void) dpy; 2362 2363 for (attrib = attribList; attrib && *attrib; attrib++) { 2364 switch (*attrib) { 2365 case GLX_PRESERVED_CONTENTS_SGIX: 2366 attrib++; 2367 preserveContents = *attrib; /* ignored */ 2368 break; 2369 case GLX_LARGEST_PBUFFER_SGIX: 2370 attrib++; 2371 useLargest = *attrib; /* ignored */ 2372 break; 2373 default: 2374 return 0; 2375 } 2376 } 2377 2378 /* not used at this time */ 2379 (void) useLargest; 2380 (void) preserveContents; 2381 2382 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); 2383 /* A GLXPbuffer handle must be an X Drawable because that's what 2384 * glXMakeCurrent takes. 2385 */ 2386 return (GLXPbuffer) xmbuf->drawable; 2387} 2388 2389 2390void 2391glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) 2392{ 2393 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2394 if (xmbuf) { 2395 XMesaDestroyBuffer(xmbuf); 2396 } 2397} 2398 2399 2400int 2401glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) 2402{ 2403 const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); 2404 2405 if (!xmbuf) { 2406 /* Generate GLXBadPbufferSGIX for bad pbuffer */ 2407 return 0; 2408 } 2409 2410 switch (attribute) { 2411 case GLX_PRESERVED_CONTENTS_SGIX: 2412 *value = True; 2413 break; 2414 case GLX_LARGEST_PBUFFER_SGIX: 2415 *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); 2416 break; 2417 case GLX_WIDTH_SGIX: 2418 *value = xmesa_buffer_width(xmbuf); 2419 break; 2420 case GLX_HEIGHT_SGIX: 2421 *value = xmesa_buffer_height(xmbuf); 2422 break; 2423 case GLX_EVENT_MASK_SGIX: 2424 *value = 0; /* XXX might be wrong */ 2425 break; 2426 default: 2427 *value = 0; 2428 } 2429 return 0; 2430} 2431 2432 2433void 2434glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) 2435{ 2436 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2437 if (xmbuf) { 2438 /* Note: we'll never generate clobber events */ 2439 xmbuf->selectedEvents = mask; 2440 } 2441} 2442 2443 2444void 2445glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) 2446{ 2447 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); 2448 if (xmbuf) { 2449 *mask = xmbuf->selectedEvents; 2450 } 2451 else { 2452 *mask = 0; 2453 } 2454} 2455 2456 2457 2458/*** GLX_SGI_cushion ***/ 2459 2460void 2461glXCushionSGI(Display *dpy, Window win, float cushion) 2462{ 2463 (void) dpy; 2464 (void) win; 2465 (void) cushion; 2466} 2467 2468 2469 2470/*** GLX_SGIX_video_resize ***/ 2471 2472int 2473glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) 2474{ 2475 (void) dpy; 2476 (void) screen; 2477 (void) channel; 2478 (void) window; 2479 return 0; 2480} 2481 2482int 2483glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) 2484{ 2485 (void) dpy; 2486 (void) screen; 2487 (void) channel; 2488 (void) x; 2489 (void) y; 2490 (void) w; 2491 (void) h; 2492 return 0; 2493} 2494 2495int 2496glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) 2497{ 2498 (void) dpy; 2499 (void) screen; 2500 (void) channel; 2501 (void) x; 2502 (void) y; 2503 (void) w; 2504 (void) h; 2505 return 0; 2506} 2507 2508int 2509glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) 2510{ 2511 (void) dpy; 2512 (void) screen; 2513 (void) channel; 2514 (void) dx; 2515 (void) dy; 2516 (void) dw; 2517 (void) dh; 2518 return 0; 2519} 2520 2521int 2522glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) 2523{ 2524 (void) dpy; 2525 (void) screen; 2526 (void) channel; 2527 (void) synctype; 2528 return 0; 2529} 2530 2531 2532 2533/*** GLX_SGIX_dmbuffer **/ 2534 2535#if defined(_DM_BUFFER_H_) 2536Bool 2537glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) 2538{ 2539 (void) dpy; 2540 (void) pbuffer; 2541 (void) params; 2542 (void) dmbuffer; 2543 return False; 2544} 2545#endif 2546 2547 2548/*** GLX_SGIX_swap_group ***/ 2549 2550void 2551glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) 2552{ 2553 (void) dpy; 2554 (void) drawable; 2555 (void) member; 2556} 2557 2558 2559 2560/*** GLX_SGIX_swap_barrier ***/ 2561 2562void 2563glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) 2564{ 2565 (void) dpy; 2566 (void) drawable; 2567 (void) barrier; 2568} 2569 2570Bool 2571glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) 2572{ 2573 (void) dpy; 2574 (void) screen; 2575 (void) max; 2576 return False; 2577} 2578 2579 2580 2581/*** GLX_SUN_get_transparent_index ***/ 2582 2583Status 2584glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) 2585{ 2586 (void) dpy; 2587 (void) overlay; 2588 (void) underlay; 2589 (void) pTransparent; 2590 return 0; 2591} 2592 2593 2594 2595/*** GLX_MESA_release_buffers ***/ 2596 2597/* 2598 * Release the depth, stencil, accum buffers attached to a GLXDrawable 2599 * (a window or pixmap) prior to destroying the GLXDrawable. 2600 */ 2601Bool 2602glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) 2603{ 2604 XMesaBuffer b = XMesaFindBuffer(dpy, d); 2605 if (b) { 2606 XMesaDestroyBuffer(b); 2607 return True; 2608 } 2609 return False; 2610} 2611 2612/*** GLX_EXT_texture_from_pixmap ***/ 2613 2614void 2615glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, 2616 const int *attrib_list) 2617{ 2618 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2619 if (b) 2620 XMesaBindTexImage(dpy, b, buffer, attrib_list); 2621} 2622 2623void 2624glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) 2625{ 2626 XMesaBuffer b = XMesaFindBuffer(dpy, drawable); 2627 if (b) 2628 XMesaReleaseTexImage(dpy, b, buffer); 2629} 2630