|  |  | @@ -0,0 +1,626 @@ | 
		
	
		
			
			|  |  |  | /** | 
		
	
		
			
			|  |  |  | * GLX initialization.  Code based on glxext.c, glx_query.c, and | 
		
	
		
			
			|  |  |  | * glcontextmodes.c under src/glx/x11/.  The major difference is that no DRI | 
		
	
		
			
			|  |  |  | * related code here. | 
		
	
		
			
			|  |  |  | * | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #include <assert.h> | 
		
	
		
			
			|  |  |  | #include <X11/Xlib.h> | 
		
	
		
			
			|  |  |  | #include <X11/Xproto.h> | 
		
	
		
			
			|  |  |  | #include <X11/extensions/Xext.h> | 
		
	
		
			
			|  |  |  | #include <X11/extensions/extutil.h> | 
		
	
		
			
			|  |  |  | #include <sys/time.h> | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #include "glxinit.h" | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | typedef struct GLXGenericGetString | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | CARD8 reqType; | 
		
	
		
			
			|  |  |  | CARD8 glxCode; | 
		
	
		
			
			|  |  |  | CARD16 length B16; | 
		
	
		
			
			|  |  |  | CARD32 for_whom B32; | 
		
	
		
			
			|  |  |  | CARD32 name B32; | 
		
	
		
			
			|  |  |  | } xGLXGenericGetStringReq; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #define sz_xGLXGenericGetStringReq 12 | 
		
	
		
			
			|  |  |  | #define X_GLXGenericGetString 0 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Extension required boiler plate */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static char *__glXExtensionName = GLX_EXTENSION_NAME; | 
		
	
		
			
			|  |  |  | static XExtensionInfo *__glXExtensionInfo = NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; | 
		
	
		
			
			|  |  |  | static | 
		
	
		
			
			|  |  |  | XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, | 
		
	
		
			
			|  |  |  | __glXExtensionName, &__glXExtensionHooks, | 
		
	
		
			
			|  |  |  | __GLX_NUMBER_EVENTS, NULL) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static GLint | 
		
	
		
			
			|  |  |  | _gl_convert_from_x_visual_type(int visualType) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #define NUM_VISUAL_TYPES   6 | 
		
	
		
			
			|  |  |  | static const int glx_visual_types[NUM_VISUAL_TYPES] = { | 
		
	
		
			
			|  |  |  | GLX_STATIC_GRAY, GLX_GRAY_SCALE, | 
		
	
		
			
			|  |  |  | GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, | 
		
	
		
			
			|  |  |  | GLX_TRUE_COLOR, GLX_DIRECT_COLOR | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return ((unsigned) visualType < NUM_VISUAL_TYPES) | 
		
	
		
			
			|  |  |  | ? glx_visual_types[visualType] : GLX_NONE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static __GLcontextModes * | 
		
	
		
			
			|  |  |  | _gl_context_modes_create(unsigned count, size_t minimum_size) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const size_t size = (minimum_size > sizeof(__GLcontextModes)) | 
		
	
		
			
			|  |  |  | ? minimum_size : sizeof(__GLcontextModes); | 
		
	
		
			
			|  |  |  | __GLcontextModes *base = NULL; | 
		
	
		
			
			|  |  |  | __GLcontextModes **next; | 
		
	
		
			
			|  |  |  | unsigned i; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | next = &base; | 
		
	
		
			
			|  |  |  | for (i = 0; i < count; i++) { | 
		
	
		
			
			|  |  |  | *next = (__GLcontextModes *) Xmalloc(size); | 
		
	
		
			
			|  |  |  | if (*next == NULL) { | 
		
	
		
			
			|  |  |  | _gl_context_modes_destroy(base); | 
		
	
		
			
			|  |  |  | base = NULL; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | memset(*next, 0, size); | 
		
	
		
			
			|  |  |  | (*next)->visualID = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->visualType = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->visualRating = GLX_NONE; | 
		
	
		
			
			|  |  |  | (*next)->transparentPixel = GLX_NONE; | 
		
	
		
			
			|  |  |  | (*next)->transparentRed = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->transparentGreen = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->transparentBlue = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->transparentAlpha = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->transparentIndex = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->xRenderable = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->fbconfigID = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; | 
		
	
		
			
			|  |  |  | (*next)->bindToTextureRgb = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->bindToTextureRgba = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->bindToMipmapTexture = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->bindToTextureTargets = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | (*next)->yInverted = GLX_DONT_CARE; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | next = &((*next)->next); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return base; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _X_HIDDEN void | 
		
	
		
			
			|  |  |  | _gl_context_modes_destroy(__GLcontextModes * modes) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | while (modes != NULL) { | 
		
	
		
			
			|  |  |  | __GLcontextModes *const next = modes->next; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Xfree(modes); | 
		
	
		
			
			|  |  |  | modes = next; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _X_HIDDEN char * | 
		
	
		
			
			|  |  |  | __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | xGLXGenericGetStringReq *req; | 
		
	
		
			
			|  |  |  | xGLXSingleReply reply; | 
		
	
		
			
			|  |  |  | int length; | 
		
	
		
			
			|  |  |  | int numbytes; | 
		
	
		
			
			|  |  |  | char *buf; | 
		
	
		
			
			|  |  |  | CARD32 for_whom = screen; | 
		
	
		
			
			|  |  |  | CARD32 glxCode = X_GLXQueryServerString; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | LockDisplay(dpy); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* All of the GLX protocol requests for getting a string from the server | 
		
	
		
			
			|  |  |  | * look the same.  The exact meaning of the for_whom field is usually | 
		
	
		
			
			|  |  |  | * either the screen number (for glXQueryServerString) or the context tag | 
		
	
		
			
			|  |  |  | * (for GLXSingle). | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | GetReq(GLXGenericGetString, req); | 
		
	
		
			
			|  |  |  | req->reqType = opcode; | 
		
	
		
			
			|  |  |  | req->glxCode = glxCode; | 
		
	
		
			
			|  |  |  | req->for_whom = for_whom; | 
		
	
		
			
			|  |  |  | req->name = name; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _XReply(dpy, (xReply *) & reply, 0, False); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | length = reply.length * 4; | 
		
	
		
			
			|  |  |  | numbytes = reply.size; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | buf = (char *) Xmalloc(numbytes); | 
		
	
		
			
			|  |  |  | if (buf != NULL) { | 
		
	
		
			
			|  |  |  | _XRead(dpy, buf, numbytes); | 
		
	
		
			
			|  |  |  | length -= numbytes; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _XEatData(dpy, length); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | UnlockDisplay(dpy); | 
		
	
		
			
			|  |  |  | SyncHandle(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return buf; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /************************************************************************/ | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** Free the per screen configs data as well as the array of | 
		
	
		
			
			|  |  |  | ** __glXScreenConfigs. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | static void | 
		
	
		
			
			|  |  |  | FreeScreenConfigs(__GLXdisplayPrivate * priv) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | __GLXscreenConfigs *psc; | 
		
	
		
			
			|  |  |  | GLint i, screens; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Free screen configuration information */ | 
		
	
		
			
			|  |  |  | psc = priv->screenConfigs; | 
		
	
		
			
			|  |  |  | screens = ScreenCount(priv->dpy); | 
		
	
		
			
			|  |  |  | for (i = 0; i < screens; i++, psc++) { | 
		
	
		
			
			|  |  |  | if (psc->configs) { | 
		
	
		
			
			|  |  |  | _gl_context_modes_destroy(psc->configs); | 
		
	
		
			
			|  |  |  | psc->configs = NULL;   /* NOTE: just for paranoia */ | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | if (psc->visuals) { | 
		
	
		
			
			|  |  |  | _gl_context_modes_destroy(psc->visuals); | 
		
	
		
			
			|  |  |  | psc->visuals = NULL;   /* NOTE: just for paranoia */ | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | Xfree((char *) psc->serverGLXexts); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | XFree((char *) priv->screenConfigs); | 
		
	
		
			
			|  |  |  | priv->screenConfigs = NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /************************************************************************/ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** Query the version of the GLX extension.  This procedure works even if | 
		
	
		
			
			|  |  |  | ** the client extension is not completely set up. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | static Bool | 
		
	
		
			
			|  |  |  | QueryVersion(Display * dpy, int opcode, int *major, int *minor) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | xGLXQueryVersionReq *req; | 
		
	
		
			
			|  |  |  | xGLXQueryVersionReply reply; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Send the glXQueryVersion request */ | 
		
	
		
			
			|  |  |  | LockDisplay(dpy); | 
		
	
		
			
			|  |  |  | GetReq(GLXQueryVersion, req); | 
		
	
		
			
			|  |  |  | req->reqType = opcode; | 
		
	
		
			
			|  |  |  | req->glxCode = X_GLXQueryVersion; | 
		
	
		
			
			|  |  |  | req->majorVersion = GLX_MAJOR_VERSION; | 
		
	
		
			
			|  |  |  | req->minorVersion = GLX_MINOR_VERSION; | 
		
	
		
			
			|  |  |  | _XReply(dpy, (xReply *) & reply, 0, False); | 
		
	
		
			
			|  |  |  | UnlockDisplay(dpy); | 
		
	
		
			
			|  |  |  | SyncHandle(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (reply.majorVersion != GLX_MAJOR_VERSION) { | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** The server does not support the same major release as this | 
		
	
		
			
			|  |  |  | ** client. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | return GL_FALSE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | *major = reply.majorVersion; | 
		
	
		
			
			|  |  |  | *minor = min(reply.minorVersion, GLX_MINOR_VERSION); | 
		
	
		
			
			|  |  |  | return GL_TRUE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _X_HIDDEN void | 
		
	
		
			
			|  |  |  | __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, | 
		
	
		
			
			|  |  |  | const INT32 * bp, Bool tagged_only, | 
		
	
		
			
			|  |  |  | Bool fbconfig_style_tags) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int i; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!tagged_only) { | 
		
	
		
			
			|  |  |  | /* Copy in the first set of properties */ | 
		
	
		
			
			|  |  |  | config->visualID = *bp++; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->visualType = _gl_convert_from_x_visual_type(*bp++); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->rgbMode = *bp++; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->redBits = *bp++; | 
		
	
		
			
			|  |  |  | config->greenBits = *bp++; | 
		
	
		
			
			|  |  |  | config->blueBits = *bp++; | 
		
	
		
			
			|  |  |  | config->alphaBits = *bp++; | 
		
	
		
			
			|  |  |  | config->accumRedBits = *bp++; | 
		
	
		
			
			|  |  |  | config->accumGreenBits = *bp++; | 
		
	
		
			
			|  |  |  | config->accumBlueBits = *bp++; | 
		
	
		
			
			|  |  |  | config->accumAlphaBits = *bp++; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->doubleBufferMode = *bp++; | 
		
	
		
			
			|  |  |  | config->stereoMode = *bp++; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->rgbBits = *bp++; | 
		
	
		
			
			|  |  |  | config->depthBits = *bp++; | 
		
	
		
			
			|  |  |  | config->stencilBits = *bp++; | 
		
	
		
			
			|  |  |  | config->numAuxBuffers = *bp++; | 
		
	
		
			
			|  |  |  | config->level = *bp++; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | count -= __GLX_MIN_CONFIG_PROPS; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** Additional properties may be in a list at the end | 
		
	
		
			
			|  |  |  | ** of the reply.  They are in pairs of property type | 
		
	
		
			
			|  |  |  | ** and property value. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #define FETCH_OR_SET(tag) \ | 
		
	
		
			
			|  |  |  | config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (i = 0; i < count; i += 2) { | 
		
	
		
			
			|  |  |  | switch (*bp++) { | 
		
	
		
			
			|  |  |  | case GLX_RGBA: | 
		
	
		
			
			|  |  |  | FETCH_OR_SET(rgbMode); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BUFFER_SIZE: | 
		
	
		
			
			|  |  |  | config->rgbBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_LEVEL: | 
		
	
		
			
			|  |  |  | config->level = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_DOUBLEBUFFER: | 
		
	
		
			
			|  |  |  | FETCH_OR_SET(doubleBufferMode); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_STEREO: | 
		
	
		
			
			|  |  |  | FETCH_OR_SET(stereoMode); | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_AUX_BUFFERS: | 
		
	
		
			
			|  |  |  | config->numAuxBuffers = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_RED_SIZE: | 
		
	
		
			
			|  |  |  | config->redBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_GREEN_SIZE: | 
		
	
		
			
			|  |  |  | config->greenBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BLUE_SIZE: | 
		
	
		
			
			|  |  |  | config->blueBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_ALPHA_SIZE: | 
		
	
		
			
			|  |  |  | config->alphaBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_DEPTH_SIZE: | 
		
	
		
			
			|  |  |  | config->depthBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_STENCIL_SIZE: | 
		
	
		
			
			|  |  |  | config->stencilBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_ACCUM_RED_SIZE: | 
		
	
		
			
			|  |  |  | config->accumRedBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_ACCUM_GREEN_SIZE: | 
		
	
		
			
			|  |  |  | config->accumGreenBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_ACCUM_BLUE_SIZE: | 
		
	
		
			
			|  |  |  | config->accumBlueBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_ACCUM_ALPHA_SIZE: | 
		
	
		
			
			|  |  |  | config->accumAlphaBits = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_VISUAL_CAVEAT_EXT: | 
		
	
		
			
			|  |  |  | config->visualRating = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_X_VISUAL_TYPE: | 
		
	
		
			
			|  |  |  | config->visualType = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_TYPE: | 
		
	
		
			
			|  |  |  | config->transparentPixel = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_INDEX_VALUE: | 
		
	
		
			
			|  |  |  | config->transparentIndex = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_RED_VALUE: | 
		
	
		
			
			|  |  |  | config->transparentRed = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_GREEN_VALUE: | 
		
	
		
			
			|  |  |  | config->transparentGreen = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_BLUE_VALUE: | 
		
	
		
			
			|  |  |  | config->transparentBlue = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_TRANSPARENT_ALPHA_VALUE: | 
		
	
		
			
			|  |  |  | config->transparentAlpha = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_VISUAL_ID: | 
		
	
		
			
			|  |  |  | config->visualID = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_DRAWABLE_TYPE: | 
		
	
		
			
			|  |  |  | config->drawableType = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_RENDER_TYPE: | 
		
	
		
			
			|  |  |  | config->renderType = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_X_RENDERABLE: | 
		
	
		
			
			|  |  |  | config->xRenderable = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_FBCONFIG_ID: | 
		
	
		
			
			|  |  |  | config->fbconfigID = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_MAX_PBUFFER_WIDTH: | 
		
	
		
			
			|  |  |  | config->maxPbufferWidth = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_MAX_PBUFFER_HEIGHT: | 
		
	
		
			
			|  |  |  | config->maxPbufferHeight = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_MAX_PBUFFER_PIXELS: | 
		
	
		
			
			|  |  |  | config->maxPbufferPixels = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: | 
		
	
		
			
			|  |  |  | config->optimalPbufferWidth = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: | 
		
	
		
			
			|  |  |  | config->optimalPbufferHeight = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_VISUAL_SELECT_GROUP_SGIX: | 
		
	
		
			
			|  |  |  | config->visualSelectGroup = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_SWAP_METHOD_OML: | 
		
	
		
			
			|  |  |  | config->swapMethod = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_SAMPLE_BUFFERS_SGIS: | 
		
	
		
			
			|  |  |  | config->sampleBuffers = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_SAMPLES_SGIS: | 
		
	
		
			
			|  |  |  | config->samples = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BIND_TO_TEXTURE_RGB_EXT: | 
		
	
		
			
			|  |  |  | config->bindToTextureRgb = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BIND_TO_TEXTURE_RGBA_EXT: | 
		
	
		
			
			|  |  |  | config->bindToTextureRgba = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: | 
		
	
		
			
			|  |  |  | config->bindToMipmapTexture = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_BIND_TO_TEXTURE_TARGETS_EXT: | 
		
	
		
			
			|  |  |  | config->bindToTextureTargets = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case GLX_Y_INVERTED_EXT: | 
		
	
		
			
			|  |  |  | config->yInverted = *bp++; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | case None: | 
		
	
		
			
			|  |  |  | i = count; | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | default: | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->renderType = | 
		
	
		
			
			|  |  |  | (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | config->haveAccumBuffer = ((config->accumRedBits + | 
		
	
		
			
			|  |  |  | config->accumGreenBits + | 
		
	
		
			
			|  |  |  | config->accumBlueBits + | 
		
	
		
			
			|  |  |  | config->accumAlphaBits) > 0); | 
		
	
		
			
			|  |  |  | config->haveDepthBuffer = (config->depthBits > 0); | 
		
	
		
			
			|  |  |  | config->haveStencilBuffer = (config->stencilBits > 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static __GLcontextModes * | 
		
	
		
			
			|  |  |  | createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, | 
		
	
		
			
			|  |  |  | int screen, GLboolean tagged_only) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | INT32 buf[__GLX_TOTAL_CONFIG], *props; | 
		
	
		
			
			|  |  |  | unsigned prop_size; | 
		
	
		
			
			|  |  |  | __GLcontextModes *modes, *m; | 
		
	
		
			
			|  |  |  | int i; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (nprops == 0) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Check number of properties */ | 
		
	
		
			
			|  |  |  | if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Allocate memory for our config structure */ | 
		
	
		
			
			|  |  |  | modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); | 
		
	
		
			
			|  |  |  | if (!modes) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | prop_size = nprops * __GLX_SIZE_INT32; | 
		
	
		
			
			|  |  |  | if (prop_size <= sizeof(buf)) | 
		
	
		
			
			|  |  |  | props = buf; | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | props = Xmalloc(prop_size); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* Read each config structure and convert it into our format */ | 
		
	
		
			
			|  |  |  | m = modes; | 
		
	
		
			
			|  |  |  | for (i = 0; i < nvisuals; i++) { | 
		
	
		
			
			|  |  |  | _XRead(dpy, (char *) props, prop_size); | 
		
	
		
			
			|  |  |  | /* Older X servers don't send this so we default it here. */ | 
		
	
		
			
			|  |  |  | m->drawableType = GLX_WINDOW_BIT; | 
		
	
		
			
			|  |  |  | __glXInitializeVisualConfigFromTags(m, nprops, props, | 
		
	
		
			
			|  |  |  | tagged_only, GL_TRUE); | 
		
	
		
			
			|  |  |  | m->screen = screen; | 
		
	
		
			
			|  |  |  | m = m->next; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (props != buf) | 
		
	
		
			
			|  |  |  | Xfree(props); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return modes; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static GLboolean | 
		
	
		
			
			|  |  |  | getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | xGLXGetVisualConfigsReq *req; | 
		
	
		
			
			|  |  |  | __GLXscreenConfigs *psc; | 
		
	
		
			
			|  |  |  | xGLXGetVisualConfigsReply reply; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | LockDisplay(dpy); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | psc = priv->screenConfigs + screen; | 
		
	
		
			
			|  |  |  | psc->visuals = NULL; | 
		
	
		
			
			|  |  |  | GetReq(GLXGetVisualConfigs, req); | 
		
	
		
			
			|  |  |  | req->reqType = priv->majorOpcode; | 
		
	
		
			
			|  |  |  | req->glxCode = X_GLXGetVisualConfigs; | 
		
	
		
			
			|  |  |  | req->screen = screen; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!_XReply(dpy, (xReply *) & reply, 0, False)) | 
		
	
		
			
			|  |  |  | goto out; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | psc->visuals = createConfigsFromProperties(dpy, | 
		
	
		
			
			|  |  |  | reply.numVisuals, | 
		
	
		
			
			|  |  |  | reply.numProps, | 
		
	
		
			
			|  |  |  | screen, GL_FALSE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | out: | 
		
	
		
			
			|  |  |  | UnlockDisplay(dpy); | 
		
	
		
			
			|  |  |  | return psc->visuals != NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static GLboolean | 
		
	
		
			
			|  |  |  | getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | xGLXGetFBConfigsReq *fb_req; | 
		
	
		
			
			|  |  |  | xGLXGetFBConfigsSGIXReq *sgi_req; | 
		
	
		
			
			|  |  |  | xGLXVendorPrivateWithReplyReq *vpreq; | 
		
	
		
			
			|  |  |  | xGLXGetFBConfigsReply reply; | 
		
	
		
			
			|  |  |  | __GLXscreenConfigs *psc; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | psc = priv->screenConfigs + screen; | 
		
	
		
			
			|  |  |  | psc->serverGLXexts = | 
		
	
		
			
			|  |  |  | __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | LockDisplay(dpy); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | psc->configs = NULL; | 
		
	
		
			
			|  |  |  | if (atof(priv->serverGLXversion) >= 1.3) { | 
		
	
		
			
			|  |  |  | GetReq(GLXGetFBConfigs, fb_req); | 
		
	
		
			
			|  |  |  | fb_req->reqType = priv->majorOpcode; | 
		
	
		
			
			|  |  |  | fb_req->glxCode = X_GLXGetFBConfigs; | 
		
	
		
			
			|  |  |  | fb_req->screen = screen; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { | 
		
	
		
			
			|  |  |  | GetReqExtra(GLXVendorPrivateWithReply, | 
		
	
		
			
			|  |  |  | sz_xGLXGetFBConfigsSGIXReq + | 
		
	
		
			
			|  |  |  | sz_xGLXVendorPrivateWithReplyReq, vpreq); | 
		
	
		
			
			|  |  |  | sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; | 
		
	
		
			
			|  |  |  | sgi_req->reqType = priv->majorOpcode; | 
		
	
		
			
			|  |  |  | sgi_req->glxCode = X_GLXVendorPrivateWithReply; | 
		
	
		
			
			|  |  |  | sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; | 
		
	
		
			
			|  |  |  | sgi_req->screen = screen; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | goto out; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!_XReply(dpy, (xReply *) & reply, 0, False)) | 
		
	
		
			
			|  |  |  | goto out; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | psc->configs = createConfigsFromProperties(dpy, | 
		
	
		
			
			|  |  |  | reply.numFBConfigs, | 
		
	
		
			
			|  |  |  | reply.numAttribs * 2, | 
		
	
		
			
			|  |  |  | screen, GL_TRUE); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | out: | 
		
	
		
			
			|  |  |  | UnlockDisplay(dpy); | 
		
	
		
			
			|  |  |  | return psc->configs != NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static GLboolean | 
		
	
		
			
			|  |  |  | AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | __GLXscreenConfigs *psc; | 
		
	
		
			
			|  |  |  | GLint i, screens; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** First allocate memory for the array of per screen configs. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | screens = ScreenCount(dpy); | 
		
	
		
			
			|  |  |  | psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs)); | 
		
	
		
			
			|  |  |  | if (!psc) { | 
		
	
		
			
			|  |  |  | return GL_FALSE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); | 
		
	
		
			
			|  |  |  | priv->screenConfigs = psc; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | priv->serverGLXversion = | 
		
	
		
			
			|  |  |  | __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION); | 
		
	
		
			
			|  |  |  | if (priv->serverGLXversion == NULL) { | 
		
	
		
			
			|  |  |  | FreeScreenConfigs(priv); | 
		
	
		
			
			|  |  |  | return GL_FALSE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (i = 0; i < screens; i++, psc++) { | 
		
	
		
			
			|  |  |  | getFBConfigs(dpy, priv, i); | 
		
	
		
			
			|  |  |  | getVisualConfigs(dpy, priv, i); | 
		
	
		
			
			|  |  |  | psc->scr = i; | 
		
	
		
			
			|  |  |  | psc->dpy = dpy; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | SyncHandle(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return GL_TRUE; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _X_HIDDEN void | 
		
	
		
			
			|  |  |  | __glXRelease(__GLXdisplayPrivate *dpyPriv) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | FreeScreenConfigs(dpyPriv); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (dpyPriv->serverGLXvendor) { | 
		
	
		
			
			|  |  |  | Xfree((char *) dpyPriv->serverGLXvendor); | 
		
	
		
			
			|  |  |  | dpyPriv->serverGLXvendor = NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | if (dpyPriv->serverGLXversion) { | 
		
	
		
			
			|  |  |  | Xfree((char *) dpyPriv->serverGLXversion); | 
		
	
		
			
			|  |  |  | dpyPriv->serverGLXversion = NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Xfree(dpyPriv); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | _X_HIDDEN __GLXdisplayPrivate * | 
		
	
		
			
			|  |  |  | __glXInitialize(Display * dpy) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | XExtDisplayInfo *info = __glXFindDisplay(dpy); | 
		
	
		
			
			|  |  |  | __GLXdisplayPrivate *dpyPriv; | 
		
	
		
			
			|  |  |  | int major, minor; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!XextHasExtension(info)) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* See if the versions are compatible */ | 
		
	
		
			
			|  |  |  | if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); | 
		
	
		
			
			|  |  |  | if (!dpyPriv) | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* | 
		
	
		
			
			|  |  |  | ** Init the display private and then read in the screen config | 
		
	
		
			
			|  |  |  | ** structures from the server. | 
		
	
		
			
			|  |  |  | */ | 
		
	
		
			
			|  |  |  | dpyPriv->majorOpcode = info->codes->major_opcode; | 
		
	
		
			
			|  |  |  | dpyPriv->majorVersion = major; | 
		
	
		
			
			|  |  |  | dpyPriv->minorVersion = minor; | 
		
	
		
			
			|  |  |  | dpyPriv->dpy = dpy; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | dpyPriv->serverGLXvendor = NULL; | 
		
	
		
			
			|  |  |  | dpyPriv->serverGLXversion = NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { | 
		
	
		
			
			|  |  |  | Xfree(dpyPriv); | 
		
	
		
			
			|  |  |  | return NULL; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return dpyPriv; | 
		
	
		
			
			|  |  |  | } |