00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "glxheader.h"
00044 #include "glxapi.h"
00045 #include "GL/xmesa.h"
00046 #include "context.h"
00047 #include "config.h"
00048 #include "macros.h"
00049 #include "imports.h"
00050 #include "mtypes.h"
00051 #include "version.h"
00052 #include "xfonts.h"
00053 #include "xmesaP.h"
00054 #include "state_tracker/st_context.h"
00055 #include "state_tracker/st_public.h"
00056
00057
00058 #ifdef __VMS
00059 #define _mesa_sprintf sprintf
00060 #endif
00061
00062
00063 #define CLIENT_MAJOR_VERSION 1
00064 #define CLIENT_MINOR_VERSION 4
00065
00066
00067
00068
00069 #define SERVER_MAJOR_VERSION 1
00070 #define SERVER_MINOR_VERSION 4
00071
00072
00073 #define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING
00074
00075
00076 #define VENDOR "Brian Paul"
00077
00078 #define EXTENSIONS \
00079 "GLX_MESA_set_3dfx_mode " \
00080 "GLX_MESA_copy_sub_buffer " \
00081 "GLX_MESA_pixmap_colormap " \
00082 "GLX_MESA_release_buffers " \
00083 "GLX_ARB_get_proc_address " \
00084 "GLX_EXT_texture_from_pixmap " \
00085 "GLX_EXT_visual_info " \
00086 "GLX_EXT_visual_rating " \
00087 \
00088 "GLX_SGIX_fbconfig " \
00089 "GLX_SGIX_pbuffer "
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 struct fake_glx_context {
00102 __GLXcontext glxContext;
00103 XMesaContext xmesaContext;
00104 };
00105
00106
00107
00108
00109
00110
00111
00112 #define DONT_CARE -1
00113
00114
00115 static XMesaVisual *VisualTable = NULL;
00116 static int NumVisuals = 0;
00117
00118
00119
00120
00121
00122
00123 typedef struct _OverlayInfo {
00124
00125
00126
00127
00128 unsigned long overlay_visual;
00129 long transparent_type;
00130 long value;
00131 long layer;
00132 } OverlayInfo;
00133
00134
00135
00136
00137 #if defined(__cplusplus) || defined(c_plusplus)
00138 #define CLASS c_class
00139 #else
00140 #define CLASS class
00141 #endif
00142
00143
00144
00145
00146
00147
00148 static GLboolean
00149 is_usable_visual( XVisualInfo *vinfo )
00150 {
00151 switch (vinfo->CLASS) {
00152 case StaticGray:
00153 case GrayScale:
00154
00155 return GL_TRUE;
00156 case StaticColor:
00157 case PseudoColor:
00158
00159 if (vinfo->depth>=4) {
00160 return GL_TRUE;
00161 }
00162 else {
00163 return GL_FALSE;
00164 }
00165 case TrueColor:
00166 case DirectColor:
00167
00168 return GL_TRUE;
00169 default:
00170
00171 return GL_FALSE;
00172 }
00173 }
00174
00175
00176
00184 static OverlayInfo *
00185 GetOverlayInfo(Display *dpy, int screen, int *numOverlays)
00186 {
00187 Atom overlayVisualsAtom;
00188 Atom actualType;
00189 Status status;
00190 unsigned char *ovInfo;
00191 unsigned long sizeData, bytesLeft;
00192 int actualFormat;
00193
00194
00195
00196
00197
00198 overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
00199 if (overlayVisualsAtom == None) {
00200 return 0;
00201 }
00202
00203 status = XGetWindowProperty(dpy, RootWindow(dpy, screen),
00204 overlayVisualsAtom, 0L, (long) 10000, False,
00205 overlayVisualsAtom, &actualType, &actualFormat,
00206 &sizeData, &bytesLeft,
00207 &ovInfo);
00208
00209 if (status != Success || actualType != overlayVisualsAtom ||
00210 actualFormat != 32 || sizeData < 4) {
00211
00212 XFree((void *) ovInfo);
00213 *numOverlays = 0;
00214 return NULL;
00215 }
00216
00217 *numOverlays = sizeData / 4;
00218 return (OverlayInfo *) ovInfo;
00219 }
00220
00221
00222
00232 static int
00233 level_of_visual( Display *dpy, XVisualInfo *vinfo )
00234 {
00235 OverlayInfo *overlay_info;
00236 int numOverlaysPerScreen, i;
00237
00238 overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen);
00239 if (!overlay_info) {
00240 return 0;
00241 }
00242
00243
00244 for (i = 0; i < numOverlaysPerScreen; i++) {
00245 const OverlayInfo *ov = overlay_info + i;
00246 if (ov->overlay_visual == vinfo->visualid) {
00247
00248 if ( ov->layer!=0) {
00249 int level = ov->layer;
00250 XFree((void *) overlay_info);
00251 return level;
00252 }
00253 else {
00254 XFree((void *) overlay_info);
00255 return 0;
00256 }
00257 }
00258 }
00259
00260
00261 XFree((void *) overlay_info);
00262 return 0;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 static XMesaVisual
00273 save_glx_visual( Display *dpy, XVisualInfo *vinfo,
00274 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
00275 GLboolean stereoFlag,
00276 GLint depth_size, GLint stencil_size,
00277 GLint accumRedSize, GLint accumGreenSize,
00278 GLint accumBlueSize, GLint accumAlphaSize,
00279 GLint level, GLint numAuxBuffers )
00280 {
00281 GLboolean ximageFlag = GL_TRUE;
00282 XMesaVisual xmvis;
00283 GLint i;
00284 GLboolean comparePointers;
00285
00286 if (dbFlag) {
00287
00288 char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER");
00289 if (backbuffer) {
00290 if (backbuffer[0]=='p' || backbuffer[0]=='P') {
00291 ximageFlag = GL_FALSE;
00292 }
00293 else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
00294 ximageFlag = GL_TRUE;
00295 }
00296 else {
00297 _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
00298 }
00299 }
00300 }
00301
00302 if (stereoFlag) {
00303
00304 return NULL;
00305 }
00306
00307 if (stencil_size > 0 && depth_size > 0)
00308 depth_size = 24;
00309
00310
00311
00312 if (_mesa_getenv("MESA_GLX_VISUAL_HACK"))
00313 comparePointers = GL_TRUE;
00314 else
00315 comparePointers = GL_FALSE;
00316
00317
00318 if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA"))
00319 alphaFlag = GL_TRUE;
00320
00321
00322 for (i=0; i<NumVisuals; i++) {
00323 XMesaVisual v = VisualTable[i];
00324 if (v->display == dpy
00325 && v->mesa_visual.level == level
00326 && v->mesa_visual.numAuxBuffers == numAuxBuffers
00327 && v->ximage_flag == ximageFlag
00328 && v->mesa_visual.rgbMode == rgbFlag
00329 && v->mesa_visual.doubleBufferMode == dbFlag
00330 && v->mesa_visual.stereoMode == stereoFlag
00331 && (v->mesa_visual.alphaBits > 0) == alphaFlag
00332 && (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
00333 && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
00334 && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
00335 && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
00336 && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
00337 && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
00338
00339 if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
00340 || (comparePointers && v->vishandle == vinfo)) {
00341 return v;
00342 }
00343 }
00344 }
00345
00346
00347
00348 xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
00349 stereoFlag, ximageFlag,
00350 depth_size, stencil_size,
00351 accumRedSize, accumBlueSize,
00352 accumBlueSize, accumAlphaSize, 0, level,
00353 GLX_NONE_EXT );
00354 if (xmvis) {
00355
00356
00357
00358 xmvis->vishandle = vinfo;
00359
00360 VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable,
00361 sizeof(XMesaVisual) * NumVisuals,
00362 sizeof(XMesaVisual) * (NumVisuals + 1));
00363
00364 VisualTable[NumVisuals] = xmvis;
00365 NumVisuals++;
00366
00367
00368
00369 xmvis->mesa_visual.numAuxBuffers = numAuxBuffers;
00370 }
00371 return xmvis;
00372 }
00373
00374
00381 static GLint
00382 default_depth_bits(void)
00383 {
00384 int zBits;
00385 const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
00386 if (zEnv)
00387 zBits = _mesa_atoi(zEnv);
00388 else
00389 zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
00390 return zBits;
00391 }
00392
00393 static GLint
00394 default_alpha_bits(void)
00395 {
00396 int aBits;
00397 const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
00398 if (aEnv)
00399 aBits = _mesa_atoi(aEnv);
00400 else
00401 aBits = 0;
00402 return aBits;
00403 }
00404
00405 static GLint
00406 default_accum_bits(void)
00407 {
00408 return 16;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 static XMesaVisual
00422 create_glx_visual( Display *dpy, XVisualInfo *visinfo )
00423 {
00424 int vislevel;
00425 GLint zBits = default_depth_bits();
00426 GLint accBits = default_accum_bits();
00427 GLboolean alphaFlag = default_alpha_bits() > 0;
00428
00429 vislevel = level_of_visual( dpy, visinfo );
00430 if (vislevel) {
00431
00432 return save_glx_visual( dpy, visinfo,
00433 GL_FALSE,
00434 GL_FALSE,
00435 GL_FALSE,
00436 GL_FALSE,
00437 0,
00438 0,
00439 0,0,0,0,
00440 vislevel,
00441 0
00442 );
00443 }
00444 else if (is_usable_visual( visinfo )) {
00445 if (_mesa_getenv("MESA_GLX_FORCE_CI")) {
00446
00447 return save_glx_visual( dpy, visinfo,
00448 GL_FALSE,
00449 GL_FALSE,
00450 GL_TRUE,
00451 GL_FALSE,
00452 zBits,
00453 STENCIL_BITS,
00454 0, 0, 0, 0,
00455 0,
00456 0
00457 );
00458 }
00459 else {
00460
00461
00462
00463 return save_glx_visual( dpy, visinfo,
00464 GL_TRUE,
00465 alphaFlag,
00466 GL_TRUE,
00467 GL_FALSE,
00468 zBits,
00469 STENCIL_BITS,
00470 accBits,
00471 accBits,
00472 accBits,
00473 accBits,
00474 0,
00475 0
00476 );
00477 }
00478 }
00479 else {
00480 _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
00481 return NULL;
00482 }
00483 }
00484
00485
00486
00487
00488
00489
00490 static XMesaVisual
00491 find_glx_visual( Display *dpy, XVisualInfo *vinfo )
00492 {
00493 int i;
00494
00495
00496 for (i=0;i<NumVisuals;i++) {
00497 if (VisualTable[i]->display==dpy
00498 && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
00499 return VisualTable[i];
00500 }
00501 }
00502
00503
00504 for (i=0;i<NumVisuals;i++) {
00505 if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
00506 return VisualTable[i];
00507 }
00508 }
00509
00510 return NULL;
00511 }
00512
00513
00514
00520 static int
00521 transparent_pixel( XMesaVisual glxvis )
00522 {
00523 Display *dpy = glxvis->display;
00524 XVisualInfo *vinfo = glxvis->visinfo;
00525 OverlayInfo *overlay_info;
00526 int numOverlaysPerScreen, i;
00527
00528 overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen);
00529 if (!overlay_info) {
00530 return -1;
00531 }
00532
00533 for (i = 0; i < numOverlaysPerScreen; i++) {
00534 const OverlayInfo *ov = overlay_info + i;
00535 if (ov->overlay_visual == vinfo->visualid) {
00536
00537 if (ov->transparent_type == 0) {
00538
00539 XFree((void *) overlay_info);
00540 return -1;
00541 }
00542 else {
00543
00544 XFree((void *) overlay_info);
00545 return ov->value;
00546 }
00547 }
00548 }
00549
00550
00551 XFree((void *) overlay_info);
00552 return -1;
00553 }
00554
00555
00556
00560 static XVisualInfo *
00561 get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
00562 {
00563 XVisualInfo temp, *vis;
00564 long mask;
00565 int n;
00566 unsigned int default_depth;
00567 int default_class;
00568
00569 mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
00570 temp.screen = scr;
00571 temp.depth = depth;
00572 temp.CLASS = xclass;
00573
00574 default_depth = DefaultDepth(dpy,scr);
00575 default_class = DefaultVisual(dpy,scr)->CLASS;
00576
00577 if (depth==default_depth && xclass==default_class) {
00578
00579 temp.visualid = DefaultVisual(dpy,scr)->visualid;
00580 mask |= VisualIDMask;
00581 }
00582
00583 vis = XGetVisualInfo( dpy, mask, &temp, &n );
00584
00585
00586
00587
00588
00589 if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
00590 if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 &&
00591 _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
00592 _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
00593 return vis;
00594 }
00595 else {
00596 XFree((void *) vis);
00597 return NULL;
00598 }
00599 }
00600
00601 return vis;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 static XVisualInfo *
00615 get_env_visual(Display *dpy, int scr, const char *varname)
00616 {
00617 char value[100], type[100];
00618 int depth, xclass = -1;
00619 XVisualInfo *vis;
00620
00621 if (!_mesa_getenv( varname )) {
00622 return NULL;
00623 }
00624
00625 _mesa_strncpy( value, _mesa_getenv(varname), 100 );
00626 value[99] = 0;
00627
00628 sscanf( value, "%s %d", type, &depth );
00629
00630 if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor;
00631 else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor;
00632 else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
00633 else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor;
00634 else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale;
00635 else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray;
00636
00637 if (xclass>-1 && depth>0) {
00638 vis = get_visual( dpy, scr, depth, xclass );
00639 if (vis) {
00640 return vis;
00641 }
00642 }
00643
00644 _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
00645 type, depth);
00646
00647 return NULL;
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 static XVisualInfo *
00661 choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth,
00662 int preferred_class )
00663 {
00664 XVisualInfo *vis;
00665 int xclass, visclass = 0;
00666 int depth;
00667
00668 if (rgba) {
00669 Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
00670
00671 vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
00672 if (vis) {
00673 return vis;
00674 }
00675
00676 if (preferred_class==DONT_CARE) {
00677 for (xclass=0;xclass<6;xclass++) {
00678 switch (xclass) {
00679 case 0: visclass = TrueColor; break;
00680 case 1: visclass = DirectColor; break;
00681 case 2: visclass = PseudoColor; break;
00682 case 3: visclass = StaticColor; break;
00683 case 4: visclass = GrayScale; break;
00684 case 5: visclass = StaticGray; break;
00685 }
00686 if (min_depth==0) {
00687
00688 for (depth=0;depth<=32;depth++) {
00689 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
00690
00691
00692 vis = get_visual( dpy, screen, 8, PseudoColor );
00693 if (vis) {
00694 return vis;
00695 }
00696 }
00697 vis = get_visual( dpy, screen, depth, visclass );
00698 if (vis) {
00699 return vis;
00700 }
00701 }
00702 }
00703 else {
00704
00705 for (depth=32;depth>=min_depth;depth--) {
00706 if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
00707
00708
00709 vis = get_visual( dpy, screen, 8, PseudoColor );
00710 if (vis) {
00711 return vis;
00712 }
00713 }
00714 vis = get_visual( dpy, screen, depth, visclass );
00715 if (vis) {
00716 return vis;
00717 }
00718 }
00719 }
00720 }
00721 }
00722 else {
00723
00724 switch (preferred_class) {
00725 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
00726 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
00727 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
00728 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
00729 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
00730 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
00731 default: return NULL;
00732 }
00733 if (min_depth==0) {
00734
00735 for (depth=0;depth<=32;depth++) {
00736 vis = get_visual( dpy, screen, depth, visclass );
00737 if (vis) {
00738 return vis;
00739 }
00740 }
00741 }
00742 else {
00743
00744 for (depth=32;depth>=min_depth;depth--) {
00745 vis = get_visual( dpy, screen, depth, visclass );
00746 if (vis) {
00747 return vis;
00748 }
00749 }
00750 }
00751 }
00752 }
00753 else {
00754
00755 vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
00756 if (vis) {
00757 return vis;
00758 }
00759
00760 if (preferred_class==DONT_CARE) {
00761 for (xclass=0;xclass<4;xclass++) {
00762 switch (xclass) {
00763 case 0: visclass = PseudoColor; break;
00764 case 1: visclass = StaticColor; break;
00765 case 2: visclass = GrayScale; break;
00766 case 3: visclass = StaticGray; break;
00767 }
00768
00769 for (depth=8;depth<=16;depth++) {
00770 vis = get_visual( dpy, screen, depth, visclass );
00771 if (vis) {
00772 return vis;
00773 }
00774 }
00775
00776 for (depth=min_depth;depth<8;depth++) {
00777 vis = get_visual( dpy, screen, depth, visclass );
00778 if (vis) {
00779 return vis;
00780 }
00781 }
00782 }
00783 }
00784 else {
00785
00786 switch (preferred_class) {
00787 case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break;
00788 case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break;
00789 case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break;
00790 case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break;
00791 case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break;
00792 case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break;
00793 default: return NULL;
00794 }
00795
00796 for (depth=8;depth<=16;depth++) {
00797 vis = get_visual( dpy, screen, depth, visclass );
00798 if (vis) {
00799 return vis;
00800 }
00801 }
00802
00803 for (depth=min_depth;depth<8;depth++) {
00804 vis = get_visual( dpy, screen, depth, visclass );
00805 if (vis) {
00806 return vis;
00807 }
00808 }
00809 }
00810 }
00811
00812
00813 return NULL;
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 static XVisualInfo *
00831 choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag,
00832 int level, int trans_type, int trans_value,
00833 int min_depth, int preferred_class )
00834 {
00835 OverlayInfo *overlay_info;
00836 int numOverlaysPerScreen;
00837 int i;
00838 XVisualInfo *deepvis;
00839 int deepest;
00840
00841
00842
00843 switch (preferred_class) {
00844 case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break;
00845 case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break;
00846 case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break;
00847 case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break;
00848 case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break;
00849 case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break;
00850 default: preferred_class = DONT_CARE;
00851 }
00852
00853 overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen);
00854 if (!overlay_info) {
00855 return NULL;
00856 }
00857
00858
00859 deepest = min_depth;
00860 deepvis = NULL;
00861
00862 for (i = 0; i < numOverlaysPerScreen; i++) {
00863 const OverlayInfo *ov = overlay_info + i;
00864 XVisualInfo *vislist, vistemplate;
00865 int count;
00866
00867 if (ov->layer!=level) {
00868
00869 continue;
00870 }
00871 if (!(trans_type==DONT_CARE
00872 || (trans_type==GLX_TRANSPARENT_INDEX_EXT
00873 && ov->transparent_type>0)
00874 || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
00875
00876 continue;
00877 }
00878 if (trans_value!=DONT_CARE && trans_value!=ov->value) {
00879
00880 continue;
00881 }
00882
00883
00884 vistemplate.visualid = ov->overlay_visual;
00885 vistemplate.screen = scr;
00886 vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
00887 &vistemplate, &count );
00888
00889 if (count!=1) {
00890
00891 continue;
00892 }
00893 if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
00894
00895 continue;
00896 }
00897
00898
00899 if (rgbFlag && vislist->CLASS != TrueColor
00900 && vislist->CLASS != DirectColor)
00901 continue;
00902
00903
00904 if (!rgbFlag
00905 && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor))
00906 continue;
00907
00908 if (deepvis==NULL || vislist->depth > deepest) {
00909
00910 if (deepvis) {
00911 XFree( deepvis );
00912 }
00913 deepest = vislist->depth;
00914 deepvis = vislist;
00915
00916
00917 }
00918 }
00919
00920
00921
00922
00923
00924
00925
00926 return deepvis;
00927 }
00928
00929
00930
00931
00932
00933
00934
00938 static void
00939 destroy_visuals_on_display(Display *dpy)
00940 {
00941 int i;
00942 for (i = 0; i < NumVisuals; i++) {
00943 if (VisualTable[i]->display == dpy) {
00944
00945 int j;
00946 free(VisualTable[i]);
00947 for (j = i; j < NumVisuals - 1; j++)
00948 VisualTable[j] = VisualTable[j + 1];
00949 NumVisuals--;
00950 }
00951 }
00952 }
00953
00954
00958 static int
00959 close_display_callback(Display *dpy, XExtCodes *codes)
00960 {
00961 destroy_visuals_on_display(dpy);
00962 xmesa_destroy_buffers_on_display(dpy);
00963 return 0;
00964 }
00965
00966
00971 static _XExtension *
00972 lookup_extension(Display *dpy, const char *extName)
00973 {
00974 _XExtension *ext;
00975 for (ext = dpy->ext_procs; ext; ext = ext->next) {
00976 if (ext->name && strcmp(ext->name, extName) == 0) {
00977 return ext;
00978 }
00979 }
00980 return NULL;
00981 }
00982
00983
00988 static void
00989 register_with_display(Display *dpy)
00990 {
00991 const char *extName = "MesaGLX";
00992 _XExtension *ext;
00993
00994 ext = lookup_extension(dpy, extName);
00995 if (!ext) {
00996 XExtCodes *c = XAddExtension(dpy);
00997 ext = dpy->ext_procs;
00998 assert(c->extension == ext->codes.extension);
00999 ext->name = _mesa_strdup(extName);
01000 ext->close_display = close_display_callback;
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01016 static XMesaVisual
01017 choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
01018 {
01019 const GLboolean rgbModeDefault = fbConfig;
01020 const int *parselist;
01021 XVisualInfo *vis;
01022 int min_ci = 0;
01023 int min_red=0, min_green=0, min_blue=0;
01024 GLboolean rgb_flag = rgbModeDefault;
01025 GLboolean alpha_flag = GL_FALSE;
01026 GLboolean double_flag = GL_FALSE;
01027 GLboolean stereo_flag = GL_FALSE;
01028 GLint depth_size = 0;
01029 GLint stencil_size = 0;
01030 GLint accumRedSize = 0;
01031 GLint accumGreenSize = 0;
01032 GLint accumBlueSize = 0;
01033 GLint accumAlphaSize = 0;
01034 int level = 0;
01035 int visual_type = DONT_CARE;
01036 int trans_type = DONT_CARE;
01037 int trans_value = DONT_CARE;
01038 GLint caveat = DONT_CARE;
01039 XMesaVisual xmvis = NULL;
01040 int desiredVisualID = -1;
01041 int numAux = 0;
01042
01043 parselist = list;
01044
01045 while (*parselist) {
01046
01047 switch (*parselist) {
01048 case GLX_USE_GL:
01049 if (fbConfig) {
01050
01051 return NULL;
01052 }
01053 else {
01054
01055 parselist++;
01056 }
01057 break;
01058 case GLX_BUFFER_SIZE:
01059 parselist++;
01060 min_ci = *parselist++;
01061 break;
01062 case GLX_LEVEL:
01063 parselist++;
01064 level = *parselist++;
01065 break;
01066 case GLX_RGBA:
01067 if (fbConfig) {
01068
01069 return NULL;
01070 }
01071 else {
01072 rgb_flag = GL_TRUE;
01073 parselist++;
01074 }
01075 break;
01076 case GLX_DOUBLEBUFFER:
01077 parselist++;
01078 if (fbConfig) {
01079 double_flag = *parselist++;
01080 }
01081 else {
01082 double_flag = GL_TRUE;
01083 }
01084 break;
01085 case GLX_STEREO:
01086 parselist++;
01087 if (fbConfig) {
01088 stereo_flag = *parselist++;
01089 }
01090 else {
01091 stereo_flag = GL_TRUE;
01092 }
01093 break;
01094 case GLX_AUX_BUFFERS:
01095 parselist++;
01096 numAux = *parselist++;
01097 if (numAux > MAX_AUX_BUFFERS)
01098 return NULL;
01099 break;
01100 case GLX_RED_SIZE:
01101 parselist++;
01102 min_red = *parselist++;
01103 break;
01104 case GLX_GREEN_SIZE:
01105 parselist++;
01106 min_green = *parselist++;
01107 break;
01108 case GLX_BLUE_SIZE:
01109 parselist++;
01110 min_blue = *parselist++;
01111 break;
01112 case GLX_ALPHA_SIZE:
01113 parselist++;
01114 {
01115 GLint size = *parselist++;
01116 alpha_flag = size ? GL_TRUE : GL_FALSE;
01117 }
01118 break;
01119 case GLX_DEPTH_SIZE:
01120 parselist++;
01121 depth_size = *parselist++;
01122 break;
01123 case GLX_STENCIL_SIZE:
01124 parselist++;
01125 stencil_size = *parselist++;
01126 break;
01127 case GLX_ACCUM_RED_SIZE:
01128 parselist++;
01129 {
01130 GLint size = *parselist++;
01131 accumRedSize = MAX2( accumRedSize, size );
01132 }
01133 break;
01134 case GLX_ACCUM_GREEN_SIZE:
01135 parselist++;
01136 {
01137 GLint size = *parselist++;
01138 accumGreenSize = MAX2( accumGreenSize, size );
01139 }
01140 break;
01141 case GLX_ACCUM_BLUE_SIZE:
01142 parselist++;
01143 {
01144 GLint size = *parselist++;
01145 accumBlueSize = MAX2( accumBlueSize, size );
01146 }
01147 break;
01148 case GLX_ACCUM_ALPHA_SIZE:
01149 parselist++;
01150 {
01151 GLint size = *parselist++;
01152 accumAlphaSize = MAX2( accumAlphaSize, size );
01153 }
01154 break;
01155
01156
01157
01158
01159 case GLX_X_VISUAL_TYPE_EXT:
01160 parselist++;
01161 visual_type = *parselist++;
01162 break;
01163 case GLX_TRANSPARENT_TYPE_EXT:
01164 parselist++;
01165 trans_type = *parselist++;
01166 break;
01167 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
01168 parselist++;
01169 trans_value = *parselist++;
01170 break;
01171 case GLX_TRANSPARENT_RED_VALUE_EXT:
01172 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
01173 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
01174 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
01175
01176 parselist++;
01177 parselist++;
01178 break;
01179
01180
01181
01182
01183 case GLX_VISUAL_CAVEAT_EXT:
01184 parselist++;
01185 caveat = *parselist++;
01186 break;
01187
01188
01189
01190
01191 case GLX_SAMPLE_BUFFERS_ARB:
01192
01193 return NULL;
01194 case GLX_SAMPLES_ARB:
01195
01196 return NULL;
01197
01198
01199
01200
01201 case GLX_RENDER_TYPE:
01202 if (!fbConfig)
01203 return NULL;
01204 parselist++;
01205 if (*parselist == GLX_RGBA_BIT) {
01206 rgb_flag = GL_TRUE;
01207 }
01208 else if (*parselist == GLX_COLOR_INDEX_BIT) {
01209 rgb_flag = GL_FALSE;
01210 }
01211 else if (*parselist == 0) {
01212 rgb_flag = GL_TRUE;
01213 }
01214 parselist++;
01215 break;
01216 case GLX_DRAWABLE_TYPE:
01217 if (!fbConfig)
01218 return NULL;
01219 parselist++;
01220 if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
01221 return NULL;
01222 }
01223 parselist++;
01224 break;
01225 case GLX_FBCONFIG_ID:
01226 if (!fbConfig)
01227 return NULL;
01228 parselist++;
01229 desiredVisualID = *parselist++;
01230 break;
01231 case GLX_X_RENDERABLE:
01232 if (!fbConfig)
01233 return NULL;
01234 parselist += 2;
01235
01236 break;
01237
01238 #ifdef GLX_EXT_texture_from_pixmap
01239 case GLX_BIND_TO_TEXTURE_RGB_EXT:
01240 parselist++;
01241 break;
01242 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
01243 parselist++;
01244 break;
01245 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
01246 parselist++;
01247 break;
01248 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
01249 parselist++;
01250 if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
01251 GLX_TEXTURE_2D_BIT_EXT |
01252 GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
01253
01254 return NULL;
01255 }
01256 break;
01257 case GLX_Y_INVERTED_EXT:
01258 parselist++;
01259 break;
01260 #endif
01261
01262 case None:
01263
01264 break;
01265
01266 default:
01267
01268 _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
01269 *parselist);
01270 return NULL;
01271 }
01272 }
01273
01274 (void) caveat;
01275
01276
01277
01278
01279
01280
01281
01282
01283 if (desiredVisualID != -1) {
01284
01285 XVisualInfo temp;
01286 int n;
01287 temp.visualid = desiredVisualID;
01288 temp.screen = screen;
01289 vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
01290 if (vis) {
01291
01292 double_flag = GL_TRUE;
01293 if (vis->depth > 8)
01294 rgb_flag = GL_TRUE;
01295 depth_size = default_depth_bits();
01296 stencil_size = STENCIL_BITS;
01297
01298 }
01299 }
01300 else if (level==0) {
01301
01302 if (rgb_flag) {
01303
01304 int min_rgb = min_red + min_green + min_blue;
01305 if (min_rgb>1 && min_rgb<8) {
01306
01307 min_rgb = 1;
01308 }
01309 vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
01310 }
01311 else {
01312
01313 vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
01314 accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0;
01315 }
01316 }
01317 else {
01318
01319 if (rgb_flag) {
01320
01321 int min_rgb = min_red + min_green + min_blue;
01322 if (min_rgb>1 && min_rgb<8) {
01323
01324 min_rgb = 1;
01325 }
01326 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
01327 trans_type, trans_value, min_rgb, visual_type );
01328 }
01329 else {
01330
01331 vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
01332 trans_type, trans_value, min_ci, visual_type );
01333 }
01334 }
01335
01336 if (vis) {
01337
01338
01339
01340
01341
01342 if (stencil_size > 0)
01343 depth_size = 24;
01344 else if (depth_size > 24)
01345 depth_size = 32;
01346 else if (depth_size > 16)
01347 depth_size = 24;
01348 else if (depth_size > 0) {
01349 depth_size = default_depth_bits();
01350 }
01351
01352 if (!alpha_flag) {
01353 alpha_flag = default_alpha_bits() > 0;
01354 }
01355
01356
01357 if (stencil_size > 0)
01358 stencil_size = STENCIL_BITS;
01359 if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
01360 accumAlphaSize > 0) {
01361 accumRedSize =
01362 accumGreenSize =
01363 accumBlueSize = default_accum_bits();
01364 accumAlphaSize = alpha_flag ? accumRedSize : 0;
01365 }
01366
01367 xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
01368 stereo_flag, depth_size, stencil_size,
01369 accumRedSize, accumGreenSize,
01370 accumBlueSize, accumAlphaSize, level, numAux );
01371 }
01372
01373 return xmvis;
01374 }
01375
01376
01377 static XVisualInfo *
01378 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
01379 {
01380 XMesaVisual xmvis;
01381
01382
01383 register_with_display(dpy);
01384
01385 xmvis = choose_visual(dpy, screen, list, GL_FALSE);
01386 if (xmvis) {
01387 #if 0
01388 return xmvis->vishandle;
01389 #else
01390
01391 xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
01392 if (xmvis->vishandle) {
01393 _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
01394 }
01395 return xmvis->vishandle;
01396 #endif
01397 }
01398 else
01399 return NULL;
01400 }
01401
01402
01403 static GLXContext
01404 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
01405 GLXContext share_list, Bool direct )
01406 {
01407 XMesaVisual xmvis;
01408 struct fake_glx_context *glxCtx;
01409 struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
01410
01411 if (!dpy || !visinfo)
01412 return 0;
01413
01414 glxCtx = CALLOC_STRUCT(fake_glx_context);
01415 if (!glxCtx)
01416 return 0;
01417
01418
01419 #if 0
01420 XMesaGarbageCollect();
01421 #endif
01422
01423 xmvis = find_glx_visual( dpy, visinfo );
01424 if (!xmvis) {
01425
01426 xmvis = create_glx_visual( dpy, visinfo );
01427 if (!xmvis) {
01428
01429 _mesa_free(glxCtx);
01430 return NULL;
01431 }
01432 }
01433
01434 glxCtx->xmesaContext = XMesaCreateContext(xmvis,
01435 shareCtx ? shareCtx->xmesaContext : NULL);
01436 if (!glxCtx->xmesaContext) {
01437 _mesa_free(glxCtx);
01438 return NULL;
01439 }
01440
01441 glxCtx->glxContext.isDirect = GL_FALSE;
01442 glxCtx->glxContext.currentDpy = dpy;
01443 glxCtx->glxContext.xid = (XID) glxCtx;
01444
01445 assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
01446
01447 return (GLXContext) glxCtx;
01448 }
01449
01450
01451
01452 static GLXContext MakeCurrent_PrevContext = 0;
01453 static GLXDrawable MakeCurrent_PrevDrawable = 0;
01454 static GLXDrawable MakeCurrent_PrevReadable = 0;
01455 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
01456 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
01457
01458
01459
01460 static Bool
01461 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
01462 GLXDrawable read, GLXContext ctx )
01463 {
01464 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
01465 static boolean firsttime = 1, no_rast = 0;
01466
01467 if (firsttime) {
01468 no_rast = getenv("SP_NO_RAST") != NULL;
01469 firsttime = 0;
01470 }
01471
01472
01473 if (ctx && draw && read) {
01474 XMesaBuffer drawBuffer, readBuffer;
01475 XMesaContext xmctx = glxCtx->xmesaContext;
01476
01477
01478 if (ctx == MakeCurrent_PrevContext
01479 && draw == MakeCurrent_PrevDrawable) {
01480 drawBuffer = MakeCurrent_PrevDrawBuffer;
01481 }
01482 else {
01483 drawBuffer = XMesaFindBuffer( dpy, draw );
01484 }
01485 if (!drawBuffer) {
01486
01487 drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
01488 if (!drawBuffer) {
01489
01490 return False;
01491 }
01492 #ifdef FX
01493 FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer );
01494 #endif
01495 }
01496
01497
01498 if (ctx == MakeCurrent_PrevContext
01499 && read == MakeCurrent_PrevReadable) {
01500 readBuffer = MakeCurrent_PrevReadBuffer;
01501 }
01502 else {
01503 readBuffer = XMesaFindBuffer( dpy, read );
01504 }
01505 if (!readBuffer) {
01506
01507 readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
01508 if (!readBuffer) {
01509
01510 return False;
01511 }
01512 #ifdef FX
01513 FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer );
01514 #endif
01515 }
01516
01517 if (no_rast &&
01518 MakeCurrent_PrevContext == ctx &&
01519 MakeCurrent_PrevDrawable == draw &&
01520 MakeCurrent_PrevReadable == read &&
01521 MakeCurrent_PrevDrawBuffer == drawBuffer &&
01522 MakeCurrent_PrevReadBuffer == readBuffer)
01523 return True;
01524
01525 MakeCurrent_PrevContext = ctx;
01526 MakeCurrent_PrevDrawable = draw;
01527 MakeCurrent_PrevReadable = read;
01528 MakeCurrent_PrevDrawBuffer = drawBuffer;
01529 MakeCurrent_PrevReadBuffer = readBuffer;
01530
01531
01532 if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
01533 ((__GLXcontext *) ctx)->currentDpy = dpy;
01534 ((__GLXcontext *) ctx)->currentDrawable = draw;
01535 ((__GLXcontext *) ctx)->currentReadable = read;
01536 return True;
01537 }
01538 else {
01539 return False;
01540 }
01541 }
01542 else if (!ctx && !draw && !read) {
01543
01544 XMesaMakeCurrent( NULL, NULL );
01545 MakeCurrent_PrevContext = 0;
01546 MakeCurrent_PrevDrawable = 0;
01547 MakeCurrent_PrevReadable = 0;
01548 MakeCurrent_PrevDrawBuffer = 0;
01549 MakeCurrent_PrevReadBuffer = 0;
01550 return True;
01551 }
01552 else {
01553
01554
01555
01556 return False;
01557 }
01558 }
01559
01560
01561 static Bool
01562 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
01563 {
01564 return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
01565 }
01566
01567
01568 static GLXPixmap
01569 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
01570 {
01571 XMesaVisual v;
01572 XMesaBuffer b;
01573
01574 v = find_glx_visual( dpy, visinfo );
01575 if (!v) {
01576 v = create_glx_visual( dpy, visinfo );
01577 if (!v) {
01578
01579 return 0;
01580 }
01581 }
01582
01583 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
01584 if (!b) {
01585 return 0;
01586 }
01587 return b->drawable;
01588 }
01589
01590
01591
01592
01593 static GLXPixmap
01594 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
01595 Pixmap pixmap, Colormap cmap )
01596 {
01597 XMesaVisual v;
01598 XMesaBuffer b;
01599
01600 v = find_glx_visual( dpy, visinfo );
01601 if (!v) {
01602 v = create_glx_visual( dpy, visinfo );
01603 if (!v) {
01604
01605 return 0;
01606 }
01607 }
01608
01609 b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
01610 if (!b) {
01611 return 0;
01612 }
01613 return b->drawable;
01614 }
01615
01616
01617 static void
01618 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
01619 {
01620 XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
01621 if (b) {
01622 XMesaDestroyBuffer(b);
01623 }
01624 else if (_mesa_getenv("MESA_DEBUG")) {
01625 _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
01626 }
01627 }
01628
01629
01630 static void
01631 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
01632 unsigned long mask )
01633 {
01634 struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src;
01635 struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst;
01636 XMesaContext xm_src = fakeSrc->xmesaContext;
01637 XMesaContext xm_dst = fakeDst->xmesaContext;
01638 (void) dpy;
01639 if (MakeCurrent_PrevContext == src) {
01640 _mesa_Flush();
01641 }
01642 st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
01643 }
01644
01645
01646 static Bool
01647 Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
01648 {
01649
01650 (void) dpy;
01651 (void) errorb;
01652 (void) event;
01653 return True;
01654 }
01655
01656
01657 extern void _kw_ungrab_all( Display *dpy );
01658 void _kw_ungrab_all( Display *dpy )
01659 {
01660 XUngrabPointer( dpy, CurrentTime );
01661 XUngrabKeyboard( dpy, CurrentTime );
01662 }
01663
01664
01665 static void
01666 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
01667 {
01668 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
01669 (void) dpy;
01670 MakeCurrent_PrevContext = 0;
01671 MakeCurrent_PrevDrawable = 0;
01672 MakeCurrent_PrevReadable = 0;
01673 MakeCurrent_PrevDrawBuffer = 0;
01674 MakeCurrent_PrevReadBuffer = 0;
01675 XMesaDestroyContext( glxCtx->xmesaContext );
01676 XMesaGarbageCollect();
01677 _mesa_free(glxCtx);
01678 }
01679
01680
01681 static Bool
01682 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
01683 {
01684 (void) dpy;
01685 (void) ctx;
01686 return False;
01687 }
01688
01689
01690
01691 static void
01692 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
01693 {
01694 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
01695 static boolean firsttime = 1, no_rast = 0;
01696
01697 if (firsttime) {
01698 no_rast = getenv("SP_NO_RAST") != NULL;
01699 firsttime = 0;
01700 }
01701
01702 if (no_rast)
01703 return;
01704
01705 if (buffer) {
01706 XMesaSwapBuffers(buffer);
01707 }
01708 else if (_mesa_getenv("MESA_DEBUG")) {
01709 _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
01710 (int) drawable);
01711 }
01712 }
01713
01714
01715
01716
01717
01718 static void
01719 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
01720 int x, int y, int width, int height )
01721 {
01722 XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
01723 if (buffer) {
01724 XMesaCopySubBuffer(buffer, x, y, width, height);
01725 }
01726 else if (_mesa_getenv("MESA_DEBUG")) {
01727 _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
01728 }
01729 }
01730
01731
01732 static Bool
01733 Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
01734 {
01735 (void) dpy;
01736
01737 assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
01738 *maj = CLIENT_MAJOR_VERSION;
01739 *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
01740 return True;
01741 }
01742
01743
01744
01745
01746
01747 static int
01748 get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
01749 {
01750 ASSERT(xmvis);
01751 switch(attrib) {
01752 case GLX_USE_GL:
01753 if (fbconfig)
01754 return GLX_BAD_ATTRIBUTE;
01755 *value = (int) True;
01756 return 0;
01757 case GLX_BUFFER_SIZE:
01758 *value = xmvis->visinfo->depth;
01759 return 0;
01760 case GLX_LEVEL:
01761 *value = xmvis->mesa_visual.level;
01762 return 0;
01763 case GLX_RGBA:
01764 if (fbconfig)
01765 return GLX_BAD_ATTRIBUTE;
01766 if (xmvis->mesa_visual.rgbMode) {
01767 *value = True;
01768 }
01769 else {
01770 *value = False;
01771 }
01772 return 0;
01773 case GLX_DOUBLEBUFFER:
01774 *value = (int) xmvis->mesa_visual.doubleBufferMode;
01775 return 0;
01776 case GLX_STEREO:
01777 *value = (int) xmvis->mesa_visual.stereoMode;
01778 return 0;
01779 case GLX_AUX_BUFFERS:
01780 *value = xmvis->mesa_visual.numAuxBuffers;
01781 return 0;
01782 case GLX_RED_SIZE:
01783 *value = xmvis->mesa_visual.redBits;
01784 return 0;
01785 case GLX_GREEN_SIZE:
01786 *value = xmvis->mesa_visual.greenBits;
01787 return 0;
01788 case GLX_BLUE_SIZE:
01789 *value = xmvis->mesa_visual.blueBits;
01790 return 0;
01791 case GLX_ALPHA_SIZE:
01792 *value = xmvis->mesa_visual.alphaBits;
01793 return 0;
01794 case GLX_DEPTH_SIZE:
01795 *value = xmvis->mesa_visual.depthBits;
01796 return 0;
01797 case GLX_STENCIL_SIZE:
01798 *value = xmvis->mesa_visual.stencilBits;
01799 return 0;
01800 case GLX_ACCUM_RED_SIZE:
01801 *value = xmvis->mesa_visual.accumRedBits;
01802 return 0;
01803 case GLX_ACCUM_GREEN_SIZE:
01804 *value = xmvis->mesa_visual.accumGreenBits;
01805 return 0;
01806 case GLX_ACCUM_BLUE_SIZE:
01807 *value = xmvis->mesa_visual.accumBlueBits;
01808 return 0;
01809 case GLX_ACCUM_ALPHA_SIZE:
01810 *value = xmvis->mesa_visual.accumAlphaBits;
01811 return 0;
01812
01813
01814
01815
01816 case GLX_X_VISUAL_TYPE_EXT:
01817 switch (xmvis->visinfo->CLASS) {
01818 case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0;
01819 case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0;
01820 case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0;
01821 case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0;
01822 case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0;
01823 case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0;
01824 }
01825 return 0;
01826 case GLX_TRANSPARENT_TYPE_EXT:
01827 if (xmvis->mesa_visual.level==0) {
01828
01829 *value = GLX_NONE_EXT;
01830 }
01831 else if (xmvis->mesa_visual.level>0) {
01832
01833 if (xmvis->mesa_visual.rgbMode) {
01834 *value = GLX_TRANSPARENT_RGB_EXT;
01835 }
01836 else {
01837 *value = GLX_TRANSPARENT_INDEX_EXT;
01838 }
01839 }
01840 else if (xmvis->mesa_visual.level<0) {
01841
01842 *value = GLX_NONE_EXT;
01843 }
01844 return 0;
01845 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
01846 {
01847 int pixel = transparent_pixel( xmvis );
01848 if (pixel>=0) {
01849 *value = pixel;
01850 }
01851
01852 }
01853 return 0;
01854 case GLX_TRANSPARENT_RED_VALUE_EXT:
01855
01856 return 0;
01857 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
01858
01859 return 0;
01860 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
01861
01862 return 0;
01863 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
01864
01865 return 0;
01866
01867
01868
01869
01870 case GLX_VISUAL_CAVEAT_EXT:
01871
01872 if (xmvis->mesa_visual.visualRating > 0)
01873 *value = xmvis->mesa_visual.visualRating;
01874 else
01875 *value = GLX_NONE_EXT;
01876 return 0;
01877
01878
01879
01880
01881 case GLX_SAMPLE_BUFFERS_ARB:
01882 *value = 0;
01883 return 0;
01884 case GLX_SAMPLES_ARB:
01885 *value = 0;
01886 return 0;
01887
01888
01889
01890
01891 case GLX_SCREEN_EXT:
01892 if (!fbconfig)
01893 return GLX_BAD_ATTRIBUTE;
01894 *value = xmvis->visinfo->screen;
01895 break;
01896 case GLX_DRAWABLE_TYPE:
01897 if (!fbconfig)
01898 return GLX_BAD_ATTRIBUTE;
01899 *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
01900 break;
01901 case GLX_RENDER_TYPE_SGIX:
01902 if (!fbconfig)
01903 return GLX_BAD_ATTRIBUTE;
01904 if (xmvis->mesa_visual.rgbMode)
01905 *value = GLX_RGBA_BIT;
01906 else
01907 *value = GLX_COLOR_INDEX_BIT;
01908 break;
01909 case GLX_X_RENDERABLE_SGIX:
01910 if (!fbconfig)
01911 return GLX_BAD_ATTRIBUTE;
01912 *value = True;
01913 break;
01914 case GLX_FBCONFIG_ID_SGIX:
01915 if (!fbconfig)
01916 return GLX_BAD_ATTRIBUTE;
01917 *value = xmvis->visinfo->visualid;
01918 break;
01919 case GLX_MAX_PBUFFER_WIDTH:
01920 if (!fbconfig)
01921 return GLX_BAD_ATTRIBUTE;
01922
01923 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
01924 break;
01925 case GLX_MAX_PBUFFER_HEIGHT:
01926 if (!fbconfig)
01927 return GLX_BAD_ATTRIBUTE;
01928 *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
01929 break;
01930 case GLX_MAX_PBUFFER_PIXELS:
01931 if (!fbconfig)
01932 return GLX_BAD_ATTRIBUTE;
01933 *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
01934 DisplayHeight(xmvis->display, xmvis->visinfo->screen);
01935 break;
01936 case GLX_VISUAL_ID:
01937 if (!fbconfig)
01938 return GLX_BAD_ATTRIBUTE;
01939 *value = xmvis->visinfo->visualid;
01940 break;
01941
01942 #ifdef GLX_EXT_texture_from_pixmap
01943 case GLX_BIND_TO_TEXTURE_RGB_EXT:
01944 *value = True;
01945 break;
01946 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
01947
01948 *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
01949 break;
01950 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
01951 *value = True;
01952 break;
01953 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
01954 *value = (GLX_TEXTURE_1D_BIT_EXT |
01955 GLX_TEXTURE_2D_BIT_EXT |
01956 GLX_TEXTURE_RECTANGLE_BIT_EXT);
01957 break;
01958 case GLX_Y_INVERTED_EXT:
01959 *value = True;
01960 break;
01961 #endif
01962
01963 default:
01964 return GLX_BAD_ATTRIBUTE;
01965 }
01966 return Success;
01967 }
01968
01969
01970 static int
01971 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
01972 int attrib, int *value )
01973 {
01974 XMesaVisual xmvis;
01975 int k;
01976 if (!dpy || !visinfo)
01977 return GLX_BAD_ATTRIBUTE;
01978
01979 xmvis = find_glx_visual( dpy, visinfo );
01980 if (!xmvis) {
01981
01982 xmvis = create_glx_visual( dpy, visinfo );
01983 if (!xmvis) {
01984
01985 if (attrib==GLX_USE_GL) {
01986 *value = (int) False;
01987 return 0;
01988 }
01989 else {
01990 return GLX_BAD_VISUAL;
01991 }
01992 }
01993 }
01994
01995 k = get_config(xmvis, attrib, value, GL_FALSE);
01996 return k;
01997 }
01998
01999
02000 static void
02001 Fake_glXWaitGL( void )
02002 {
02003 XMesaContext xmesa = XMesaGetCurrentContext();
02004 XMesaFlush( xmesa );
02005 }
02006
02007
02008
02009 static void
02010 Fake_glXWaitX( void )
02011 {
02012 XMesaContext xmesa = XMesaGetCurrentContext();
02013 XMesaFlush( xmesa );
02014 }
02015
02016
02017 static const char *
02018 get_extensions( void )
02019 {
02020 #ifdef FX
02021 const char *fx = _mesa_getenv("MESA_GLX_FX");
02022 if (fx && fx[0] != 'd') {
02023 return EXTENSIONS;
02024 }
02025 #endif
02026 return EXTENSIONS + 23;
02027 }
02028
02029
02030
02031
02032 static const char *
02033 Fake_glXQueryExtensionsString( Display *dpy, int screen )
02034 {
02035 (void) dpy;
02036 (void) screen;
02037 return get_extensions();
02038 }
02039
02040
02041
02042
02043 static const char *
02044 Fake_glXQueryServerString( Display *dpy, int screen, int name )
02045 {
02046 static char version[1000];
02047 _mesa_sprintf(version, "%d.%d %s",
02048 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
02049
02050 (void) dpy;
02051 (void) screen;
02052
02053 switch (name) {
02054 case GLX_EXTENSIONS:
02055 return get_extensions();
02056 case GLX_VENDOR:
02057 return VENDOR;
02058 case GLX_VERSION:
02059 return version;
02060 default:
02061 return NULL;
02062 }
02063 }
02064
02065
02066
02067
02068 static const char *
02069 Fake_glXGetClientString( Display *dpy, int name )
02070 {
02071 static char version[1000];
02072 _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
02073 CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
02074
02075 (void) dpy;
02076
02077 switch (name) {
02078 case GLX_EXTENSIONS:
02079 return get_extensions();
02080 case GLX_VENDOR:
02081 return VENDOR;
02082 case GLX_VERSION:
02083 return version;
02084 default:
02085 return NULL;
02086 }
02087 }
02088
02089
02090
02091
02092
02093
02094
02095
02096 static int
02097 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
02098 int attribute, int *value )
02099 {
02100 XMesaVisual v = (XMesaVisual) config;
02101 (void) dpy;
02102 (void) config;
02103
02104 if (!dpy || !config || !value)
02105 return -1;
02106
02107 return get_config(v, attribute, value, GL_TRUE);
02108 }
02109
02110
02111 static GLXFBConfig *
02112 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
02113 {
02114 XVisualInfo *visuals, visTemplate;
02115 const long visMask = VisualScreenMask;
02116 int i;
02117
02118
02119 visTemplate.screen = screen;
02120 visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
02121 if (*nelements > 0) {
02122 XMesaVisual *results;
02123 results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual));
02124 if (!results) {
02125 *nelements = 0;
02126 return NULL;
02127 }
02128 for (i = 0; i < *nelements; i++) {
02129 results[i] = create_glx_visual(dpy, visuals + i);
02130 }
02131 return (GLXFBConfig *) results;
02132 }
02133 return NULL;
02134 }
02135
02136
02137 static GLXFBConfig *
02138 Fake_glXChooseFBConfig( Display *dpy, int screen,
02139 const int *attribList, int *nitems )
02140 {
02141 XMesaVisual xmvis;
02142
02143 if (!attribList || !attribList[0]) {
02144
02145 return Fake_glXGetFBConfigs(dpy, screen, nitems);
02146 }
02147
02148 xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
02149 if (xmvis) {
02150 GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual));
02151 if (!config) {
02152 *nitems = 0;
02153 return NULL;
02154 }
02155 *nitems = 1;
02156 config[0] = (GLXFBConfig) xmvis;
02157 return (GLXFBConfig *) config;
02158 }
02159 else {
02160 *nitems = 0;
02161 return NULL;
02162 }
02163 }
02164
02165
02166 static XVisualInfo *
02167 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
02168 {
02169 if (dpy && config) {
02170 XMesaVisual xmvis = (XMesaVisual) config;
02171 #if 0
02172 return xmvis->vishandle;
02173 #else
02174
02175 xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
02176 if (xmvis->vishandle) {
02177 _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
02178 }
02179 return xmvis->vishandle;
02180 #endif
02181 }
02182 else {
02183 return NULL;
02184 }
02185 }
02186
02187
02188 static GLXWindow
02189 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
02190 const int *attribList )
02191 {
02192 XMesaVisual xmvis = (XMesaVisual) config;
02193 XMesaBuffer xmbuf;
02194 if (!xmvis)
02195 return 0;
02196
02197 xmbuf = XMesaCreateWindowBuffer(xmvis, win);
02198 if (!xmbuf)
02199 return 0;
02200
02201 #ifdef FX
02202
02203 FXcreateContext(xmvis, win, NULL, xmbuf);
02204 #endif
02205
02206 (void) dpy;
02207 (void) attribList;
02208
02209 return win;
02210 }
02211
02212
02213 static void
02214 Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
02215 {
02216 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window);
02217 if (b)
02218 XMesaDestroyBuffer(b);
02219
02220 }
02221
02222
02223
02224 static GLXPixmap
02225 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
02226 const int *attribList )
02227 {
02228 XMesaVisual v = (XMesaVisual) config;
02229 XMesaBuffer b;
02230 const int *attr;
02231 int target = 0, format = 0, mipmap = 0;
02232 int value;
02233
02234 if (!dpy || !config || !pixmap)
02235 return 0;
02236
02237 for (attr = attribList; *attr; attr++) {
02238 switch (*attr) {
02239 case GLX_TEXTURE_FORMAT_EXT:
02240 attr++;
02241 switch (*attr) {
02242 case GLX_TEXTURE_FORMAT_NONE_EXT:
02243 case GLX_TEXTURE_FORMAT_RGB_EXT:
02244 case GLX_TEXTURE_FORMAT_RGBA_EXT:
02245 format = *attr;
02246 break;
02247 default:
02248
02249 return 0;
02250 }
02251 break;
02252 case GLX_TEXTURE_TARGET_EXT:
02253 attr++;
02254 switch (*attr) {
02255 case GLX_TEXTURE_1D_EXT:
02256 case GLX_TEXTURE_2D_EXT:
02257 case GLX_TEXTURE_RECTANGLE_EXT:
02258 target = *attr;
02259 break;
02260 default:
02261
02262 return 0;
02263 }
02264 break;
02265 case GLX_MIPMAP_TEXTURE_EXT:
02266 attr++;
02267 if (*attr)
02268 mipmap = 1;
02269 break;
02270 default:
02271
02272 return 0;
02273 }
02274 }
02275
02276 if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
02277 if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
02278 &value, GL_TRUE) != Success
02279 || !value) {
02280 return 0;
02281 }
02282 }
02283 else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
02284 if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
02285 &value, GL_TRUE) != Success
02286 || !value) {
02287 return 0;
02288 }
02289 }
02290 if (mipmap) {
02291 if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
02292 &value, GL_TRUE) != Success
02293 || !value) {
02294 return 0;
02295 }
02296 }
02297 if (target == GLX_TEXTURE_1D_EXT) {
02298 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
02299 &value, GL_TRUE) != Success
02300 || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
02301 return 0;
02302 }
02303 }
02304 else if (target == GLX_TEXTURE_2D_EXT) {
02305 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
02306 &value, GL_TRUE) != Success
02307 || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
02308 return 0;
02309 }
02310 }
02311 if (target == GLX_TEXTURE_RECTANGLE_EXT) {
02312 if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
02313 &value, GL_TRUE) != Success
02314 || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
02315 return 0;
02316 }
02317 }
02318
02319 if (format || target || mipmap) {
02320
02321 b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
02322 }
02323 else {
02324 b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
02325 }
02326 if (!b) {
02327 return 0;
02328 }
02329
02330 return pixmap;
02331 }
02332
02333
02334 static void
02335 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
02336 {
02337 XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap);
02338 if (b)
02339 XMesaDestroyBuffer(b);
02340
02341 }
02342
02343
02344 static GLXPbuffer
02345 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
02346 const int *attribList )
02347 {
02348 XMesaVisual xmvis = (XMesaVisual) config;
02349 XMesaBuffer xmbuf;
02350 const int *attrib;
02351 int width = 0, height = 0;
02352 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
02353
02354 (void) dpy;
02355
02356 for (attrib = attribList; *attrib; attrib++) {
02357 switch (*attrib) {
02358 case GLX_PBUFFER_WIDTH:
02359 attrib++;
02360 width = *attrib;
02361 break;
02362 case GLX_PBUFFER_HEIGHT:
02363 attrib++;
02364 height = *attrib;
02365 break;
02366 case GLX_PRESERVED_CONTENTS:
02367 attrib++;
02368 preserveContents = *attrib;
02369 break;
02370 case GLX_LARGEST_PBUFFER:
02371 attrib++;
02372 useLargest = *attrib;
02373 break;
02374 default:
02375 return 0;
02376 }
02377 }
02378
02379
02380 (void) useLargest;
02381 (void) preserveContents;
02382
02383 if (width == 0 || height == 0)
02384 return 0;
02385
02386 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
02387
02388
02389
02390 if (xmbuf)
02391 return (GLXPbuffer) xmbuf->drawable;
02392 else
02393 return 0;
02394 }
02395
02396
02397 static void
02398 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
02399 {
02400 XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
02401 if (b) {
02402 XMesaDestroyBuffer(b);
02403 }
02404 }
02405
02406
02407 static void
02408 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
02409 unsigned int *value )
02410 {
02411 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
02412 if (!xmbuf)
02413 return;
02414
02415 switch (attribute) {
02416 case GLX_WIDTH:
02417 *value = xmesa_buffer_width(xmbuf);
02418 break;
02419 case GLX_HEIGHT:
02420 *value = xmesa_buffer_width(xmbuf);
02421 break;
02422 case GLX_PRESERVED_CONTENTS:
02423 *value = True;
02424 break;
02425 case GLX_LARGEST_PBUFFER:
02426 *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
02427 break;
02428 case GLX_FBCONFIG_ID:
02429 *value = xmbuf->xm_visual->visinfo->visualid;
02430 return;
02431 #ifdef GLX_EXT_texture_from_pixmap
02432 case GLX_TEXTURE_FORMAT_EXT:
02433 *value = xmbuf->TextureFormat;
02434 break;
02435 case GLX_TEXTURE_TARGET_EXT:
02436 *value = xmbuf->TextureTarget;
02437 break;
02438 case GLX_MIPMAP_TEXTURE_EXT:
02439 *value = xmbuf->TextureMipmap;
02440 break;
02441 #endif
02442
02443 default:
02444 return;
02445 }
02446 }
02447
02448
02449 static GLXContext
02450 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
02451 int renderType, GLXContext shareList, Bool direct )
02452 {
02453 struct fake_glx_context *glxCtx;
02454 struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList;
02455 XMesaVisual xmvis = (XMesaVisual) config;
02456
02457 if (!dpy || !config ||
02458 (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
02459 return 0;
02460
02461 glxCtx = CALLOC_STRUCT(fake_glx_context);
02462 if (!glxCtx)
02463 return 0;
02464
02465
02466 XMesaGarbageCollect();
02467
02468 glxCtx->xmesaContext = XMesaCreateContext(xmvis,
02469 shareCtx ? shareCtx->xmesaContext : NULL);
02470 if (!glxCtx->xmesaContext) {
02471 _mesa_free(glxCtx);
02472 return NULL;
02473 }
02474
02475 glxCtx->glxContext.isDirect = GL_FALSE;
02476 glxCtx->glxContext.currentDpy = dpy;
02477 glxCtx->glxContext.xid = (XID) glxCtx;
02478
02479 assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
02480
02481 return (GLXContext) glxCtx;
02482 }
02483
02484
02485 static int
02486 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
02487 {
02488 struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
02489 XMesaContext xmctx = glxCtx->xmesaContext;
02490
02491 (void) dpy;
02492 (void) ctx;
02493
02494 switch (attribute) {
02495 case GLX_FBCONFIG_ID:
02496 *value = xmctx->xm_visual->visinfo->visualid;
02497 break;
02498 case GLX_RENDER_TYPE:
02499 if (xmctx->xm_visual->mesa_visual.rgbMode)
02500 *value = GLX_RGBA_BIT;
02501 else
02502 *value = GLX_COLOR_INDEX_BIT;
02503 break;
02504 case GLX_SCREEN:
02505 *value = 0;
02506 return Success;
02507 default:
02508 return GLX_BAD_ATTRIBUTE;
02509 }
02510 return 0;
02511 }
02512
02513
02514 static void
02515 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
02516 {
02517 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
02518 if (xmbuf)
02519 xmbuf->selectedEvents = mask;
02520 }
02521
02522
02523 static void
02524 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
02525 unsigned long *mask )
02526 {
02527 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
02528 if (xmbuf)
02529 *mask = xmbuf->selectedEvents;
02530 else
02531 *mask = 0;
02532 }
02533
02534
02535
02536
02537
02538 static int
02539 Fake_glXSwapIntervalSGI(int interval)
02540 {
02541 (void) interval;
02542 return 0;
02543 }
02544
02545
02546
02547
02548
02549 static unsigned int FrameCounter = 0;
02550
02551 static int
02552 Fake_glXGetVideoSyncSGI(unsigned int *count)
02553 {
02554
02555 *count = FrameCounter++;
02556 return 0;
02557 }
02558
02559 static int
02560 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
02561 {
02562 if (divisor <= 0 || remainder < 0)
02563 return GLX_BAD_VALUE;
02564
02565 FrameCounter++;
02566 while (FrameCounter % divisor != remainder)
02567 FrameCounter++;
02568 *count = FrameCounter;
02569 return 0;
02570 }
02571
02572
02573
02574
02575
02576 static Bool
02577 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
02578 {
02579 return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
02580 }
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592 #if defined(_VL_H)
02593
02594 static GLXVideoSourceSGIX
02595 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
02596 {
02597 (void) dpy;
02598 (void) screen;
02599 (void) server;
02600 (void) path;
02601 (void) nodeClass;
02602 (void) drainNode;
02603 return 0;
02604 }
02605
02606 static void
02607 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
02608 {
02609 (void) dpy;
02610 (void) src;
02611 }
02612
02613 #endif
02614
02615
02616
02617
02618 static void
02619 Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
02620 {
02621 (void) dpy;
02622 (void) context;
02623 }
02624
02625 static GLXContextID
02626 Fake_glXGetContextIDEXT(const GLXContext context)
02627 {
02628 (void) context;
02629 return 0;
02630 }
02631
02632 static GLXContext
02633 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
02634 {
02635 (void) dpy;
02636 (void) contextID;
02637 return 0;
02638 }
02639
02640 static int
02641 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
02642 {
02643 (void) dpy;
02644 (void) context;
02645 (void) attribute;
02646 (void) value;
02647 return 0;
02648 }
02649
02650
02651
02652
02653
02654 static int
02655 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
02656 {
02657 return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value);
02658 }
02659
02660 static GLXFBConfigSGIX *
02661 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
02662 {
02663 return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements);
02664 }
02665
02666
02667 static GLXPixmap
02668 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
02669 {
02670 XMesaVisual xmvis = (XMesaVisual) config;
02671 XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
02672 return xmbuf->drawable;
02673 }
02674
02675
02676 static GLXContext
02677 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
02678 {
02679 XMesaVisual xmvis = (XMesaVisual) config;
02680 struct fake_glx_context *glxCtx;
02681 struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
02682
02683 glxCtx = CALLOC_STRUCT(fake_glx_context);
02684 if (!glxCtx)
02685 return 0;
02686
02687
02688 XMesaGarbageCollect();
02689
02690 glxCtx->xmesaContext = XMesaCreateContext(xmvis,
02691 shareCtx ? shareCtx->xmesaContext : NULL);
02692 if (!glxCtx->xmesaContext) {
02693 _mesa_free(glxCtx);
02694 return NULL;
02695 }
02696
02697 glxCtx->glxContext.isDirect = GL_FALSE;
02698 glxCtx->glxContext.currentDpy = dpy;
02699 glxCtx->glxContext.xid = (XID) glxCtx;
02700
02701 assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
02702
02703 return (GLXContext) glxCtx;
02704 }
02705
02706
02707 static XVisualInfo *
02708 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
02709 {
02710 return Fake_glXGetVisualFromFBConfig(dpy, config);
02711 }
02712
02713
02714 static GLXFBConfigSGIX
02715 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
02716 {
02717 XMesaVisual xmvis = find_glx_visual(dpy, vis);
02718 if (!xmvis) {
02719
02720 xmvis = create_glx_visual(dpy, vis);
02721 }
02722
02723 return (GLXFBConfigSGIX) xmvis;
02724 }
02725
02726
02727
02728
02729
02730 static GLXPbufferSGIX
02731 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
02732 unsigned int width, unsigned int height,
02733 int *attribList)
02734 {
02735 XMesaVisual xmvis = (XMesaVisual) config;
02736 XMesaBuffer xmbuf;
02737 const int *attrib;
02738 GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
02739
02740 (void) dpy;
02741
02742 for (attrib = attribList; attrib && *attrib; attrib++) {
02743 switch (*attrib) {
02744 case GLX_PRESERVED_CONTENTS_SGIX:
02745 attrib++;
02746 preserveContents = *attrib;
02747 break;
02748 case GLX_LARGEST_PBUFFER_SGIX:
02749 attrib++;
02750 useLargest = *attrib;
02751 break;
02752 default:
02753 return 0;
02754 }
02755 }
02756
02757
02758 (void) useLargest;
02759 (void) preserveContents;
02760
02761 xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
02762
02763
02764
02765 return (GLXPbuffer) xmbuf->drawable;
02766 }
02767
02768
02769 static void
02770 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
02771 {
02772 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
02773 if (xmbuf) {
02774 XMesaDestroyBuffer(xmbuf);
02775 }
02776 }
02777
02778
02779 static int
02780 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
02781 {
02782 const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
02783
02784 if (!xmbuf) {
02785
02786 return 0;
02787 }
02788
02789 switch (attribute) {
02790 case GLX_PRESERVED_CONTENTS_SGIX:
02791 *value = True;
02792 break;
02793 case GLX_LARGEST_PBUFFER_SGIX:
02794 *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
02795 break;
02796 case GLX_WIDTH_SGIX:
02797 *value = xmesa_buffer_width(xmbuf);
02798 break;
02799 case GLX_HEIGHT_SGIX:
02800 *value = xmesa_buffer_height(xmbuf);
02801 break;
02802 case GLX_EVENT_MASK_SGIX:
02803 *value = 0;
02804 break;
02805 default:
02806 *value = 0;
02807 }
02808 return 0;
02809 }
02810
02811
02812 static void
02813 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
02814 {
02815 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
02816 if (xmbuf) {
02817
02818 xmbuf->selectedEvents = mask;
02819 }
02820 }
02821
02822
02823 static void
02824 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
02825 {
02826 XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
02827 if (xmbuf) {
02828 *mask = xmbuf->selectedEvents;
02829 }
02830 else {
02831 *mask = 0;
02832 }
02833 }
02834
02835
02836
02837
02838
02839 static void
02840 Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
02841 {
02842 (void) dpy;
02843 (void) win;
02844 (void) cushion;
02845 }
02846
02847
02848
02849
02850
02851 static int
02852 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
02853 {
02854 (void) dpy;
02855 (void) screen;
02856 (void) channel;
02857 (void) window;
02858 return 0;
02859 }
02860
02861 static int
02862 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
02863 {
02864 (void) dpy;
02865 (void) screen;
02866 (void) channel;
02867 (void) x;
02868 (void) y;
02869 (void) w;
02870 (void) h;
02871 return 0;
02872 }
02873
02874 static int
02875 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
02876 {
02877 (void) dpy;
02878 (void) screen;
02879 (void) channel;
02880 (void) x;
02881 (void) y;
02882 (void) w;
02883 (void) h;
02884 return 0;
02885 }
02886
02887 static int
02888 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
02889 {
02890 (void) dpy;
02891 (void) screen;
02892 (void) channel;
02893 (void) dx;
02894 (void) dy;
02895 (void) dw;
02896 (void) dh;
02897 return 0;
02898 }
02899
02900 static int
02901 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
02902 {
02903 (void) dpy;
02904 (void) screen;
02905 (void) channel;
02906 (void) synctype;
02907 return 0;
02908 }
02909
02910
02911
02912
02913
02914 #if defined(_DM_BUFFER_H_)
02915 static Bool
02916 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
02917 {
02918 (void) dpy;
02919 (void) pbuffer;
02920 (void) params;
02921 (void) dmbuffer;
02922 return False;
02923 }
02924 #endif
02925
02926
02927
02928
02929 static void
02930 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
02931 {
02932 (void) dpy;
02933 (void) drawable;
02934 (void) member;
02935 }
02936
02937
02938
02939
02940
02941 static void
02942 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
02943 {
02944 (void) dpy;
02945 (void) drawable;
02946 (void) barrier;
02947 }
02948
02949 static Bool
02950 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
02951 {
02952 (void) dpy;
02953 (void) screen;
02954 (void) max;
02955 return False;
02956 }
02957
02958
02959
02960
02961
02962 static Status
02963 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
02964 {
02965 (void) dpy;
02966 (void) overlay;
02967 (void) underlay;
02968 (void) pTransparent;
02969 return 0;
02970 }
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980 static Bool
02981 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
02982 {
02983 XMesaBuffer b = XMesaFindBuffer(dpy, d);
02984 if (b) {
02985 XMesaDestroyBuffer(b);
02986 return True;
02987 }
02988 return False;
02989 }
02990
02991
02992
02993
02994
02995 static Bool
02996 Fake_glXSet3DfxModeMESA( int mode )
02997 {
02998 return XMesaSetFXmode( mode );
02999 }
03000
03001
03002
03003
03004 static void *
03005 Fake_glXAllocateMemoryNV( GLsizei size,
03006 GLfloat readFrequency,
03007 GLfloat writeFrequency,
03008 GLfloat priority )
03009 {
03010 (void) size;
03011 (void) readFrequency;
03012 (void) writeFrequency;
03013 (void) priority;
03014 return NULL;
03015 }
03016
03017
03018 static void
03019 Fake_glXFreeMemoryNV( GLvoid *pointer )
03020 {
03021 (void) pointer;
03022 }
03023
03024
03025
03026
03027 static GLuint
03028 Fake_glXGetAGPOffsetMESA( const GLvoid *pointer )
03029 {
03030 (void) pointer;
03031 return ~0;
03032 }
03033
03034
03035
03036
03037 static void
03038 Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
03039 const int *attrib_list)
03040 {
03041 XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
03042 if (b)
03043 XMesaBindTexImage(dpy, b, buffer, attrib_list);
03044 }
03045
03046 static void
03047 Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
03048 {
03049 XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
03050 if (b)
03051 XMesaReleaseTexImage(dpy, b, buffer);
03052 }
03053
03054
03055
03056 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
03057
03058
03066 struct _glxapi_table *
03067 _mesa_GetGLXDispatchTable(void)
03068 {
03069 static struct _glxapi_table glx;
03070
03071
03072 {
03073 GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
03074 (void) size;
03075 assert(_glxapi_get_dispatch_table_size() >= size);
03076 }
03077
03078
03079 _glxapi_set_no_op_table(&glx);
03080
03081
03082 glx.ChooseVisual = Fake_glXChooseVisual;
03083 glx.CopyContext = Fake_glXCopyContext;
03084 glx.CreateContext = Fake_glXCreateContext;
03085 glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
03086 glx.DestroyContext = Fake_glXDestroyContext;
03087 glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
03088 glx.GetConfig = Fake_glXGetConfig;
03089
03090
03091 glx.IsDirect = Fake_glXIsDirect;
03092 glx.MakeCurrent = Fake_glXMakeCurrent;
03093 glx.QueryExtension = Fake_glXQueryExtension;
03094 glx.QueryVersion = Fake_glXQueryVersion;
03095 glx.SwapBuffers = Fake_glXSwapBuffers;
03096 glx.UseXFont = Fake_glXUseXFont;
03097 glx.WaitGL = Fake_glXWaitGL;
03098 glx.WaitX = Fake_glXWaitX;
03099
03100
03101 glx.GetClientString = Fake_glXGetClientString;
03102 glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
03103 glx.QueryServerString = Fake_glXQueryServerString;
03104
03105
03106
03107
03108
03109 glx.ChooseFBConfig = Fake_glXChooseFBConfig;
03110 glx.CreateNewContext = Fake_glXCreateNewContext;
03111 glx.CreatePbuffer = Fake_glXCreatePbuffer;
03112 glx.CreatePixmap = Fake_glXCreatePixmap;
03113 glx.CreateWindow = Fake_glXCreateWindow;
03114 glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
03115 glx.DestroyPixmap = Fake_glXDestroyPixmap;
03116 glx.DestroyWindow = Fake_glXDestroyWindow;
03117
03118 glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
03119 glx.GetFBConfigs = Fake_glXGetFBConfigs;
03120 glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
03121 glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
03122 glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
03123 glx.QueryContext = Fake_glXQueryContext;
03124 glx.QueryDrawable = Fake_glXQueryDrawable;
03125 glx.SelectEvent = Fake_glXSelectEvent;
03126
03127
03128 glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
03129
03130
03131 glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
03132 glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
03133
03134
03135 glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
03136
03137
03138
03139 #if defined(_VL_H)
03140 glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
03141 glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
03142 #endif
03143
03144
03145 glx.FreeContextEXT = Fake_glXFreeContextEXT;
03146 glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
03147
03148 glx.ImportContextEXT = Fake_glXImportContextEXT;
03149 glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
03150
03151
03152 glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
03153 glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
03154 glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
03155 glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
03156 glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
03157 glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
03158
03159
03160 glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
03161 glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
03162 glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
03163 glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
03164 glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
03165
03166
03167 glx.CushionSGI = Fake_glXCushionSGI;
03168
03169
03170 glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
03171 glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
03172 glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
03173 glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
03174 glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
03175
03176
03177 #if defined(_DM_BUFFER_H_)
03178 glx.AssociateDMPbufferSGIX = NULL;
03179 #endif
03180
03181
03182 glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
03183
03184
03185 glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
03186 glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
03187
03188
03189 glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
03190
03191
03192 glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
03193
03194
03195 glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
03196
03197
03198 glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
03199
03200
03201 glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;
03202
03203
03204 glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV;
03205 glx.FreeMemoryNV = Fake_glXFreeMemoryNV;
03206
03207
03208 glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA;
03209
03210
03211 glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
03212 glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
03213
03214 return &glx;
03215 }