X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Ffakeglx.c;h=af60bfaaa4e6b54e66a47d591095c69fb072bed5;hb=3dd299c3d5b88114894ec30d1fac85fba688201f;hp=73fde865e342f5985036c682a7ef6ed27ea05d68;hpb=49e80bf6b163310f7cd776261872201eea57053a;p=mesa.git diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 73fde865e34..af60bfaaa4e 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.5 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * Copyright (C) 2009 VMware, Inc. All Rights Reserved. @@ -18,9 +17,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ @@ -40,7 +40,8 @@ */ - +#include +#include #include "glxheader.h" #include "glxapi.h" #include "main/context.h" @@ -51,10 +52,7 @@ #include "main/version.h" #include "xfonts.h" #include "xmesaP.h" - -#ifdef __VMS -#define _mesa_sprintf sprintf -#endif +#include "util/u_math.h" /* This indicates the client-side GLX API and GLX encoder version. */ #define CLIENT_MAJOR_VERSION 1 @@ -67,7 +65,7 @@ #define SERVER_MINOR_VERSION 4 /* This is appended onto the glXGetClient/ServerString version strings. */ -#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING +#define MESA_GLX_VERSION "Mesa " PACKAGE_VERSION /* Who implemented this GLX? */ #define VENDOR "Brian Paul" @@ -77,6 +75,7 @@ "GLX_MESA_copy_sub_buffer " \ "GLX_MESA_pixmap_colormap " \ "GLX_MESA_release_buffers " \ + "GLX_ARB_create_context " \ "GLX_ARB_get_proc_address " \ "GLX_EXT_texture_from_pixmap " \ "GLX_EXT_visual_info " \ @@ -85,21 +84,6 @@ "GLX_SGIX_fbconfig " \ "GLX_SGIX_pbuffer " -/* - * Our fake GLX context will contain a "real" GLX context and an XMesa context. - * - * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, - * and vice versa. - * - * We really just need this structure in order to make the libGL functions - * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() - * work correctly. - */ -struct fake_glx_context { - __GLXcontext glxContext; /* this MUST be first! */ - XMesaContext xmesaContext; -}; - /**********************************************************************/ @@ -152,13 +136,8 @@ is_usable_visual( XVisualInfo *vinfo ) return GL_TRUE; case StaticColor: case PseudoColor: - /* Any StaticColor/PseudoColor visual of at least 4 bits */ - if (vinfo->depth>=4) { - return GL_TRUE; - } - else { - return GL_FALSE; - } + /* Color-index rendering is not supported. */ + return GL_FALSE; case TrueColor: case DirectColor: /* Any depth of TrueColor or DirectColor works in RGB mode */ @@ -206,7 +185,7 @@ GetOverlayInfo(Display *dpy, int screen, int *numOverlays) if (status != Success || actualType != overlayVisualsAtom || actualFormat != 32 || sizeData < 4) { /* something went wrong */ - XFree((void *) ovInfo); + free((void *) ovInfo); *numOverlays = 0; return NULL; } @@ -244,18 +223,18 @@ level_of_visual( Display *dpy, XVisualInfo *vinfo ) /* found the visual */ if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { int level = ov->layer; - XFree((void *) overlay_info); + free((void *) overlay_info); return level; } else { - XFree((void *) overlay_info); + free((void *) overlay_info); return 0; } } } /* The visual ID was not found in the overlay list. */ - XFree((void *) overlay_info); + free((void *) overlay_info); return 0; } @@ -268,7 +247,7 @@ level_of_visual( Display *dpy, XVisualInfo *vinfo ) */ static XMesaVisual save_glx_visual( Display *dpy, XVisualInfo *vinfo, - GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag, + GLboolean alphaFlag, GLboolean dbFlag, GLboolean stereoFlag, GLint depth_size, GLint stencil_size, GLint accumRedSize, GLint accumGreenSize, @@ -278,11 +257,10 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, GLboolean ximageFlag = GL_TRUE; XMesaVisual xmvis; GLint i; - GLboolean comparePointers; if (dbFlag) { /* Check if the MESA_BACK_BUFFER env var is set */ - char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER"); + char *backbuffer = getenv("MESA_BACK_BUFFER"); if (backbuffer) { if (backbuffer[0]=='p' || backbuffer[0]=='P') { ximageFlag = GL_FALSE; @@ -301,15 +279,9 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, return NULL; } - /* Comparing IDs uses less memory but sometimes fails. */ - /* XXX revisit this after 3.0 is finished. */ - if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) - comparePointers = GL_TRUE; - else - comparePointers = GL_FALSE; /* Force the visual to have an alpha channel */ - if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + if (getenv("MESA_GLX_FORCE_ALPHA")) alphaFlag = GL_TRUE; /* First check if a matching visual is already in the list */ @@ -319,7 +291,6 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, && v->mesa_visual.level == level && v->mesa_visual.numAuxBuffers == numAuxBuffers && v->ximage_flag == ximageFlag - && v->mesa_visual.rgbMode == rgbFlag && v->mesa_visual.doubleBufferMode == dbFlag && v->mesa_visual.stereoMode == stereoFlag && (v->mesa_visual.alphaBits > 0) == alphaFlag @@ -329,9 +300,8 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { - /* now either compare XVisualInfo pointers or visual IDs */ - if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) - || (comparePointers && v->vishandle == vinfo)) { + /* now compare visual IDs */ + if (v->visinfo->visualid == vinfo->visualid) { return v; } } @@ -339,21 +309,15 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, /* Create a new visual and add it to the list. */ - xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, + xmvis = XMesaCreateVisual( dpy, vinfo, GL_TRUE, alphaFlag, dbFlag, stereoFlag, ximageFlag, depth_size, stencil_size, accumRedSize, accumBlueSize, accumBlueSize, accumAlphaSize, 0, level, GLX_NONE_EXT ); if (xmvis) { - /* Save a copy of the pointer now so we can find this visual again - * if we need to search for it in find_glx_visual(). - */ - xmvis->vishandle = vinfo; /* Allocate more space for additional visual */ - VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, - sizeof(XMesaVisual) * NumVisuals, - sizeof(XMesaVisual) * (NumVisuals + 1)); + VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1)); /* add xmvis to the list */ VisualTable[NumVisuals] = xmvis; NumVisuals++; @@ -376,9 +340,9 @@ static GLint default_depth_bits(void) { int zBits; - const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + const char *zEnv = getenv("MESA_GLX_DEPTH_BITS"); if (zEnv) - zBits = _mesa_atoi(zEnv); + zBits = atoi(zEnv); else zBits = DEFAULT_SOFTWARE_DEPTH_BITS; return zBits; @@ -388,9 +352,9 @@ static GLint default_alpha_bits(void) { int aBits; - const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); + const char *aEnv = getenv("MESA_GLX_ALPHA_BITS"); if (aEnv) - aBits = _mesa_atoi(aEnv); + aBits = atoi(aEnv); else aBits = 0; return aBits; @@ -422,53 +386,26 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) vislevel = level_of_visual( dpy, visinfo ); if (vislevel) { - /* Configure this visual as a CI, single-buffered overlay */ - return save_glx_visual( dpy, visinfo, - GL_FALSE, /* rgb */ - GL_FALSE, /* alpha */ - GL_FALSE, /* double */ - GL_FALSE, /* stereo */ - 0, /* depth bits */ - 0, /* stencil bits */ - 0,0,0,0, /* accum bits */ - vislevel, /* level */ - 0 /* numAux */ - ); + /* Color-index rendering to overlays is not supported. */ + return NULL; } else if (is_usable_visual( visinfo )) { - if (_mesa_getenv("MESA_GLX_FORCE_CI")) { - /* Configure this visual as a COLOR INDEX visual. */ - return save_glx_visual( dpy, visinfo, - GL_FALSE, /* rgb */ - GL_FALSE, /* alpha */ - GL_TRUE, /* double */ - GL_FALSE, /* stereo */ - zBits, - STENCIL_BITS, - 0, 0, 0, 0, /* accum bits */ - 0, /* level */ - 0 /* numAux */ - ); - } - else { - /* Configure this visual as RGB, double-buffered, depth-buffered. */ - /* This is surely wrong for some people's needs but what else */ - /* can be done? They should use glXChooseVisual(). */ - return save_glx_visual( dpy, visinfo, - GL_TRUE, /* rgb */ - alphaFlag, /* alpha */ - GL_TRUE, /* double */ - GL_FALSE, /* stereo */ - zBits, - STENCIL_BITS, - accBits, /* r */ - accBits, /* g */ - accBits, /* b */ - accBits, /* a */ - 0, /* level */ - 0 /* numAux */ - ); - } + /* Configure this visual as RGB, double-buffered, depth-buffered. */ + /* This is surely wrong for some people's needs but what else */ + /* can be done? They should use glXChooseVisual(). */ + return save_glx_visual( dpy, visinfo, + alphaFlag, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + 8, /* stencil bits */ + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ + 0, /* level */ + 0 /* numAux */ + ); } else { _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); @@ -494,13 +431,6 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo ) } } - /* if that fails, try to match pointers */ - for (i=0;idisplay==dpy && VisualTable[i]->vishandle==vinfo) { - return VisualTable[i]; - } - } - return NULL; } @@ -530,19 +460,19 @@ transparent_pixel( XMesaVisual glxvis ) /* found it! */ if (ov->transparent_type == 0) { /* type 0 indicates no transparency */ - XFree((void *) overlay_info); + free((void *) overlay_info); return -1; } else { /* ov->value is the transparent pixel */ - XFree((void *) overlay_info); + free((void *) overlay_info); return ov->value; } } } /* The visual ID was not found in the overlay list. */ - XFree((void *) overlay_info); + free((void *) overlay_info); return -1; } @@ -581,13 +511,13 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. */ if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { - if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && - _mesa_bitcount((GLuint) vis->green_mask) <= 8 && - _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { + if (util_bitcount((GLuint) vis->red_mask ) <= 8 && + util_bitcount((GLuint) vis->green_mask) <= 8 && + util_bitcount((GLuint) vis->blue_mask ) <= 8) { return vis; } else { - XFree((void *) vis); + free((void *) vis); return NULL; } } @@ -612,21 +542,19 @@ get_env_visual(Display *dpy, int scr, const char *varname) int depth, xclass = -1; XVisualInfo *vis; - if (!_mesa_getenv( varname )) { + if (!getenv( varname )) { return NULL; } - _mesa_strncpy( value, _mesa_getenv(varname), 100 ); + strncpy( value, getenv(varname), 100 ); value[99] = 0; sscanf( value, "%s %d", type, &depth ); - if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; - else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; - else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; - else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; - else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; - else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; + if (strcmp(type,"TrueColor")==0) xclass = TrueColor; + else if (strcmp(type,"DirectColor")==0) xclass = DirectColor; + else if (strcmp(type,"GrayScale")==0) xclass = GrayScale; + else if (strcmp(type,"StaticGray")==0) xclass = StaticGray; if (xclass>-1 && depth>0) { vis = get_visual( dpy, scr, depth, xclass ); @@ -646,160 +574,79 @@ get_env_visual(Display *dpy, int scr, const char *varname) /* * Select an X visual which satisfies the RGBA/CI flag and minimum depth. * Input: dpy, screen - X display and screen number - * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode * min_depth - minimum visual depth * preferred_class - preferred GLX visual class or DONT_CARE * Return: pointer to an XVisualInfo or NULL. */ static XVisualInfo * -choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, - int preferred_class ) +choose_x_visual(Display *dpy, int screen, int min_depth, int preferred_class) { XVisualInfo *vis; int xclass, visclass = 0; int depth; - if (rgba) { - Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True); - /* First see if the MESA_RGB_VISUAL env var is defined */ - vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); - if (vis) { - return vis; - } - /* Otherwise, search for a suitable visual */ - if (preferred_class==DONT_CARE) { - for (xclass=0;xclass<6;xclass++) { - switch (xclass) { - case 0: visclass = TrueColor; break; - case 1: visclass = DirectColor; break; - case 2: visclass = PseudoColor; break; - case 3: visclass = StaticColor; break; - case 4: visclass = GrayScale; break; - case 5: visclass = StaticGray; break; - } - if (min_depth==0) { - /* start with shallowest */ - for (depth=0;depth<=32;depth++) { - if (visclass==TrueColor && depth==8 && !hp_cr_maps) { - /* Special case: try to get 8-bit PseudoColor before */ - /* 8-bit TrueColor */ - vis = get_visual( dpy, screen, 8, PseudoColor ); - if (vis) { - return vis; - } - } - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - else { - /* start with deepest */ - for (depth=32;depth>=min_depth;depth--) { - if (visclass==TrueColor && depth==8 && !hp_cr_maps) { - /* Special case: try to get 8-bit PseudoColor before */ - /* 8-bit TrueColor */ - vis = get_visual( dpy, screen, 8, PseudoColor ); - if (vis) { - return vis; - } - } - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - } - } - else { - /* search for a specific visual class */ - switch (preferred_class) { - case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; - case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; - case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; - case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; - case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; - case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; - default: return NULL; - } - if (min_depth==0) { - /* start with shallowest */ - for (depth=0;depth<=32;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } - else { - /* start with deepest */ - for (depth=32;depth>=min_depth;depth--) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } + /* First see if the MESA_RGB_VISUAL env var is defined */ + vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); + if (vis) { + return vis; + } + /* Otherwise, search for a suitable visual */ + if (preferred_class==DONT_CARE) { + for (xclass=0;xclass<4;xclass++) { + switch (xclass) { + case 0: visclass = TrueColor; break; + case 1: visclass = DirectColor; break; + case 2: visclass = GrayScale; break; + case 3: visclass = StaticGray; break; + } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + else { + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } } } else { - /* First see if the MESA_CI_VISUAL env var is defined */ - vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" ); - if (vis) { - return vis; + /* search for a specific visual class */ + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; + case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; + case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; + case GLX_PSEUDO_COLOR_EXT: + case GLX_STATIC_COLOR_EXT: + default: return NULL; } - /* Otherwise, search for a suitable visual, starting with shallowest */ - if (preferred_class==DONT_CARE) { - for (xclass=0;xclass<4;xclass++) { - switch (xclass) { - case 0: visclass = PseudoColor; break; - case 1: visclass = StaticColor; break; - case 2: visclass = GrayScale; break; - case 3: visclass = StaticGray; break; - } - /* try 8-bit up through 16-bit */ - for (depth=8;depth<=16;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - /* try min_depth up to 8-bit */ - for (depth=min_depth;depth<8;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } } else { - /* search for a specific visual class */ - switch (preferred_class) { - case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; - case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; - case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; - case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; - case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; - case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; - default: return NULL; - } - /* try 8-bit up through 16-bit */ - for (depth=8;depth<=16;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } - /* try min_depth up to 8-bit */ - for (depth=min_depth;depth<8;depth++) { - vis = get_visual( dpy, screen, depth, visclass ); - if (vis) { - return vis; - } - } + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } } } @@ -822,7 +669,7 @@ choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, * Return: pointer to an XVisualInfo or NULL. */ static XVisualInfo * -choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, +choose_x_overlay_visual( Display *dpy, int scr, int level, int trans_type, int trans_value, int min_depth, int preferred_class ) { @@ -880,35 +727,39 @@ choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, &vistemplate, &count ); + if (!vislist) { + /* no matches */ + continue; + } + if (count!=1) { /* something went wrong */ + free(vislist); continue; } if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { /* wrong visual class */ + free(vislist); continue; } - /* if RGB was requested, make sure we have True/DirectColor */ - if (rgbFlag && vislist->CLASS != TrueColor - && vislist->CLASS != DirectColor) + /* Color-index rendering is not supported. Make sure we have True/DirectColor */ + if (vislist->CLASS != TrueColor && vislist->CLASS != DirectColor) { + free(vislist); continue; + } - /* if CI was requested, make sure we have a color indexed visual */ - if (!rgbFlag - && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor)) + if (deepvis!=NULL && vislist->depth <= deepest) { + free(vislist); continue; - - if (deepvis==NULL || vislist->depth > deepest) { - /* YES! found a satisfactory visual */ - if (deepvis) { - XFree( deepvis ); - } - deepest = vislist->depth; - deepvis = vislist; - /* DEBUG tt = ov->transparent_type;*/ - /* DEBUG tv = ov->value; */ } + + /* YES! found a satisfactory visual */ + free(deepvis); + deepest = vislist->depth; + deepvis = vislist; + /* DEBUG tt = ov->transparent_type;*/ + /* DEBUG tv = ov->value; */ } /*DEBUG @@ -937,7 +788,7 @@ destroy_visuals_on_display(Display *dpy) if (VisualTable[i]->display == dpy) { /* remove this visual */ int j; - free(VisualTable[i]); + XMesaDestroyVisual(VisualTable[i]); for (j = i; j < NumVisuals - 1; j++) VisualTable[j] = VisualTable[j + 1]; NumVisuals--; @@ -990,7 +841,8 @@ register_with_display(Display *dpy) XExtCodes *c = XAddExtension(dpy); ext = dpy->ext_procs; /* new extension is at head of list */ assert(c->extension == ext->codes.extension); - ext->name = _mesa_strdup(extName); + (void) c; /* silence warning */ + ext->name = strdup(extName); ext->close_display = close_display_callback; } } @@ -1038,6 +890,20 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) while (*parselist) { + if (fbConfig && + parselist[1] == GLX_DONT_CARE && + parselist[0] != GLX_LEVEL) { + /* For glXChooseFBConfig(), skip attributes whose value is + * GLX_DONT_CARE (-1), unless it's GLX_LEVEL (which can legitimately be + * a negative value). + * + * From page 17 (23 of the pdf) of the GLX 1.4 spec: + * GLX DONT CARE may be specified for all attributes except GLX LEVEL. + */ + parselist += 2; + continue; + } + switch (*parselist) { case GLX_USE_GL: if (fbConfig) { @@ -1197,12 +1063,15 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) if (!fbConfig) return NULL; parselist++; - if (*parselist == GLX_RGBA_BIT) { + if (*parselist & GLX_RGBA_BIT) { rgb_flag = GL_TRUE; } - else if (*parselist == GLX_COLOR_INDEX_BIT) { + else if (*parselist & GLX_COLOR_INDEX_BIT) { rgb_flag = GL_FALSE; } + else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) { + rgb_flag = GL_TRUE; + } else if (*parselist == 0) { rgb_flag = GL_TRUE; } @@ -1218,19 +1087,22 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) parselist++; break; case GLX_FBCONFIG_ID: + case GLX_VISUAL_ID: if (!fbConfig) return NULL; parselist++; desiredVisualID = *parselist++; break; case GLX_X_RENDERABLE: + case GLX_MAX_PBUFFER_WIDTH: + case GLX_MAX_PBUFFER_HEIGHT: + case GLX_MAX_PBUFFER_PIXELS: if (!fbConfig) return NULL; parselist += 2; /* ignore */ break; -#ifdef GLX_EXT_texture_from_pixmap case GLX_BIND_TO_TEXTURE_RGB_EXT: parselist++; /*skip*/ break; @@ -1252,7 +1124,6 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) case GLX_Y_INVERTED_EXT: parselist++; /*skip*/ break; -#endif case None: /* end of list */ @@ -1266,7 +1137,11 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) } } + if (!rgb_flag) + return NULL; + (void) caveat; + (void) min_ci; /* * Since we're only simulating the GLX extension this function will never @@ -1285,46 +1160,27 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) if (vis) { /* give the visual some useful GLX attributes */ double_flag = GL_TRUE; - if (vis->depth > 8) - rgb_flag = GL_TRUE; + if (vis->depth <= 8) + return NULL; depth_size = default_depth_bits(); - stencil_size = STENCIL_BITS; + stencil_size = 8; /* XXX accum??? */ } } - else if (level==0) { - /* normal color planes */ - if (rgb_flag) { - /* Get an RGB visual */ - int min_rgb = min_red + min_green + min_blue; - if (min_rgb>1 && min_rgb<8) { - /* a special case to be sure we can get a monochrome visual */ - min_rgb = 1; - } - vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type ); - } - else { - /* Get a color index visual */ - vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type ); - accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; - } - } else { - /* over/underlay planes */ - if (rgb_flag) { - /* rgba overlay */ - int min_rgb = min_red + min_green + min_blue; - if (min_rgb>1 && min_rgb<8) { - /* a special case to be sure we can get a monochrome visual */ - min_rgb = 1; - } - vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, - trans_type, trans_value, min_rgb, visual_type ); + /* RGB visual */ + int min_rgb = min_red + min_green + min_blue; + if (min_rgb>1 && min_rgb<8) { + /* a special case to be sure we can get a monochrome visual */ + min_rgb = 1; + } + + if (level==0) { + vis = choose_x_visual(dpy, screen, min_rgb, visual_type); } else { - /* color index overlay */ - vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, - trans_type, trans_value, min_ci, visual_type ); + vis = choose_x_overlay_visual(dpy, screen, level, + trans_type, trans_value, min_rgb, visual_type); } } @@ -1348,7 +1204,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) /* we only support one size of stencil and accum buffers. */ if (stencil_size > 0) - stencil_size = STENCIL_BITS; + stencil_size = 8; if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || accumAlphaSize > 0) { accumRedSize = @@ -1357,10 +1213,11 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) accumAlphaSize = alpha_flag ? accumRedSize : 0; } - xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, + xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag, stereo_flag, depth_size, stencil_size, accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize, level, numAux ); + free(vis); } return xmvis; @@ -1377,59 +1234,30 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list ) xmvis = choose_visual(dpy, screen, list, GL_FALSE); if (xmvis) { -#if 0 - return xmvis->vishandle; -#else - /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); - if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); + if (visinfo) { + memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); } - return xmvis->vishandle; -#endif + return visinfo; } else return NULL; } -/** - * Init basic fields of a new fake_glx_context. - * If the MESA_GLX_FORCE_DIRECT env var is set, the context will be marked as - * a direct rendering context. Some apps won't run without this. - */ -static void -init_glx_context(struct fake_glx_context *glxCtx, Display *dpy) -{ - GLboolean direct = _mesa_getenv("MESA_GLX_FORCE_DIRECT") ? GL_TRUE : GL_FALSE; - glxCtx->xmesaContext->direct = direct; - glxCtx->glxContext.isDirect = direct; - glxCtx->glxContext.currentDpy = dpy; - glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ - - assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); -} - - - static GLXContext Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, GLXContext share_list, Bool direct ) { XMesaVisual xmvis; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + XMesaContext xmesaCtx; if (!dpy || !visinfo) return 0; - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) - return 0; - /* deallocate unused windows/buffers */ #if 0 - XMesaGarbageCollect(); + XMesaGarbageCollect(dpy); #endif xmvis = find_glx_visual( dpy, visinfo ); @@ -1437,22 +1265,13 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, /* This visual wasn't found with glXChooseVisual() */ xmvis = create_glx_visual( dpy, visinfo ); if (!xmvis) { - /* unusable visual */ - _mesa_free(glxCtx); return NULL; } } - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } + xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); - init_glx_context(glxCtx, dpy); - - return (GLXContext) glxCtx; + return (GLXContext) xmesaCtx; } @@ -1469,11 +1288,9 @@ static Bool Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - if (ctx && draw && read) { XMesaBuffer drawBuffer, readBuffer; - XMesaContext xmctx = glxCtx->xmesaContext; + XMesaContext xmctx = (XMesaContext) ctx; /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ if (ctx == MakeCurrent_PrevContext @@ -1490,9 +1307,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, /* Out of memory, or context/drawable depth mismatch */ return False; } -#ifdef FX - FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); -#endif } /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ @@ -1510,9 +1324,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, /* Out of memory, or context/drawable depth mismatch */ return False; } -#ifdef FX - FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); -#endif } MakeCurrent_PrevContext = ctx; @@ -1522,15 +1333,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, MakeCurrent_PrevReadBuffer = readBuffer; /* Now make current! */ - if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { - ((__GLXcontext *) ctx)->currentDpy = dpy; - ((__GLXcontext *) ctx)->currentDrawable = draw; - ((__GLXcontext *) ctx)->currentReadable = read; - return True; - } - else { - return False; - } + return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer); } else if (!ctx && !draw && !read) { /* release current context w/out assigning new one. */ @@ -1614,7 +1417,7 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) if (b) { XMesaDestroyBuffer(b); } - else if (_mesa_getenv("MESA_DEBUG")) { + else if (getenv("MESA_DEBUG")) { _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); } } @@ -1624,26 +1427,28 @@ static void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask ) { - struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; - struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; - XMesaContext xm_src = fakeSrc->xmesaContext; - XMesaContext xm_dst = fakeDst->xmesaContext; + XMesaContext xmSrc = (XMesaContext) src; + XMesaContext xmDst = (XMesaContext) dst; (void) dpy; if (MakeCurrent_PrevContext == src) { _mesa_Flush(); } - _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask ); + _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask ); } static Bool -Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) +Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) { + int op, ev, err; /* Mesa's GLX isn't really an X extension but we try to act like one. */ - (void) dpy; - (void) errorb; - (void) event; - return True; + if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err)) + ev = err = 0; + if (errorBase) + *errorBase = err; + if (eventBase) + *eventBase = ev; + return True; /* we're faking GLX so always return success */ } @@ -1658,25 +1463,24 @@ void _kw_ungrab_all( Display *dpy ) static void Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - (void) dpy; - MakeCurrent_PrevContext = 0; - MakeCurrent_PrevDrawable = 0; - MakeCurrent_PrevReadable = 0; - MakeCurrent_PrevDrawBuffer = 0; - MakeCurrent_PrevReadBuffer = 0; - XMesaDestroyContext( glxCtx->xmesaContext ); - XMesaGarbageCollect(); - _mesa_free(glxCtx); + if (ctx) { + (void) dpy; + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + XMesaDestroyContext((XMesaContext) ctx); + XMesaGarbageCollect(dpy); + } } static Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - (void) dpy; - return glxCtx->xmesaContext->direct; + XMesaContext xmCtx = (XMesaContext) ctx; + return xmCtx ? xmCtx->direct : False; } @@ -1689,7 +1493,7 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) if (buffer) { XMesaSwapBuffers(buffer); } - else if (_mesa_getenv("MESA_DEBUG")) { + else if (getenv("MESA_DEBUG")) { _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", (int) drawable); } @@ -1707,7 +1511,7 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, if (buffer) { XMesaCopySubBuffer(buffer, x, y, width, height); } - else if (_mesa_getenv("MESA_DEBUG")) { + else if (getenv("MESA_DEBUG")) { _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); } } @@ -1731,7 +1535,7 @@ Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) static int get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) { - ASSERT(xmvis); + assert(xmvis); switch(attrib) { case GLX_USE_GL: if (fbconfig) @@ -1885,7 +1689,9 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) case GLX_RENDER_TYPE_SGIX: if (!fbconfig) return GLX_BAD_ATTRIBUTE; - if (xmvis->mesa_visual.rgbMode) + if (xmvis->mesa_visual.floatMode) + *value = GLX_RGBA_FLOAT_BIT_ARB; + else if (xmvis->mesa_visual.rgbMode) *value = GLX_RGBA_BIT; else *value = GLX_COLOR_INDEX_BIT; @@ -1903,7 +1709,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) case GLX_MAX_PBUFFER_WIDTH: if (!fbconfig) return GLX_BAD_ATTRIBUTE; - /* XXX or MAX_WIDTH? */ + /* XXX should be same as ctx->Const.MaxRenderbufferSize */ *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); break; case GLX_MAX_PBUFFER_HEIGHT: @@ -1923,7 +1729,6 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = xmvis->visinfo->visualid; break; -#ifdef GLX_EXT_texture_from_pixmap case GLX_BIND_TO_TEXTURE_RGB_EXT: *value = True; /*XXX*/ break; @@ -1942,7 +1747,6 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) case GLX_Y_INVERTED_EXT: *value = True; /*XXX*/ break; -#endif default: return GLX_BAD_ATTRIBUTE; @@ -1981,6 +1785,13 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, } +static GLXContext +Fake_glXGetCurrentContext(void) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + return (GLXContext) xmesa; +} + static void Fake_glXWaitGL( void ) { @@ -2001,12 +1812,6 @@ Fake_glXWaitX( void ) static const char * get_extensions( void ) { -#ifdef FX - const char *fx = _mesa_getenv("MESA_GLX_FX"); - if (fx && fx[0] != 'd') { - return EXTENSIONS; - } -#endif return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ } @@ -2028,8 +1833,8 @@ static const char * Fake_glXQueryServerString( Display *dpy, int screen, int name ) { static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", - SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); + sprintf(version, "%d.%d %s", + SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); (void) dpy; (void) screen; @@ -2053,8 +1858,8 @@ static const char * Fake_glXGetClientString( Display *dpy, int name ) { static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, - CLIENT_MINOR_VERSION, MESA_GLX_VERSION); + sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, + CLIENT_MINOR_VERSION, MESA_GLX_VERSION); (void) dpy; @@ -2104,7 +1909,7 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); if (*nelements > 0) { XMesaVisual *results; - results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); + results = malloc(*nelements * sizeof(XMesaVisual)); if (!results) { *nelements = 0; return NULL; @@ -2112,6 +1917,7 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) for (i = 0; i < *nelements; i++) { results[i] = create_glx_visual(dpy, visuals + i); } + free(visuals); return (GLXFBConfig *) results; } return NULL; @@ -2124,6 +1930,9 @@ Fake_glXChooseFBConfig( Display *dpy, int screen, { XMesaVisual xmvis; + /* register ourselves as an extension on this display */ + register_with_display(dpy); + if (!attribList || !attribList[0]) { /* return list of all configs (per GLX_SGIX_fbconfig spec) */ return Fake_glXGetFBConfigs(dpy, screen, nitems); @@ -2131,7 +1940,7 @@ Fake_glXChooseFBConfig( Display *dpy, int screen, xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); if (xmvis) { - GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + GLXFBConfig *config = malloc(sizeof(XMesaVisual)); if (!config) { *nitems = 0; return NULL; @@ -2152,16 +1961,11 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) { if (dpy && config) { XMesaVisual xmvis = (XMesaVisual) config; -#if 0 - return xmvis->vishandle; -#else - /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); - if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + XVisualInfo* visinfo = malloc(sizeof(XVisualInfo)); + if (visinfo) { + memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo)); } - return xmvis->vishandle; -#endif + return visinfo; } else { return NULL; @@ -2182,11 +1986,6 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, if (!xmbuf) return 0; -#ifdef FX - /* XXX this will segfault if actually called */ - FXcreateContext(xmvis, win, NULL, xmbuf); -#endif - (void) dpy; (void) attribList; /* Ignored in GLX 1.3 */ @@ -2218,7 +2017,7 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, if (!dpy || !config || !pixmap) return 0; - for (attr = attribList; *attr; attr++) { + for (attr = attribList; attr && *attr; attr++) { switch (*attr) { case GLX_TEXTURE_FORMAT_EXT: attr++; @@ -2349,32 +2148,42 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, break; case GLX_PRESERVED_CONTENTS: attrib++; - preserveContents = *attrib; /* ignored */ + preserveContents = *attrib; break; case GLX_LARGEST_PBUFFER: attrib++; - useLargest = *attrib; /* ignored */ + useLargest = *attrib; break; default: return 0; } } - /* not used at this time */ - (void) useLargest; - (void) preserveContents; - if (width == 0 || height == 0) return 0; + if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) { + /* If allocation would have failed and GLX_LARGEST_PBUFFER is set, + * allocate the largest possible buffer. + */ + if (useLargest) { + width = SWRAST_MAX_WIDTH; + height = SWRAST_MAX_HEIGHT; + } + } + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - if (xmbuf) + if (xmbuf) { + xmbuf->largestPbuffer = useLargest; + xmbuf->preservedContents = preserveContents; return (GLXPbuffer) xmbuf->frontxrb->pixmap; - else + } + else { return 0; + } } @@ -2396,6 +2205,9 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, if (!xmbuf) return; + /* make sure buffer's dimensions are up to date */ + xmesa_check_and_update_buffer_size(NULL, xmbuf); + switch (attribute) { case GLX_WIDTH: *value = xmbuf->mesa_buffer.Width; @@ -2404,15 +2216,14 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, *value = xmbuf->mesa_buffer.Height; break; case GLX_PRESERVED_CONTENTS: - *value = True; + *value = xmbuf->preservedContents; break; case GLX_LARGEST_PBUFFER: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmbuf->largestPbuffer; break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; return; -#ifdef GLX_EXT_texture_from_pixmap case GLX_TEXTURE_FORMAT_EXT: *value = xmbuf->TextureFormat; break; @@ -2422,7 +2233,6 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, case GLX_MIPMAP_TEXTURE_EXT: *value = xmbuf->TextureMipmap; break; -#endif default: return; /* raise BadValue error */ @@ -2434,40 +2244,29 @@ static GLXContext Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct ) { - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; + XMesaContext xmCtx; XMesaVisual xmvis = (XMesaVisual) config; if (!dpy || !config || - (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) - return 0; - - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) + (renderType != GLX_RGBA_TYPE && + renderType != GLX_COLOR_INDEX_TYPE && + renderType != GLX_RGBA_FLOAT_TYPE_ARB && + renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT)) return 0; /* deallocate unused windows/buffers */ - XMesaGarbageCollect(); - - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } + XMesaGarbageCollect(dpy); - init_glx_context(glxCtx, dpy); + xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList); - return (GLXContext) glxCtx; + return (GLXContext) xmCtx; } static int Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) { - struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; - XMesaContext xmctx = glxCtx->xmesaContext; - + XMesaContext xmctx = (XMesaContext) ctx; (void) dpy; (void) ctx; @@ -2476,10 +2275,7 @@ Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) *value = xmctx->xm_visual->visinfo->visualid; break; case GLX_RENDER_TYPE: - if (xmctx->xm_visual->mesa_visual.rgbMode) - *value = GLX_RGBA_BIT; - else - *value = GLX_COLOR_INDEX_BIT; + *value = GLX_RGBA_TYPE; break; case GLX_SCREEN: *value = 0; @@ -2656,27 +2452,15 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm static GLXContext Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) { + XMesaContext xmCtx; XMesaVisual xmvis = (XMesaVisual) config; - struct fake_glx_context *glxCtx; - struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; - - glxCtx = CALLOC_STRUCT(fake_glx_context); - if (!glxCtx) - return 0; /* deallocate unused windows/buffers */ - XMesaGarbageCollect(); + XMesaGarbageCollect(dpy); - glxCtx->xmesaContext = XMesaCreateContext(xmvis, - shareCtx ? shareCtx->xmesaContext : NULL); - if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); - return NULL; - } + xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list); - init_glx_context(glxCtx, dpy); - - return (GLXContext) glxCtx; + return (GLXContext) xmCtx; } @@ -2752,22 +2536,22 @@ Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) } -static int +static void Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) { const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); if (!xmbuf) { /* Generate GLXBadPbufferSGIX for bad pbuffer */ - return 0; + return; } switch (attribute) { case GLX_PRESERVED_CONTENTS_SGIX: - *value = True; + *value = xmbuf->preservedContents; break; case GLX_LARGEST_PBUFFER_SGIX: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmbuf->largestPbuffer; break; case GLX_WIDTH_SGIX: *value = xmbuf->mesa_buffer.Width; @@ -2781,7 +2565,6 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un default: *value = 0; } - return 0; } @@ -2900,43 +2683,10 @@ Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *p #endif -/*** GLX_SGIX_swap_group ***/ - -static void -Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) -{ - (void) dpy; - (void) drawable; - (void) member; -} - - - -/*** GLX_SGIX_swap_barrier ***/ - -static void -Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) -{ - (void) dpy; - (void) drawable; - (void) barrier; -} - -static Bool -Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) -{ - (void) dpy; - (void) screen; - (void) max; - return False; -} - - - /*** GLX_SUN_get_transparent_index ***/ static Status -Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, unsigned long *pTransparent) { (void) dpy; (void) overlay; @@ -2966,48 +2716,6 @@ Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) -/*** GLX_MESA_set_3dfx_mode ***/ - -static Bool -Fake_glXSet3DfxModeMESA( int mode ) -{ - return XMesaSetFXmode( mode ); -} - - - -/*** GLX_NV_vertex_array range ***/ -static void * -Fake_glXAllocateMemoryNV( GLsizei size, - GLfloat readFrequency, - GLfloat writeFrequency, - GLfloat priority ) -{ - (void) size; - (void) readFrequency; - (void) writeFrequency; - (void) priority; - return NULL; -} - - -static void -Fake_glXFreeMemoryNV( GLvoid *pointer ) -{ - (void) pointer; -} - - -/*** GLX_MESA_agp_offset ***/ - -static GLuint -Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) -{ - (void) pointer; - return ~0; -} - - /*** GLX_EXT_texture_from_pixmap ***/ static void @@ -3028,6 +2736,57 @@ Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) } +static GLXContext +Fake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config, + GLXContext share_context, Bool direct, + const int *attrib_list) +{ + XMesaContext xmCtx; + XMesaVisual xmvis = (XMesaVisual) config; + int i; + int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0; + + for (i = 0; attrib_list[i]; i += 2) { + switch (attrib_list[i]) { + case GLX_CONTEXT_MAJOR_VERSION_ARB: + major = attrib_list[i + 1]; + break; + case GLX_CONTEXT_MINOR_VERSION_ARB: + minor = attrib_list[i + 1]; + break; + case GLX_CONTEXT_FLAGS_ARB: + ctxFlags = attrib_list[i + 1]; + break; + case GLX_CONTEXT_PROFILE_MASK_ARB: + profileFlags = attrib_list[i + 1]; + break; + default: + _mesa_warning(NULL, "Unexpected attribute 0x%x in " + "glXCreateContextAttribs()\n", attrib_list[i]); + return 0; + } + } + + if (major * 10 + minor > 21) { + /* swrast only supports GL 2.1 and earlier */ + return 0; + } + + /* These are ignored for now. We'd have to enhance XMesaCreateContext + * to take these flags and the version, at least. + */ + (void) ctxFlags; + (void) profileFlags; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(dpy); + + xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context); + + return (GLXContext) xmCtx; +} + + /* silence warning */ extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); @@ -3062,7 +2821,7 @@ _mesa_GetGLXDispatchTable(void) glx.DestroyContext = Fake_glXDestroyContext; glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; glx.GetConfig = Fake_glXGetConfig; - /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ + glx.GetCurrentContext = Fake_glXGetCurrentContext; /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ glx.IsDirect = Fake_glXIsDirect; glx.MakeCurrent = Fake_glXMakeCurrent; @@ -3154,13 +2913,6 @@ _mesa_GetGLXDispatchTable(void) glx.AssociateDMPbufferSGIX = NULL; #endif - /*** GLX_SGIX_swap_group ***/ - glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; - - /*** GLX_SGIX_swap_barrier ***/ - glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; - glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; - /*** GLX_SUN_get_transparent_index ***/ glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; @@ -3173,19 +2925,10 @@ _mesa_GetGLXDispatchTable(void) /*** GLX_MESA_pixmap_colormap ***/ glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; - /*** GLX_MESA_set_3dfx_mode ***/ - glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; - - /*** GLX_NV_vertex_array_range ***/ - glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; - glx.FreeMemoryNV = Fake_glXFreeMemoryNV; - - /*** GLX_MESA_agp_offset ***/ - glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; - /*** GLX_EXT_texture_from_pixmap ***/ glx.BindTexImageEXT = Fake_glXBindTexImageEXT; glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + glx.CreateContextAttribs = Fake_glXCreateContextAttribs; return &glx; }