Commit 61bc4fb7 authored by idr's avatar idr
Browse files

Add glx_query.c. Currently, the only function in that file is

__glXGetStringFromServer.  Other functions will likely be added in the
not too distant future.  Modify surrounding code to use
__glXGetStringFromServer.

As an aside, this fixes a long standing, dormant bug in
__glXInternalQueryServerString.  If memory could not be allocated to
hold the string retured by the server, _XEatData would be called with
'length'.  This is wrong.  'length' measures the size of the packet in
CARD32 units, but _XEatData expects the size to be in CARD8 units.
parent bbfefb63
...@@ -72,7 +72,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) ...@@ -72,7 +72,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc)
singlepix.c \ singlepix.c \
vertarr.c \ vertarr.c \
xfont.c \ xfont.c \
glx_pbuffer.c glx_pbuffer.c \
glx_query.c
GLX_OBJS = \ GLX_OBJS = \
clientattrib.o \ clientattrib.o \
...@@ -97,7 +98,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) ...@@ -97,7 +98,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc)
singlepix.o \ singlepix.o \
vertarr.o \ vertarr.o \
xfont.o \ xfont.o \
glx_pbuffer.o glx_pbuffer.o \
glx_query.o
GLX_DEFS = GlxDefines VidModeExtensionDefines GLX_DEFS = GlxDefines VidModeExtensionDefines
......
/*
* (C) Copyright IBM Corporation 2004
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS 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.
*/
/**
* \file glx_query.c
* Generic utility functions to query internal data from the server.
*
* \author Ian Romanick <idr@us.ibm.com>
*/
#include "glxclient.h"
/**
* GLX protocol structure for the ficticious "GXLGenericGetString" request.
*
* This is a non-existant protocol packet. It just so happens that all of
* the real protocol packets used to request a string from the server have
* an identical binary layout. The only difference between them is the
* meaning of the \c for_whom field and the value of the \c glxCode.
*/
typedef struct GLXGenericGetString {
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
/* These defines are only needed to make the GetReq macro happy.
*/
#define sz_xGLXGenericGetStringReq 12
#define X_GLXGenericGetString 0
/**
* Query the Server GLX string and cache it in the display private.
* This routine will allocate the necessay space for the string.
*/
char *
__glXGetStringFromServer( Display * dpy, int opcode, CARD32 glxCode,
CARD32 for_whom, CARD32 name )
{
xGLXGenericGetStringReq *req;
xGLXSingleReply reply;
int length;
int numbytes;
char * buf;
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;
}
...@@ -815,8 +815,8 @@ extern void _XSend(Display*, const void*, long); ...@@ -815,8 +815,8 @@ extern void _XSend(Display*, const void*, long);
extern void __glXInitializeVisualConfigFromTags( __GLcontextModes *config, extern void __glXInitializeVisualConfigFromTags( __GLcontextModes *config,
int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags ); int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags );
extern char *__glXInternalQueryServerString( Display *dpy, int opcode, extern char * __glXGetStringFromServer( Display * dpy, int opcode,
int screen, int name ); CARD32 glxCode, CARD32 for_whom, CARD32 name );
extern char *__glXstrdup(const char *str); extern char *__glXstrdup(const char *str);
......
...@@ -1464,43 +1464,6 @@ XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen, int *attribLi ...@@ -1464,43 +1464,6 @@ XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen, int *attribLi
return visualList; return visualList;
} }
/**
* Query the Server GLX string and cache it in the display private.
* This routine will allocate the necessay space for the string.
*/
char *__glXInternalQueryServerString( Display *dpy, int opcode,
int screen, int name )
{
xGLXQueryServerStringReq *req;
xGLXQueryServerStringReply reply;
int length, numbytes, slop;
char *buf;
/* Send the glXQueryServerString request */
LockDisplay(dpy);
GetReq(GLXQueryServerString,req);
req->reqType = opcode;
req->glxCode = X_GLXQueryServerString;
req->screen = screen;
req->name = name;
_XReply(dpy, (xReply*) &reply, 0, False);
length = reply.length;
numbytes = reply.n;
slop = numbytes * __GLX_SIZE_INT8 & 3;
buf = (char *)Xmalloc(numbytes);
if (!buf) {
/* Throw data on the floor */
_XEatData(dpy, length);
} else {
_XRead(dpy, (char *)buf, numbytes);
if (slop) _XEatData(dpy,4-slop);
}
UnlockDisplay(dpy);
SyncHandle();
return buf;
}
const char *GLX_PREFIX(glXQueryExtensionsString)( Display *dpy, int screen ) const char *GLX_PREFIX(glXQueryExtensionsString)( Display *dpy, int screen )
{ {
...@@ -1513,7 +1476,8 @@ const char *GLX_PREFIX(glXQueryExtensionsString)( Display *dpy, int screen ) ...@@ -1513,7 +1476,8 @@ const char *GLX_PREFIX(glXQueryExtensionsString)( Display *dpy, int screen )
if (!psc->effectiveGLXexts) { if (!psc->effectiveGLXexts) {
if (!psc->serverGLXexts) { if (!psc->serverGLXexts) {
psc->serverGLXexts = __glXInternalQueryServerString(dpy, priv->majorOpcode, psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
X_GLXQueryServerString,
screen, GLX_EXTENSIONS); screen, GLX_EXTENSIONS);
} }
...@@ -1557,21 +1521,21 @@ const char *GLX_PREFIX(glXQueryServerString)( Display *dpy, int screen, int name ...@@ -1557,21 +1521,21 @@ const char *GLX_PREFIX(glXQueryServerString)( Display *dpy, int screen, int name
case GLX_VENDOR: case GLX_VENDOR:
if (!priv->serverGLXvendor) { if (!priv->serverGLXvendor) {
priv->serverGLXvendor = priv->serverGLXvendor =
__glXInternalQueryServerString(dpy, priv->majorOpcode, __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString,
screen, GLX_VENDOR); screen, GLX_VENDOR);
} }
return(priv->serverGLXvendor); return(priv->serverGLXvendor);
case GLX_VERSION: case GLX_VERSION:
if (!priv->serverGLXversion) { if (!priv->serverGLXversion) {
priv->serverGLXversion = priv->serverGLXversion =
__glXInternalQueryServerString(dpy, priv->majorOpcode, __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString,
screen, GLX_VERSION); screen, GLX_VERSION);
} }
return(priv->serverGLXversion); return(priv->serverGLXversion);
case GLX_EXTENSIONS: case GLX_EXTENSIONS:
if (!psc->serverGLXexts) { if (!psc->serverGLXexts) {
psc->serverGLXexts = psc->serverGLXexts =
__glXInternalQueryServerString(dpy, priv->majorOpcode, __glXGetStringFromServer(dpy, priv->majorOpcode, X_GLXQueryServerString,
screen, GLX_EXTENSIONS); screen, GLX_EXTENSIONS);
} }
return(psc->serverGLXexts); return(psc->serverGLXexts);
......
...@@ -930,8 +930,9 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) ...@@ -930,8 +930,9 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
priv->screenConfigs = psc; priv->screenConfigs = psc;
priv->serverGLXversion = __glXInternalQueryServerString(dpy, priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
priv->majorOpcode, 0, GLX_VERSION); X_GLXQueryServerString,
0, GLX_VERSION);
if ( priv->serverGLXversion == NULL ) { if ( priv->serverGLXversion == NULL ) {
FreeScreenConfigs(priv); FreeScreenConfigs(priv);
return GL_FALSE; return GL_FALSE;
...@@ -948,8 +949,9 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) ...@@ -948,8 +949,9 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
*/ */
for (i = 0; i < screens; i++, psc++) { for (i = 0; i < screens; i++, psc++) {
if ( supported_request != 1 ) { if ( supported_request != 1 ) {
psc->serverGLXexts = __glXInternalQueryServerString(dpy, psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
priv->majorOpcode, i, GLX_EXTENSIONS); X_GLXQueryServerString,
i, GLX_EXTENSIONS);
if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) { if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) {
supported_request = 2; supported_request = 2;
} }
......
...@@ -900,43 +900,15 @@ const GLubyte *glGetString(GLenum name) ...@@ -900,43 +900,15 @@ const GLubyte *glGetString(GLenum name)
/* /*
** Get requested string from server ** Get requested string from server
*/ */
__GLX_SINGLE_LOAD_VARIABLES();
(void) __glXFlushRenderBuffer( gc, gc->pc );
s = __glXGetStringFromServer( dpy, gc->majorOpcode,
/* This is usually done by the __GLX_SINGLE_BEGIN macro. However, that X_GLsop_GetString, gc->currentContextTag,
* macro actually starts a new block and the __GLX_SINGLE_END macro closes name );
* it. The problem is that this function would need to use
* __GLX_SINGLE_END macro in two places, and both places are inside other
* blocks. The resulting code would either not compile or not work
* correctly.
*/
(void) __glXFlushRenderBuffer( gc, pc );
LockDisplay(dpy);
GetReqExtra( GLXSingle, 4, req );
req->reqType = gc->majorOpcode;
req->glxCode = X_GLsop_GetString;
req->contextTag = gc->currentContextTag;
pc = ((GLubyte *)(req) + sz_xGLXSingleReq);
__GLX_SINGLE_PUT_LONG(0,name);
__GLX_SINGLE_READ_XREPLY();
__GLX_SINGLE_GET_SIZE(compsize);
s = (GLubyte*) Xmalloc(compsize);
if (!s) { if (!s) {
/* Throw data on the floor */ /* Throw data on the floor */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY); __glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
} else { } else {
__GLX_SINGLE_GET_CHAR_ARRAY(s,compsize);
UnlockDisplay(dpy);
SyncHandle();
/* /*
** Update local cache ** Update local cache
*/ */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment