|
|
|
@@ -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; |
|
|
|
} |