diff options
Diffstat (limited to 'xorg-server/glx')
| -rw-r--r-- | xorg-server/glx/glxcmds.c | 4743 | ||||
| -rw-r--r-- | xorg-server/glx/glxcmdsswap.c | 1836 | 
2 files changed, 3302 insertions, 3277 deletions
| diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index 3ef567d10..d57dff5e0 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -1,2362 +1,2381 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. 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. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> -#include <assert.h> - -#include "glxserver.h" -#include <GL/glxtokens.h> -#include <unpack.h> -#include <pixmapstr.h> -#include <windowstr.h> -#include "glxutil.h" -#include "glxext.h" -#include "glapitable.h" -#include "glapi.h" -#include "glthread.h" -#include "dispatch.h" -#include "indirect_dispatch.h" -#include "indirect_table.h" -#include "indirect_util.h" - -static int -validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) -{ -    /* -    ** Check if screen exists. -    */ -    if (screen < 0 || screen >= screenInfo.numScreens) { -	client->errorValue = screen; -	*err = BadValue; -	return FALSE; -    } -    *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - -    return TRUE; -} - -static int -validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, -		 __GLXconfig **config, int *err) -{ -    __GLXconfig *m; - -    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) -	if (m->fbconfigID == id) { -	    *config = m; -	    return TRUE; -	} - -    client->errorValue = id; -    *err = __glXError(GLXBadFBConfig); - -    return FALSE; -} - -static int -validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, -	       __GLXconfig **config, int *err) -{ -    int i; - -    for (i = 0; i < pGlxScreen->numVisuals; i++) - 	if (pGlxScreen->visuals[i]->visualID == id) { -	    *config = pGlxScreen->visuals[i]; -	    return TRUE; -	} - -    client->errorValue = id; -    *err = BadValue; - -    return FALSE; -} - -static int -validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, -			  DrawablePtr pDraw, int *err) -{ -    ScreenPtr pScreen = pDraw->pScreen; -    VisualPtr pVisual = NULL; -    XID vid; -    int i; - -    vid = wVisual((WindowPtr)pDraw); -    for (i = 0; i < pScreen->numVisuals; i++) { -	if (pScreen->visuals[i].vid == vid) { -	    pVisual = &pScreen->visuals[i]; -	    break; -	} -    } - -    /* FIXME: What exactly should we check here... */ -    if (pVisual->class != glxConvertToXVisualType(config->visualType) || -	!(config->drawableType & GLX_WINDOW_BIT)) { -	client->errorValue = pDraw->id; -	*err = BadMatch; -	return FALSE; -    } - -    return TRUE; -} - -static int -validGlxContext(ClientPtr client, XID id, int access_mode, -		__GLXcontext **context, int *err) -{ -    *err = dixLookupResourceByType((pointer *) context, id, -				   __glXContextRes, client, access_mode); -    if (*err != Success) { -	client->errorValue = id; -	if (*err == BadValue) -	    *err = __glXError(GLXBadContext); -	return FALSE; -    } - -    return TRUE; -} - -static int -validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, -		 __GLXdrawable **drawable, int *err) -{ -    int rc; - -    rc = dixLookupResourceByType((pointer *) drawable, id, -				 __glXDrawableRes, client, access_mode); -    if (rc != Success && rc != BadValue) { -	*err = rc; -	client->errorValue = id; -	return FALSE; -    } - -    /* If the ID of the glx drawable we looked up doesn't match the id -     * we looked for, it's because we looked it up under the X -     * drawable ID (see DoCreateGLXDrawable). */ -    if (rc == BadValue || -	(*drawable)->drawId != id || -	(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { -	client->errorValue = id; -	switch (type) { -	case GLX_DRAWABLE_WINDOW: -	    *err = __glXError(GLXBadWindow); -	    return FALSE; -	case GLX_DRAWABLE_PIXMAP: -	    *err = __glXError(GLXBadPixmap); -	    return FALSE; -	case GLX_DRAWABLE_PBUFFER: -	    *err = __glXError(GLXBadPbuffer); -	    return FALSE; -	case GLX_DRAWABLE_ANY: -	    *err = __glXError(GLXBadDrawable); -	    return FALSE; -	} -    } - -    return TRUE; -} - -void -__glXContextDestroy(__GLXcontext *context) -{ -    __glXFlushContextCache(); -} - -static void __glXdirectContextDestroy(__GLXcontext *context) -{ -    __glXContextDestroy(context); -    free(context); -} - -static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, -					      __GLXconfig *modes, -					      __GLXcontext *shareContext) -{ -    __GLXcontext *context; - -    context = calloc(1, sizeof (__GLXcontext)); -    if (context == NULL) -	return NULL; - -    context->destroy = __glXdirectContextDestroy; - -    return context; -} - -/** - * Create a GL context with the given properties.  This routine is used - * to implement \c glXCreateContext, \c glXCreateNewContext, and - * \c glXCreateContextWithConfigSGIX.  This works becuase of the hack way - * that GLXFBConfigs are implemented.  Basically, the FBConfigID is the - * same as the VisualID. - */ - -static int -DoCreateContext(__GLXclientState *cl, GLXContextID gcId, -		GLXContextID shareList, __GLXconfig *config, -		__GLXscreen *pGlxScreen, GLboolean isDirect) -{ -    ClientPtr client = cl->client; -    __GLXcontext *glxc, *shareglxc; -    int err; -     -    LEGAL_NEW_RESOURCE(gcId, client); - -    /* -    ** Find the display list space that we want to share.   -    ** -    ** NOTE: In a multithreaded X server, we would need to keep a reference -    ** count for each display list so that if one client detroyed a list that  -    ** another client was using, the list would not really be freed until it  -    ** was no longer in use.  Since this sample implementation has no support  -    ** for multithreaded servers, we don't do this.   -    */ -    if (shareList == None) { -	shareglxc = 0; -    } else { -	if (!validGlxContext(client, shareList, DixReadAccess, -			     &shareglxc, &err)) -	    return err; - -	if (shareglxc->isDirect) { -	    /* -	    ** NOTE: no support for sharing display lists between direct -	    ** contexts, even if they are in the same address space. -	    */ -#if 0 -            /* Disabling this code seems to allow shared display lists -             * and texture objects to work.  We'll leave it disabled for now. -             */ -	    client->errorValue = shareList; -	    return BadMatch; -#endif -	} else { -	    /* -	    ** Create an indirect context regardless of what the client asked -	    ** for; this way we can share display list space with shareList. -	    */ -	    isDirect = GL_FALSE; -	} -    } - -    /* -    ** Allocate memory for the new context -    */ -    if (!isDirect) -	glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc); -    else -	glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); -    if (!glxc) { -	return BadAlloc; -    } - -    /* -    ** Initially, setup the part of the context that could be used by -    ** a GL core that needs windowing information (e.g., Mesa). -    */ -    glxc->pGlxScreen = pGlxScreen; -    glxc->config = config; - -    /* -    ** Register this context as a resource. -    */ -    if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { -	(*glxc->destroy)(glxc); -	client->errorValue = gcId; -	return BadAlloc; -    } -     -    /* -    ** Finally, now that everything is working, setup the rest of the -    ** context. -    */ -    glxc->id = gcId; -    glxc->share_id = shareList; -    glxc->idExists = GL_TRUE; -    glxc->isCurrent = GL_FALSE; -    glxc->isDirect = isDirect; -    glxc->renderMode = GL_RENDER; - -    __glXAddToContextList(glxc); - -    return Success; -} - -int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_SIZE_MATCH(xGLXCreateContextReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) -	return err; - -    return DoCreateContext(cl, req->context, req->shareList, -			   config, pGlxScreen, req->isDirect); -} - -int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_SIZE_MATCH(xGLXCreateNewContextReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) -	return err; - -    return DoCreateContext(cl, req->context, req->shareList, -			   config, pGlxScreen, req->isDirect); -} - -int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateContextWithConfigSGIXReq *req =  -	(xGLXCreateContextWithConfigSGIXReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) -	return err; - -    return DoCreateContext(cl, req->context, req->shareList, -			   config, pGlxScreen, req->isDirect); -} -int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; -    __GLXcontext *glxc; -    int err; - -    REQUEST_SIZE_MATCH(xGLXDestroyContextReq); - -    if (!validGlxContext(cl->client, req->context, DixDestroyAccess, -			 &glxc, &err)) -	    return err; - -    FreeResourceByType(req->context, __glXContextRes, FALSE); -    return Success; -} - -/*****************************************************************************/ - -/* -** For each client, the server keeps a table of all the contexts that are -** current for that client (each thread of a client may have its own current -** context).  These routines add, change, and lookup contexts in the table. -*/ - -/* -** Add a current context, and return the tag that will be used to refer to it. -*/ -static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc) -{ -    int i; -    int num = cl->numCurrentContexts; -    __GLXcontext **table = cl->currentContexts; - -    if (!glxc) return -1; -     -    /* -    ** Try to find an empty slot and use it. -    */ -    for (i=0; i < num; i++) { -	if (!table[i]) { -	    table[i] = glxc; -	    return i+1; -	} -    } -    /* -    ** Didn't find a free slot, so we'll have to grow the table. -    */ -    if (!num) { -	table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); -    } else { -	table = (__GLXcontext **) realloc(table, -					   (num+1)*sizeof(__GLXcontext *)); -    } -    table[num] = glxc; -    cl->currentContexts = table; -    cl->numCurrentContexts++; -    return num+1; -} - -/* -** Given a tag, change the current context for the corresponding entry. -*/ -static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, -				GLXContextTag tag) -{ -    __GLXcontext **table = cl->currentContexts; -    table[tag-1] = glxc; -} - -/* -** For this implementation we have chosen to simply use the index of the -** context's entry in the table as the context tag.  A tag must be greater -** than 0. -*/ -__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) -{ -    int num = cl->numCurrentContexts; - -    if (tag < 1 || tag > num) { -	return 0; -    } else { -	return cl->currentContexts[tag-1]; -    } -} - -/*****************************************************************************/ - -static void StopUsingContext(__GLXcontext *glxc) -{ -    if (glxc) { -	if (glxc == __glXLastContext) { -	    /* Tell server GL library */ -	    __glXLastContext = 0; -	} -	glxc->isCurrent = GL_FALSE; -	if (!glxc->idExists) { -	    __glXFreeContext(glxc); -	} -    } -} - -static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) -{ -    glxc->isCurrent = GL_TRUE; -    __glXLastContext = glxc;	 -} - -/** - * This is a helper function to handle the legacy (pre GLX 1.3) cases - * where passing an X window to glXMakeCurrent is valid.  Given a - * resource ID, look up the GLX drawable if available, otherwise, make - * sure it's an X window and create a GLX drawable one the fly. - */ -static __GLXdrawable * -__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, -		 int *error) -{ -    DrawablePtr pDraw; -    __GLXdrawable *pGlxDraw; -    int rc; - -    if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, -			 DixWriteAccess, &pGlxDraw, &rc)) { -	if (glxc != NULL && pGlxDraw->config != glxc->config) { -	    client->errorValue = drawId; -	    *error = BadMatch; -	    return NULL; -	} - -	return pGlxDraw; -    } - -    /* No active context and an unknown drawable, bail. */ -    if (glxc == NULL) { -	    client->errorValue = drawId; -	    *error = BadMatch; -	    return NULL; -    } - -    /* The drawId wasn't a GLX drawable.  Make sure it's a window and -     * create a GLXWindow for it.  Check that the drawable screen -     * matches the context screen and that the context fbconfig is -     * compatible with the window visual. */ - -    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); -    if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { -	client->errorValue = drawId; -	*error = __glXError(GLXBadDrawable); -	return NULL; -    } - -    if (pDraw->pScreen != glxc->pGlxScreen->pScreen) { -	client->errorValue = pDraw->pScreen->myNum; -	*error = BadMatch; -	return NULL; -    } - -    if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) -	return NULL; - -    pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen, -						pDraw, drawId, -						GLX_DRAWABLE_WINDOW, -						drawId, glxc->config); - -    /* since we are creating the drawablePrivate, drawId should be new */ -    if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { -	pGlxDraw->destroy (pGlxDraw); -	*error = BadAlloc; -	return NULL; -    } - -    return pGlxDraw; -} - -/*****************************************************************************/ -/* -** Make an OpenGL context and drawable current. -*/ - -static int -DoMakeCurrent(__GLXclientState *cl, -	      GLXDrawable drawId, GLXDrawable readId, -	      GLXContextID contextId, GLXContextTag tag) -{ -    ClientPtr client = cl->client; -    xGLXMakeCurrentReply reply; -    __GLXcontext *glxc, *prevglxc; -    __GLXdrawable *drawPriv = NULL; -    __GLXdrawable *readPriv = NULL; -    int error; -    GLuint  mask; - -    /* -    ** If one is None and the other isn't, it's a bad match. -    */ - -    mask  = (drawId == None)    ? (1 << 0) : 0; -    mask |= (readId == None)    ? (1 << 1) : 0; -    mask |= (contextId == None) ? (1 << 2) : 0; - -    if ( (mask != 0x00) && (mask != 0x07) ) { -	return BadMatch; -    } -     -    /* -    ** Lookup old context.  If we have one, it must be in a usable state. -    */ -    if (tag != 0) { -	prevglxc = __glXLookupContextByTag(cl, tag); -	if (!prevglxc) { -	    /* -	    ** Tag for previous context is invalid. -	    */ -	    return __glXError(GLXBadContextTag); -	} -	if (prevglxc->renderMode != GL_RENDER) { -	    /* Oops.  Not in render mode render. */ -	    client->errorValue = prevglxc->id; -	    return __glXError(GLXBadContextState); -	} -    } else { -	prevglxc = 0; -    } - -    /* -    ** Lookup new context.  It must not be current for someone else. -    */ -    if (contextId != None) { -	int  status; - -	if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) -	    return error; -	if ((glxc != prevglxc) && glxc->isCurrent) { -	    /* Context is current to somebody else */ -	    return BadAccess; -	} - -	assert( drawId != None ); -	assert( readId != None ); - -	drawPriv = __glXGetDrawable(glxc, drawId, client, &status); -	if (drawPriv == NULL) -	    return status; - -	readPriv = __glXGetDrawable(glxc, readId, client, &status); -	if (readPriv == NULL) -	    return status; - -    } else { -	/* Switching to no context.  Ignore new drawable. */ -	glxc = 0; -	drawPriv = 0; -	readPriv = 0; -    } - - -    if (prevglxc) { -	/* -	** Flush the previous context if needed. -	*/ -	if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) { -	    if (__glXForceCurrent(cl, tag, (int *)&error)) { -		CALL_Flush( GET_DISPATCH(), () ); -		__GLX_NOTE_FLUSHED_CMDS(prevglxc); -	    } else { -		return error; -	    } -	} - -	/* -	** Make the previous context not current. -	*/ -	if (!(*prevglxc->loseCurrent)(prevglxc)) { -	    return __glXError(GLXBadContext); -	} -	__glXFlushContextCache(); -	if (!prevglxc->isDirect) { -	    prevglxc->drawPriv = NULL; -	    prevglxc->readPriv = NULL; -	} -    } -	 - -    if ((glxc != 0) && !glxc->isDirect) { - -	glxc->drawPriv = drawPriv; -	glxc->readPriv = readPriv; - -	/* make the context current */ -	if (!(*glxc->makeCurrent)(glxc)) { -	    glxc->drawPriv = NULL; -	    glxc->readPriv = NULL; -	    return __glXError(GLXBadContext); -	} - -	glxc->isCurrent = GL_TRUE; -    } - -    if (prevglxc) { -	ChangeCurrentContext(cl, glxc, tag); -	StopUsingContext(prevglxc); -    } else { -	tag = AddCurrentContext(cl, glxc); -    } - -    if (glxc) { -	StartUsingContext(cl, glxc); -	reply.contextTag = tag; -    } else { -	reply.contextTag = 0; -    } - -    reply.length = 0; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; - -    if (client->swapped) { -	__glXSwapMakeCurrentReply(client, &reply); -    } else { -	WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply); -    } -    return Success; -} - -int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXMakeCurrentReq); - -    return DoMakeCurrent( cl, req->drawable, req->drawable, -			  req->context, req->oldContextTag ); -} - -int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq); - -    return DoMakeCurrent( cl, req->drawable, req->readdrawable, -			  req->context, req->oldContextTag ); -} - -int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq); - -    return DoMakeCurrent( cl, req->drawable, req->readable, -			  req->context, req->oldContextTag ); -} - -int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; -    xGLXIsDirectReply reply; -    __GLXcontext *glxc; -    int err; - -    REQUEST_SIZE_MATCH(xGLXIsDirectReq); - -    if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) -	return err; - -    reply.isDirect = glxc->isDirect; -    reply.length = 0; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; - -    if (client->swapped) { -	__glXSwapIsDirectReply(client, &reply); -    } else { -	WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); -    } - -    return Success; -} - -int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; -    xGLXQueryVersionReply reply; -    GLuint major, minor; - -    REQUEST_SIZE_MATCH(xGLXQueryVersionReq); - -    major = req->majorVersion; -    minor = req->minorVersion; -    (void)major; -    (void)minor; - -    /* -    ** Server should take into consideration the version numbers sent by the -    ** client if it wants to work with older clients; however, in this -    ** implementation the server just returns its version number. -    */ -    reply.majorVersion = glxMajorVersion; -    reply.minorVersion = glxMinorVersion; -    reply.length = 0; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; - -    if (client->swapped) { -	__glXSwapQueryVersionReply(client, &reply); -    } else { -	WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); -    } -    return Success; -} - -int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; -    GLXContextTag tag; -    __GLXcontext *glxc = NULL; -    int error; - -    REQUEST_SIZE_MATCH(xGLXWaitGLReq); - -    tag = req->contextTag; -    if (tag) { -	glxc = __glXLookupContextByTag(cl, tag); -	if (!glxc) -	    return __glXError(GLXBadContextTag); -     -	if (!__glXForceCurrent(cl, req->contextTag, &error)) -	    return error; - -	CALL_Finish( GET_DISPATCH(), () ); -    } - -    if (glxc && glxc->drawPriv->waitGL) -	(*glxc->drawPriv->waitGL)(glxc->drawPriv); - -    return Success; -} - -int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXWaitXReq *req = (xGLXWaitXReq *)pc; -    GLXContextTag tag; -    __GLXcontext *glxc = NULL; -    int error; - -    REQUEST_SIZE_MATCH(xGLXWaitXReq); - -    tag = req->contextTag; -    if (tag) { -	glxc = __glXLookupContextByTag(cl, tag); -	if (!glxc) -	    return __glXError(GLXBadContextTag); -     -	if (!__glXForceCurrent(cl, req->contextTag, &error)) -	    return error; -    } - -    if (glxc && glxc->drawPriv->waitX) -	(*glxc->drawPriv->waitX)(glxc->drawPriv); - -    return Success; -} - -int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; -    GLXContextID source; -    GLXContextID dest; -    GLXContextTag tag; -    unsigned long mask; -    __GLXcontext *src, *dst; -    int error; - -    REQUEST_SIZE_MATCH(xGLXCopyContextReq); - -    source = req->source; -    dest = req->dest; -    tag = req->contextTag; -    mask = req->mask; -    if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) -	return error; -    if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) -	return error; - -    /* -    ** They must be in the same address space, and same screen. -    ** NOTE: no support for direct rendering contexts here. -    */ -    if (src->isDirect || dst->isDirect || -	(src->pGlxScreen != dst->pGlxScreen)) { -	client->errorValue = source; -	return BadMatch; -    } - -    /* -    ** The destination context must not be current for any client. -    */ -    if (dst->isCurrent) { -	client->errorValue = dest; -	return BadAccess; -    } - -    if (tag) { -	__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); -	 -	if (!tagcx) { -	    return __glXError(GLXBadContextTag); -	} -	if (tagcx != src) { -	    /* -	    ** This would be caused by a faulty implementation of the client -	    ** library. -	    */ -	    return BadMatch; -	} -	/* -	** In this case, glXCopyContext is in both GL and X streams, in terms -	** of sequentiality. -	*/ -	if (__glXForceCurrent(cl, tag, &error)) { -	    /* -	    ** Do whatever is needed to make sure that all preceding requests -	    ** in both streams are completed before the copy is executed. -	    */ -	    CALL_Finish( GET_DISPATCH(), () ); -	    __GLX_NOTE_FLUSHED_CMDS(tagcx); -	} else { -	    return error; -	} -    } -    /* -    ** Issue copy.  The only reason for failure is a bad mask. -    */ -    if (!(*dst->copy)(dst, src, mask)) { -	client->errorValue = mask; -	return BadValue; -    } -    return Success; -} - -enum { -    GLX_VIS_CONFIG_UNPAIRED = 18, -    GLX_VIS_CONFIG_PAIRED = 20 -}; - -enum { -    GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED -}; - -int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; -    ClientPtr client = cl->client; -    xGLXGetVisualConfigsReply reply; -    __GLXscreen *pGlxScreen; -    __GLXconfig *modes; -    CARD32 buf[GLX_VIS_CONFIG_TOTAL]; -    int p, i, err; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; - -    reply.numVisuals = pGlxScreen->numVisuals; -    reply.numProps = GLX_VIS_CONFIG_TOTAL; -    reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; - -    if (client->swapped) { -	__GLX_SWAP_SHORT(&reply.sequenceNumber); -	__GLX_SWAP_INT(&reply.length); -	__GLX_SWAP_INT(&reply.numVisuals); -	__GLX_SWAP_INT(&reply.numProps); -    } - -    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - -    for (i = 0; i < pGlxScreen->numVisuals; i++) { -	modes = pGlxScreen->visuals[i]; - -	p = 0; -	buf[p++] = modes->visualID; -	buf[p++] = glxConvertToXVisualType( modes->visualType ); -	buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE; - -	buf[p++] = modes->redBits; -	buf[p++] = modes->greenBits; -	buf[p++] = modes->blueBits; -	buf[p++] = modes->alphaBits; -	buf[p++] = modes->accumRedBits; -	buf[p++] = modes->accumGreenBits; -	buf[p++] = modes->accumBlueBits; -	buf[p++] = modes->accumAlphaBits; - -	buf[p++] = modes->doubleBufferMode; -	buf[p++] = modes->stereoMode; - -	buf[p++] = modes->rgbBits; -	buf[p++] = modes->depthBits; -	buf[p++] = modes->stencilBits; -	buf[p++] = modes->numAuxBuffers; -	buf[p++] = modes->level; - -	assert(p == GLX_VIS_CONFIG_UNPAIRED); -	/*  -	** Add token/value pairs for extensions. -	*/ -	buf[p++] = GLX_VISUAL_CAVEAT_EXT; -	buf[p++] = modes->visualRating; -	buf[p++] = GLX_TRANSPARENT_TYPE; -	buf[p++] = modes->transparentPixel; -	buf[p++] = GLX_TRANSPARENT_RED_VALUE; -	buf[p++] = modes->transparentRed; -	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; -	buf[p++] = modes->transparentGreen; -	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; -	buf[p++] = modes->transparentBlue; -	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; -	buf[p++] = modes->transparentAlpha; -	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; -	buf[p++] = modes->transparentIndex; -	buf[p++] = GLX_SAMPLES_SGIS; -	buf[p++] = modes->samples; -	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; -	buf[p++] = modes->sampleBuffers; -	buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */ -	buf[p++] = 0; - -	assert(p == GLX_VIS_CONFIG_TOTAL); -	if (client->swapped) { -	    __GLX_SWAP_INT_ARRAY(buf, p); -	} -	WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf); -    } -    return Success; -} - -#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36) -#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) -/** - * Send the set of GLXFBConfigs to the client.  There is not currently - * and interface into the driver on the server-side to get GLXFBConfigs, - * so we "invent" some based on the \c __GLXvisualConfig structures that - * the driver does supply. - *  - * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX - * is the same, so this routine pulls double duty. - */ - -static int -DoGetFBConfigs(__GLXclientState *cl, unsigned screen) -{ -    ClientPtr client = cl->client; -    xGLXGetFBConfigsReply reply; -    __GLXscreen *pGlxScreen; -    CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; -    int p, err; -    __GLXconfig *modes; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - -    if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) -	return err; - -    reply.numFBConfigs = pGlxScreen->numFBConfigs; -    reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; -    reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; - -    if (client->swapped) { -	__GLX_SWAP_SHORT(&reply.sequenceNumber); -	__GLX_SWAP_INT(&reply.length); -	__GLX_SWAP_INT(&reply.numFBConfigs); -	__GLX_SWAP_INT(&reply.numAttribs); -    } - -    WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); - -    for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { -	p = 0; - -#define WRITE_PAIR(tag,value) \ -    do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) - -	WRITE_PAIR( GLX_VISUAL_ID,        modes->visualID ); -	WRITE_PAIR( GLX_FBCONFIG_ID,      modes->fbconfigID ); -	WRITE_PAIR( GLX_X_RENDERABLE,     GL_TRUE ); - -	WRITE_PAIR( GLX_RGBA, -		    (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE ); -	WRITE_PAIR( GLX_RENDER_TYPE,      modes->renderType ); -	WRITE_PAIR( GLX_DOUBLEBUFFER,     modes->doubleBufferMode ); -	WRITE_PAIR( GLX_STEREO,           modes->stereoMode ); - -	WRITE_PAIR( GLX_BUFFER_SIZE,      modes->rgbBits ); -	WRITE_PAIR( GLX_LEVEL,            modes->level ); -	WRITE_PAIR( GLX_AUX_BUFFERS,      modes->numAuxBuffers ); -	WRITE_PAIR( GLX_RED_SIZE,         modes->redBits ); -	WRITE_PAIR( GLX_GREEN_SIZE,       modes->greenBits ); -	WRITE_PAIR( GLX_BLUE_SIZE,        modes->blueBits ); -	WRITE_PAIR( GLX_ALPHA_SIZE,       modes->alphaBits ); -	WRITE_PAIR( GLX_ACCUM_RED_SIZE,   modes->accumRedBits ); -	WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits ); -	WRITE_PAIR( GLX_ACCUM_BLUE_SIZE,  modes->accumBlueBits ); -	WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); -	WRITE_PAIR( GLX_DEPTH_SIZE,       modes->depthBits ); -	WRITE_PAIR( GLX_STENCIL_SIZE,     modes->stencilBits ); -	WRITE_PAIR( GLX_X_VISUAL_TYPE,    modes->visualType ); -	WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); -	WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); -	WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); -	WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen ); -	WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue ); -	WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); -	WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); -	WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); -	WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples ); -	WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers ); -	/* GLX_VISUAL_SELECT_GROUP_SGIX ? */ -	WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType ); -	WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb ); -	WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba ); -	WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture ); -	WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets ); - -	if (client->swapped) { -	    __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); -	} -	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH, -		      (char *)buf); -    } -    return Success; -} - - -int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; -    REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq); -    return DoGetFBConfigs(cl, req->screen); -} - -int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; -    REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq); -    return DoGetFBConfigs(cl, req->screen); -} - -GLboolean -__glXDrawableInit(__GLXdrawable *drawable, -		  __GLXscreen *screen, DrawablePtr pDraw, int type, -		  XID drawId, __GLXconfig *config) -{ -    drawable->pDraw = pDraw; -    drawable->type = type; -    drawable->drawId = drawId; -    drawable->config = config; -    drawable->eventMask = 0; - -    return GL_TRUE; -} - -void -__glXDrawableRelease(__GLXdrawable *drawable) -{ -} - -static int  -DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, -		    __GLXconfig *config, DrawablePtr pDraw, XID drawableId, -		    XID glxDrawableId, int type) -{ -    __GLXdrawable *pGlxDraw; - -    if (pGlxScreen->pScreen != pDraw->pScreen) -	return BadMatch; - -    pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, -					  drawableId, type, -					  glxDrawableId, config); -    if (pGlxDraw == NULL) -	return BadAlloc; - -    if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) { -	pGlxDraw->destroy (pGlxDraw); -	return BadAlloc; -    } - -    /* Add the glx drawable under the XID of the underlying X drawable -     * too.  That way we'll get a callback in DrawableGone and can -     * clean up properly when the drawable is destroyed. */ -    if (drawableId != glxDrawableId && -	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { -	pGlxDraw->destroy (pGlxDraw); -	return BadAlloc; -    } - -    return Success; -} - -static int -DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, -		  XID drawableId, XID glxDrawableId) -{ -    DrawablePtr pDraw; -    int err; - -    LEGAL_NEW_RESOURCE(glxDrawableId, client); - -    err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); -    if (err != Success) { -	client->errorValue = drawableId; -	return err; -    } -    if (pDraw->type != DRAWABLE_PIXMAP) { -	client->errorValue = drawableId; -	return BadPixmap; -    } - -    err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, -			      glxDrawableId, GLX_DRAWABLE_PIXMAP); - -    return err; -} - -static void -determineTextureTarget(ClientPtr client, XID glxDrawableID, -		       CARD32 *attribs, CARD32 numAttribs) -{ -    GLenum target = 0; -    GLenum format = 0; -    int i, err; -    __GLXdrawable *pGlxDraw; - -    if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, -			  DixWriteAccess, &pGlxDraw, &err)) -	/* We just added it in CreatePixmap, so we should never get here. */ -	return; - -    for (i = 0; i < numAttribs; i++) { -	if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { -	    switch (attribs[2 * i + 1]) { -	    case GLX_TEXTURE_2D_EXT: -		target = GL_TEXTURE_2D; -		break; -	    case GLX_TEXTURE_RECTANGLE_EXT: -		target = GL_TEXTURE_RECTANGLE_ARB; -		break; -	    } -	} - -	if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) -		format = attribs[2 * i + 1]; -    } -  -    if (!target) { -	int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height; -	 -	if (h & (h - 1) || w & (w - 1)) -	    target = GL_TEXTURE_RECTANGLE_ARB; -	else -	    target = GL_TEXTURE_2D; -    } - -    pGlxDraw->target = target; -    pGlxDraw->format = format; -} - -int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) -	return err; - -    return DoCreateGLXPixmap(cl->client, pGlxScreen, config, -			     req->pixmap, req->glxpixmap); -} - -int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) -	return err; - -    err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, -			    req->pixmap, req->glxpixmap); -    if (err != Success) -	return err; - -    determineTextureTarget(cl->client, req->glxpixmap, -			   (CARD32*) (req + 1), req->numAttribs); - -    return Success; -} - -int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPixmapWithConfigSGIXReq *req =  -	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; -    __GLXconfig *config; -    __GLXscreen *pGlxScreen; -    int err; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); - -    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) -	return err; - -    return DoCreateGLXPixmap(cl->client, pGlxScreen, -			     config, req->pixmap, req->glxpixmap); -} - - -static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) -{ -    __GLXdrawable *pGlxDraw; -    int err; - -    if (!validGlxDrawable(cl->client, glxdrawable, type, -			  DixDestroyAccess, &pGlxDraw, &err)) -	return err; - -    FreeResource(glxdrawable, FALSE); - -    return Success; -} - -int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); - -    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); -} - -int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXDestroyPixmapReq); - -    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); -} - -static int -DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, -		int width, int height, XID glxDrawableId) -{ -    __GLXconfig	*config; -    __GLXscreen		*pGlxScreen; -    PixmapPtr		 pPixmap; -    int			 err; - -    LEGAL_NEW_RESOURCE(glxDrawableId, client); - -    if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) -	return err; - -    __glXenterServer(GL_FALSE); -    pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, -						    width, height, config->rgbBits, 0); -    __glXleaveServer(GL_FALSE); - -    /* Assign the pixmap the same id as the pbuffer and add it as a -     * resource so it and the DRI2 drawable will be reclaimed when the -     * pbuffer is destroyed. */ -    pPixmap->drawable.id = glxDrawableId; -    if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap)) -	return BadAlloc; - -    return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, -			       glxDrawableId, glxDrawableId, -			       GLX_DRAWABLE_PBUFFER); -} - -int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreatePbufferReq	*req = (xGLXCreatePbufferReq *) pc; -    CARD32			*attrs; -    int				 width, height, i; - -    REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); - -    attrs = (CARD32 *) (req + 1); -    width = 0; -    height = 0; - -    for (i = 0; i < req->numAttribs; i++) { -	switch (attrs[i * 2]) { -	case GLX_PBUFFER_WIDTH: -	    width = attrs[i * 2 + 1]; -	    break; -	case GLX_PBUFFER_HEIGHT: -	    height = attrs[i * 2 + 1]; -	    break; -	case GLX_LARGEST_PBUFFER: -	case GLX_PRESERVED_CONTENTS: -	    /* FIXME: huh... */ -	    break; -	} -    } - -    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, -			   width, height, req->pbuffer); -} - -int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPbufferSGIXReq); - -    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, -			   req->width, req->height, req->pbuffer); -} - -int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); - -    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); -} - -int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); - -    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); -} - -static int -DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, -			   int numAttribs, CARD32 *attribs) -{ -    __GLXdrawable *pGlxDraw; -    int i, err; - -    if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, -			  DixSetAttrAccess, &pGlxDraw, &err)) -	return err; - -    for (i = 0; i < numAttribs; i++) { -	switch(attribs[i * 2]) { -	case GLX_EVENT_MASK: -	    /* All we do is to record the event mask so we can send it -	     * back when queried.  We never actually clobber the -	     * pbuffers, so we never need to send out the event. */ -	    pGlxDraw->eventMask = attribs[i * 2 + 1]; -	    break; -	} -    } - -    return Success; -} - -int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXChangeDrawableAttributesReq *req = -	(xGLXChangeDrawableAttributesReq *) pc; - -    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); - -    return DoChangeDrawableAttributes(cl->client, req->drawable, -				      req->numAttribs, (CARD32 *) (req + 1)); -} - -int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXChangeDrawableAttributesSGIXReq *req = -	(xGLXChangeDrawableAttributesSGIXReq *)pc; - -    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); - -    return DoChangeDrawableAttributes(cl->client, req->drawable, -				      req->numAttribs, (CARD32 *) (req + 1)); -} - -int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXCreateWindowReq	*req = (xGLXCreateWindowReq *) pc; -    __GLXconfig	*config; -    __GLXscreen		*pGlxScreen; -    ClientPtr		 client = cl->client; -    DrawablePtr		 pDraw; -    int			 err; - -    REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); - -    LEGAL_NEW_RESOURCE(req->glxwindow, client); - -    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) -	return err; -    if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) -	return err; - -    err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); -    if (err != Success || pDraw->type != DRAWABLE_WINDOW) { -	client->errorValue = req->window; -	return BadWindow; -    } - -    if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) -	return err; - -    return DoCreateGLXDrawable(client, pGlxScreen, config, -			       pDraw, req->window, -			       req->glxwindow, GLX_DRAWABLE_WINDOW); -} - -int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXDestroyWindowReq); - -    return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW); -} - - -/*****************************************************************************/ - -/* -** NOTE: There is no portable implementation for swap buffers as of -** this time that is of value.  Consequently, this code must be -** implemented by somebody other than SGI. -*/ -int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; -    GLXContextTag tag; -    XID drawId; -    __GLXcontext *glxc = NULL; -    __GLXdrawable *pGlxDraw; -    int error; - -    REQUEST_SIZE_MATCH(xGLXSwapBuffersReq); - -    tag = req->contextTag; -    drawId = req->drawable; -    if (tag) { -	glxc = __glXLookupContextByTag(cl, tag); -	if (!glxc) { -	    return __glXError(GLXBadContextTag); -	} -	/* -	** The calling thread is swapping its current drawable.  In this case, -	** glxSwapBuffers is in both GL and X streams, in terms of -	** sequentiality. -	*/ -	if (__glXForceCurrent(cl, tag, &error)) { -	    /* -	    ** Do whatever is needed to make sure that all preceding requests -	    ** in both streams are completed before the swap is executed. -	    */ -	    CALL_Finish( GET_DISPATCH(), () ); -	    __GLX_NOTE_FLUSHED_CMDS(glxc); -	} else { -	    return error; -	} -    } - -    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); -    if (pGlxDraw == NULL) -	return error; - -    if (pGlxDraw->type == DRAWABLE_WINDOW && -	(*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE) -	return __glXError(GLXBadDrawable); - -    return Success; -} - - -static int -DoQueryContext(__GLXclientState *cl, GLXContextID gcId) -{ -    ClientPtr client = cl->client; -    __GLXcontext *ctx; -    xGLXQueryContextInfoEXTReply reply; -    int nProps; -    int *sendBuf, *pSendBuf; -    int nReplyBytes; -    int err; - -    if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) -	return err; - -    nProps = 3; -    reply.length = nProps << 1; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; -    reply.n = nProps; - -    nReplyBytes = reply.length << 2; -    sendBuf = (int *)malloc((size_t)nReplyBytes); -    if (sendBuf == NULL) { -	return __glXError(GLXBadContext);	/* XXX: Is this correct? */ -    } -    pSendBuf = sendBuf; -    *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; -    *pSendBuf++ = (int)(ctx->share_id); -    *pSendBuf++ = GLX_VISUAL_ID_EXT; -    *pSendBuf++ = (int)(ctx->config->visualID); -    *pSendBuf++ = GLX_SCREEN_EXT; -    *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum); - -    if (client->swapped) { -	__glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); -    } else { -	WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); -	WriteToClient(client, nReplyBytes, (char *)sendBuf); -    } -    free((char *)sendBuf); - -    return Success; -} - -int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); - -    return DoQueryContext(cl, req->context); -} - -int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; - -    REQUEST_SIZE_MATCH(xGLXQueryContextReq); - -    return DoQueryContext(cl, req->context); -} - -int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    ClientPtr		 client = cl->client; -    __GLXcontext	*context; -    __GLXdrawable	*pGlxDraw; -    GLXDrawable		 drawId; -    int			 buffer; -    int			 error; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    drawId = *((CARD32 *) (pc)); -    buffer = *((INT32 *)  (pc + 4)); - -    if (buffer != GLX_FRONT_LEFT_EXT) -	return __glXError(GLXBadPixmap); - -    context = __glXForceCurrent (cl, req->contextTag, &error); -    if (!context) -	return error; - -    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, -			  DixReadAccess, &pGlxDraw, &error)) -	return error; - -    if (!context->textureFromPixmap) -	return __glXError(GLXUnsupportedPrivateRequest); - -    return context->textureFromPixmap->bindTexImage(context, -						    buffer, -						    pGlxDraw); -} - -int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    ClientPtr		 client = cl->client; -    __GLXdrawable	*pGlxDraw; -    __GLXcontext	*context; -    GLXDrawable		 drawId; -    int			 buffer; -    int			 error; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    drawId = *((CARD32 *) (pc)); -    buffer = *((INT32 *)  (pc + 4)); -     -    context = __glXForceCurrent (cl, req->contextTag, &error); -    if (!context) -	return error; - -    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, -			  DixReadAccess, &pGlxDraw, &error)) -	return error; - -    if (!context->textureFromPixmap) -	return __glXError(GLXUnsupportedPrivateRequest); - -    return context->textureFromPixmap->releaseTexImage(context, -						       buffer, -						       pGlxDraw); -} - -int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLXContextTag         tag = req->contextTag; -    __GLXcontext         *glxc = NULL; -    __GLXdrawable        *pGlxDraw; -    ClientPtr		  client = cl->client; -    GLXDrawable		  drawId; -    int                   error; -    int                   x, y, width, height; - -    (void) client; -    (void) req; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    drawId = *((CARD32 *) (pc)); -    x      = *((INT32 *)  (pc + 4)); -    y      = *((INT32 *)  (pc + 8)); -    width  = *((INT32 *)  (pc + 12)); -    height = *((INT32 *)  (pc + 16)); - -    if (tag) { -	glxc = __glXLookupContextByTag(cl, tag); -	if (!glxc) { -	    return __glXError(GLXBadContextTag); -	} -	/* -	** The calling thread is swapping its current drawable.  In this case, -	** glxSwapBuffers is in both GL and X streams, in terms of -	** sequentiality. -	*/ -	if (__glXForceCurrent(cl, tag, &error)) { -	    /* -	    ** Do whatever is needed to make sure that all preceding requests -	    ** in both streams are completed before the swap is executed. -	    */ -	    CALL_Finish( GET_DISPATCH(), () ); -	    __GLX_NOTE_FLUSHED_CMDS(glxc); -	} else { -	    return error; -	} -    } - -    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); -    if (!pGlxDraw) -	return error; - -    if (pGlxDraw == NULL || -	pGlxDraw->type != GLX_DRAWABLE_WINDOW || -	pGlxDraw->copySubBuffer == NULL) -	return __glXError(GLXBadDrawable); - -    (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height); - -    return Success; -} - -/* -** Get drawable attributes -*/ -static int -DoGetDrawableAttributes(__GLXclientState *cl, XID drawId) -{ -    ClientPtr client = cl->client; -    xGLXGetDrawableAttributesReply reply; -    __GLXdrawable *pGlxDraw; -    CARD32 attributes[6]; -    int numAttribs, error; - -    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, -			  DixGetAttrAccess, &pGlxDraw, &error)) -	return error; - -    numAttribs = 3; -    reply.length = numAttribs << 1; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; -    reply.numAttribs = numAttribs; - -    attributes[0] = GLX_TEXTURE_TARGET_EXT; -    attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : -	GLX_TEXTURE_RECTANGLE_EXT; -    attributes[2] = GLX_Y_INVERTED_EXT; -    attributes[3] = GL_FALSE; -    attributes[4] = GLX_EVENT_MASK; -    attributes[5] = pGlxDraw->eventMask; - -    if (client->swapped) { -	__glXSwapGetDrawableAttributesReply(client, &reply, attributes); -    } else { -	WriteToClient(client, sz_xGLXGetDrawableAttributesReply, -		      (char *)&reply); -	WriteToClient(client, reply.length * sizeof (CARD32), -		      (char *)attributes); -    } - -    return Success; -} - -int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; - -    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq); - -    return DoGetDrawableAttributes(cl, req->drawable); -} - -int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetDrawableAttributesSGIXReq *req = -	(xGLXGetDrawableAttributesSGIXReq *)pc; -     -    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); - -    return DoGetDrawableAttributes(cl, req->drawable); -} - -/************************************************************************/ - -/* -** Render and Renderlarge are not in the GLX API.  They are used by the GLX -** client library to send batches of GL rendering commands. -*/ - -/* -** Execute all the drawing commands in a request. -*/ -int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXRenderReq *req; -    ClientPtr client= cl->client; -    int left, cmdlen, error; -    int commandsDone; -    CARD16 opcode; -    __GLXrenderHeader *hdr; -    __GLXcontext *glxc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_AT_LEAST_SIZE(xGLXRenderReq); - -    req = (xGLXRenderReq *) pc; -    if (client->swapped) { -	__GLX_SWAP_SHORT(&req->length); -	__GLX_SWAP_INT(&req->contextTag); -    } - -    glxc = __glXForceCurrent(cl, req->contextTag, &error); -    if (!glxc) { -	return error; -    } - -    commandsDone = 0; -    pc += sz_xGLXRenderReq; -    left = (req->length << 2) - sz_xGLXRenderReq; -    while (left > 0) { -        __GLXrenderSizeData entry; -        int extra; -	__GLXdispatchRenderProcPtr proc; -	int err; - -	if (left < sizeof(__GLXrenderHeader)) -	    return BadLength; - -	/* -	** Verify that the header length and the overall length agree. -	** Also, each command must be word aligned. -	*/ -	hdr = (__GLXrenderHeader *) pc; -	if (client->swapped) { -	    __GLX_SWAP_SHORT(&hdr->length); -	    __GLX_SWAP_SHORT(&hdr->opcode); -	} -	cmdlen = hdr->length; -	opcode = hdr->opcode; - -	/* -	** Check for core opcodes and grab entry data. -	*/ -	err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); -	proc = (__GLXdispatchRenderProcPtr) -	    __glXGetProtocolDecodeFunction(& Render_dispatch_info, -					   opcode, client->swapped); - -	if ((err < 0) || (proc == NULL)) { -	    client->errorValue = commandsDone; -	    return __glXError(GLXBadRenderRequest); -	} - -        if (entry.varsize) { -            /* variable size command */ -            extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE, -				     client->swapped); -            if (extra < 0) { -                extra = 0; -            } -            if (cmdlen != __GLX_PAD(entry.bytes + extra)) { -                return BadLength; -            } -        } else { -            /* constant size command */ -            if (cmdlen != __GLX_PAD(entry.bytes)) { -                return BadLength; -            } -        } -	if (left < cmdlen) { -	    return BadLength; -	} - -	/* -	** Skip over the header and execute the command.  We allow the -	** caller to trash the command memory.  This is useful especially -	** for things that require double alignment - they can just shift -	** the data towards lower memory (trashing the header) by 4 bytes -	** and achieve the required alignment. -	*/ -	(*proc)(pc + __GLX_RENDER_HDR_SIZE); -	pc += cmdlen; -	left -= cmdlen; -	commandsDone++; -    } -    __GLX_NOTE_UNFLUSHED_CMDS(glxc); -    return Success; -} - - -/* -** Execute a large rendering request (one that spans multiple X requests). -*/ -int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXRenderLargeReq *req; -    ClientPtr client= cl->client; -    size_t dataBytes; -    __GLXrenderLargeHeader *hdr; -    __GLXcontext *glxc; -    int error; -    CARD16 opcode; -    __GLX_DECLARE_SWAP_VARIABLES; -     -    req = (xGLXRenderLargeReq *) pc; -    if (client->swapped) { -	__GLX_SWAP_SHORT(&req->length); -	__GLX_SWAP_INT(&req->contextTag); -	__GLX_SWAP_INT(&req->dataBytes); -	__GLX_SWAP_SHORT(&req->requestNumber); -	__GLX_SWAP_SHORT(&req->requestTotal); -    } - -    glxc = __glXForceCurrent(cl, req->contextTag, &error); -    if (!glxc) { -	/* Reset in case this isn't 1st request. */ -	__glXResetLargeCommandStatus(cl); -	return error; -    } -    dataBytes = req->dataBytes; - -    /* -    ** Check the request length. -    */ -    if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) { -	client->errorValue = req->length; -	/* Reset in case this isn't 1st request. */ -	__glXResetLargeCommandStatus(cl); -	return BadLength; -    } -    pc += sz_xGLXRenderLargeReq; -     -    if (cl->largeCmdRequestsSoFar == 0) { -	__GLXrenderSizeData entry; -	int extra; -	size_t cmdlen; -	int err; - -	/* -	** This is the first request of a multi request command. -	** Make enough space in the buffer, then copy the entire request. -	*/ -	if (req->requestNumber != 1) { -	    client->errorValue = req->requestNumber; -	    return __glXError(GLXBadLargeRequest); -	} - -	hdr = (__GLXrenderLargeHeader *) pc; -	if (client->swapped) { -	    __GLX_SWAP_INT(&hdr->length); -	    __GLX_SWAP_INT(&hdr->opcode); -	} -	cmdlen = hdr->length; -	opcode = hdr->opcode; - -	/* -	** Check for core opcodes and grab entry data. -	*/ -	err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); -	if (err < 0) { -	    client->errorValue = opcode; -	    return __glXError(GLXBadLargeRequest); -	} - -	if (entry.varsize) { -	    /* -	    ** If it's a variable-size command (a command whose length must -	    ** be computed from its parameters), all the parameters needed -	    ** will be in the 1st request, so it's okay to do this. -	    */ -	    extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, -				     client->swapped); -	    if (extra < 0) { -		extra = 0; -	    } -	    /* large command's header is 4 bytes longer, so add 4 */ -	    if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { -		return BadLength; -	    } -	} else { -	    /* constant size command */ -	    if (cmdlen != __GLX_PAD(entry.bytes + 4)) { -		return BadLength; -	    } -	} -	/* -	** Make enough space in the buffer, then copy the entire request. -	*/ -	if (cl->largeCmdBufSize < cmdlen) { -	    if (!cl->largeCmdBuf) { -		cl->largeCmdBuf = (GLbyte *) malloc(cmdlen); -	    } else { -		cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen); -	    } -	    if (!cl->largeCmdBuf) { -		return BadAlloc; -	    } -	    cl->largeCmdBufSize = cmdlen; -	} -	memcpy(cl->largeCmdBuf, pc, dataBytes); - -	cl->largeCmdBytesSoFar = dataBytes; -	cl->largeCmdBytesTotal = cmdlen; -	cl->largeCmdRequestsSoFar = 1; -	cl->largeCmdRequestsTotal = req->requestTotal; -	return Success; -	 -    } else { -	/* -	** We are receiving subsequent (i.e. not the first) requests of a -	** multi request command. -	*/ - -	/* -	** Check the request number and the total request count. -	*/ -	if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) { -	    client->errorValue = req->requestNumber; -	    __glXResetLargeCommandStatus(cl); -	    return __glXError(GLXBadLargeRequest); -	} -	if (req->requestTotal != cl->largeCmdRequestsTotal) { -	    client->errorValue = req->requestTotal; -	    __glXResetLargeCommandStatus(cl); -	    return __glXError(GLXBadLargeRequest); -	} - -	/* -	** Check that we didn't get too much data. -	*/ -	if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) { -	    client->errorValue = dataBytes; -	    __glXResetLargeCommandStatus(cl); -	    return __glXError(GLXBadLargeRequest); -	} -	memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes); -	cl->largeCmdBytesSoFar += dataBytes; -	cl->largeCmdRequestsSoFar++; - -	if (req->requestNumber == cl->largeCmdRequestsTotal) { -	    __GLXdispatchRenderProcPtr proc; - -	    /* -	    ** This is the last request; it must have enough bytes to complete -	    ** the command. -	    */ -	    /* NOTE: the two pad macros have been added below; they are needed -	    ** because the client library pads the total byte count, but not -	    ** the per-request byte counts.  The Protocol Encoding says the -	    ** total byte count should not be padded, so a proposal will be  -	    ** made to the ARB to relax the padding constraint on the total  -	    ** byte count, thus preserving backward compatibility.  Meanwhile,  -	    ** the padding done below fixes a bug that did not allow -	    ** large commands of odd sizes to be accepted by the server. -	    */ -	    if (__GLX_PAD(cl->largeCmdBytesSoFar) != -		__GLX_PAD(cl->largeCmdBytesTotal)) { -		client->errorValue = dataBytes; -		__glXResetLargeCommandStatus(cl); -		return __glXError(GLXBadLargeRequest); -	    } -	    hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf; -	    /* -	    ** The opcode and length field in the header had already been -	    ** swapped when the first request was received. -	    ** -	    ** Use the opcode to index into the procedure table. -	    */ -	    opcode = hdr->opcode; - -	    proc = (__GLXdispatchRenderProcPtr) -	      __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, -					     client->swapped); -	    if (proc == NULL) { -		client->errorValue = opcode; -		return __glXError(GLXBadLargeRequest); -	    } - -	    /* -	    ** Skip over the header and execute the command. -	    */ -	    (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); -	    __GLX_NOTE_UNFLUSHED_CMDS(glxc); - -	    /* -	    ** Reset for the next RenderLarge series. -	    */ -	    __glXResetLargeCommandStatus(cl); -	} else { -	    /* -	    ** This is neither the first nor the last request. -	    */ -	} -	return Success; -    } -} - -/************************************************************************/ - -/* -** No support is provided for the vendor-private requests other than -** allocating the entry points in the dispatch table. -*/ - -int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLint vendorcode = req->vendorCode; -    __GLXdispatchVendorPrivProcPtr proc; - -    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); - -    proc = (__GLXdispatchVendorPrivProcPtr) -      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, -				     vendorcode, 0); -    if (proc != NULL) { -	(*proc)(cl, (GLbyte*)req); -	return Success; -    } - -    cl->client->errorValue = req->vendorCode; -    return __glXError(GLXUnsupportedPrivateRequest); -} - -int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLint vendorcode = req->vendorCode; -    __GLXdispatchVendorPrivProcPtr proc; - -    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); - -    proc = (__GLXdispatchVendorPrivProcPtr) -      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, -				     vendorcode, 0); -    if (proc != NULL) { -	return (*proc)(cl, (GLbyte*)req); -    } - -    cl->client->errorValue = vendorcode; -    return __glXError(GLXUnsupportedPrivateRequest); -} - -int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; -    xGLXQueryExtensionsStringReply reply; -    __GLXscreen *pGlxScreen; -    size_t n, length; -    char *buf; -    int err; - -    REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq); - -    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) -	return err; - -    n = strlen(pGlxScreen->GLXextensions) + 1; -    length = __GLX_PAD(n) >> 2; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; -    reply.length = length; -    reply.n = n; - -    /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/ -    buf = (char *) malloc(length << 2); -    if (buf == NULL) -        return BadAlloc; -    memcpy(buf, pGlxScreen->GLXextensions, n); - -    if (client->swapped) { -        glxSwapQueryExtensionsStringReply(client, &reply, buf); -    } else { -        WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); -        WriteToClient(client, (int)(length << 2), (char *)buf); -    } - -    free(buf); -    return Success; -} - -int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; -    xGLXQueryServerStringReply reply; -    size_t n, length; -    const char *ptr; -    char *buf; -    __GLXscreen *pGlxScreen; -    int err; -    char ver_str[16]; - -    REQUEST_SIZE_MATCH(xGLXQueryServerStringReq); - -    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) -	return err; - -    switch(req->name) { -	case GLX_VENDOR: -	    ptr = pGlxScreen->GLXvendor; -	    break; -	case GLX_VERSION: -	    /* Return to the server version rather than the screen version -	     * to prevent confusion when they do not match. -	     */ -	    snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion); -	    ptr = ver_str; -	    break; -	case GLX_EXTENSIONS: -	    ptr = pGlxScreen->GLXextensions; -	    break; -	default: -	    return BadValue;  -    } - -    n = strlen(ptr) + 1; -    length = __GLX_PAD(n) >> 2; -    reply.type = X_Reply; -    reply.sequenceNumber = client->sequence; -    reply.length = length; -    reply.n = n; - -    buf = (char *) malloc(length << 2); -    if (buf == NULL) { -        return BadAlloc; -    } -    memcpy(buf, ptr, n); - -    if (client->swapped) { -        glxSwapQueryServerStringReply(client, &reply, buf); -    } else { -        WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); -        WriteToClient(client, (int)(length << 2), buf); -    } - -    free(buf); -    return Success; -} - -int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; -    const char *buf; -    -    REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); - -    buf = (const char *)(req+1); -    if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq))) -	return BadLength; - -    cl->GLClientmajorVersion = req->major; -    cl->GLClientminorVersion = req->minor; -    free(cl->GLClientextensions); -    cl->GLClientextensions = strdup(buf); - -    return Success; -} +/*
 + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 + * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * 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 including the dates of first publication and
 + * either this permission notice or a reference to
 + * http://oss.sgi.com/projects/FreeB/
 + * 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 NONINFRINGEMENT. IN NO EVENT SHALL
 + * SILICON GRAPHICS, INC. 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.
 + *
 + * Except as contained in this notice, the name of Silicon Graphics, Inc.
 + * shall not be used in advertising or otherwise to promote the sale, use or
 + * other dealings in this Software without prior written authorization from
 + * Silicon Graphics, Inc.
 + */
 +
 +#ifdef HAVE_DIX_CONFIG_H
 +#include <dix-config.h>
 +#endif
 +
 +#include <string.h>
 +#include <assert.h>
 +
 +#include "glxserver.h"
 +#include <GL/glxtokens.h>
 +#include <unpack.h>
 +#include <pixmapstr.h>
 +#include <windowstr.h>
 +#include "glxutil.h"
 +#include "glxext.h"
 +#include "glapitable.h"
 +#include "glapi.h"
 +#include "glthread.h"
 +#include "dispatch.h"
 +#include "indirect_dispatch.h"
 +#include "indirect_table.h"
 +#include "indirect_util.h"
 +
 +static int
 +validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
 +{
 +    /*
 +    ** Check if screen exists.
 +    */
 +    if (screen < 0 || screen >= screenInfo.numScreens) {
 +	client->errorValue = screen;
 +	*err = BadValue;
 +	return FALSE;
 +    }
 +    *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
 +
 +    return TRUE;
 +}
 +
 +static int
 +validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
 +		 __GLXconfig **config, int *err)
 +{
 +    __GLXconfig *m;
 +
 +    for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
 +	if (m->fbconfigID == id) {
 +	    *config = m;
 +	    return TRUE;
 +	}
 +
 +    client->errorValue = id;
 +    *err = __glXError(GLXBadFBConfig);
 +
 +    return FALSE;
 +}
 +
 +static int
 +validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
 +	       __GLXconfig **config, int *err)
 +{
 +    int i;
 +
 +    for (i = 0; i < pGlxScreen->numVisuals; i++)
 + 	if (pGlxScreen->visuals[i]->visualID == id) {
 +	    *config = pGlxScreen->visuals[i];
 +	    return TRUE;
 +	}
 +
 +    client->errorValue = id;
 +    *err = BadValue;
 +
 +    return FALSE;
 +}
 +
 +static int
 +validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config,
 +			  DrawablePtr pDraw, int *err)
 +{
 +    ScreenPtr pScreen = pDraw->pScreen;
 +    VisualPtr pVisual = NULL;
 +    XID vid;
 +    int i;
 +
 +    vid = wVisual((WindowPtr)pDraw);
 +    for (i = 0; i < pScreen->numVisuals; i++) {
 +	if (pScreen->visuals[i].vid == vid) {
 +	    pVisual = &pScreen->visuals[i];
 +	    break;
 +	}
 +    }
 +
 +    /* FIXME: What exactly should we check here... */
 +    if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
 +	!(config->drawableType & GLX_WINDOW_BIT)) {
 +	client->errorValue = pDraw->id;
 +	*err = BadMatch;
 +	return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +static int
 +validGlxContext(ClientPtr client, XID id, int access_mode,
 +		__GLXcontext **context, int *err)
 +{
 +    *err = dixLookupResourceByType((pointer *) context, id,
 +				   __glXContextRes, client, access_mode);
 +    if (*err != Success) {
 +	client->errorValue = id;
 +	if (*err == BadValue)
 +	    *err = __glXError(GLXBadContext);
 +	return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +static int
 +validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
 +		 __GLXdrawable **drawable, int *err)
 +{
 +    int rc;
 +
 +    rc = dixLookupResourceByType((pointer *) drawable, id,
 +				 __glXDrawableRes, client, access_mode);
 +    if (rc != Success && rc != BadValue) {
 +	*err = rc;
 +	client->errorValue = id;
 +	return FALSE;
 +    }
 +
 +    /* If the ID of the glx drawable we looked up doesn't match the id
 +     * we looked for, it's because we looked it up under the X
 +     * drawable ID (see DoCreateGLXDrawable). */
 +    if (rc == BadValue ||
 +	(*drawable)->drawId != id ||
 +	(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
 +	client->errorValue = id;
 +	switch (type) {
 +	case GLX_DRAWABLE_WINDOW:
 +	    *err = __glXError(GLXBadWindow);
 +	    return FALSE;
 +	case GLX_DRAWABLE_PIXMAP:
 +	    *err = __glXError(GLXBadPixmap);
 +	    return FALSE;
 +	case GLX_DRAWABLE_PBUFFER:
 +	    *err = __glXError(GLXBadPbuffer);
 +	    return FALSE;
 +	case GLX_DRAWABLE_ANY:
 +	    *err = __glXError(GLXBadDrawable);
 +	    return FALSE;
 +	}
 +    }
 +
 +    return TRUE;
 +}
 +
 +void
 +__glXContextDestroy(__GLXcontext *context)
 +{
 +    __glXFlushContextCache();
 +}
 +
 +static void __glXdirectContextDestroy(__GLXcontext *context)
 +{
 +    __glXContextDestroy(context);
 +    free(context);
 +}
 +
 +static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
 +					      __GLXconfig *modes,
 +					      __GLXcontext *shareContext)
 +{
 +    __GLXcontext *context;
 +
 +    context = calloc(1, sizeof (__GLXcontext));
 +    if (context == NULL)
 +	return NULL;
 +
 +    context->destroy = __glXdirectContextDestroy;
 +
 +    return context;
 +}
 +
 +/**
 + * Create a GL context with the given properties.  This routine is used
 + * to implement \c glXCreateContext, \c glXCreateNewContext, and
 + * \c glXCreateContextWithConfigSGIX.  This works becuase of the hack way
 + * that GLXFBConfigs are implemented.  Basically, the FBConfigID is the
 + * same as the VisualID.
 + */
 +
 +static int
 +DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
 +		GLXContextID shareList, __GLXconfig *config,
 +		__GLXscreen *pGlxScreen, GLboolean isDirect)
 +{
 +    ClientPtr client = cl->client;
 +    __GLXcontext *glxc, *shareglxc;
 +    int err;
 +    
 +    LEGAL_NEW_RESOURCE(gcId, client);
 +
 +    /*
 +    ** Find the display list space that we want to share.  
 +    **
 +    ** NOTE: In a multithreaded X server, we would need to keep a reference
 +    ** count for each display list so that if one client detroyed a list that 
 +    ** another client was using, the list would not really be freed until it 
 +    ** was no longer in use.  Since this sample implementation has no support 
 +    ** for multithreaded servers, we don't do this.  
 +    */
 +    if (shareList == None) {
 +	shareglxc = 0;
 +    } else {
 +	if (!validGlxContext(client, shareList, DixReadAccess,
 +			     &shareglxc, &err))
 +	    return err;
 +
 +	if (shareglxc->isDirect) {
 +	    /*
 +	    ** NOTE: no support for sharing display lists between direct
 +	    ** contexts, even if they are in the same address space.
 +	    */
 +#if 0
 +            /* Disabling this code seems to allow shared display lists
 +             * and texture objects to work.  We'll leave it disabled for now.
 +             */
 +	    client->errorValue = shareList;
 +	    return BadMatch;
 +#endif
 +	} else {
 +	    /*
 +	    ** Create an indirect context regardless of what the client asked
 +	    ** for; this way we can share display list space with shareList.
 +	    */
 +	    isDirect = GL_FALSE;
 +	}
 +    }
 +
 +    /*
 +    ** Allocate memory for the new context
 +    */
 +    if (!isDirect)
 +	glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
 +    else
 +	glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
 +    if (!glxc) {
 +	return BadAlloc;
 +    }
 +
 +    /*
 +    ** Initially, setup the part of the context that could be used by
 +    ** a GL core that needs windowing information (e.g., Mesa).
 +    */
 +    glxc->pGlxScreen = pGlxScreen;
 +    glxc->config = config;
 +
 +    /*
 +    ** Register this context as a resource.
 +    */
 +    if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
 +	(*glxc->destroy)(glxc);
 +	client->errorValue = gcId;
 +	return BadAlloc;
 +    }
 +    
 +    /*
 +    ** Finally, now that everything is working, setup the rest of the
 +    ** context.
 +    */
 +    glxc->id = gcId;
 +    glxc->share_id = shareList;
 +    glxc->idExists = GL_TRUE;
 +    glxc->isCurrent = GL_FALSE;
 +    glxc->isDirect = isDirect;
 +    glxc->renderMode = GL_RENDER;
 +
 +    __glXAddToContextList(glxc);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateContextReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
 +	return err;
 +
 +    return DoCreateContext(cl, req->context, req->shareList,
 +			   config, pGlxScreen, req->isDirect);
 +}
 +
 +int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateNewContextReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
 +	return err;
 +
 +    return DoCreateContext(cl, req->context, req->shareList,
 +			   config, pGlxScreen, req->isDirect);
 +}
 +
 +int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateContextWithConfigSGIXReq *req = 
 +	(xGLXCreateContextWithConfigSGIXReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
 +	return err;
 +
 +    return DoCreateContext(cl, req->context, req->shareList,
 +			   config, pGlxScreen, req->isDirect);
 +}
 +int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
 +    __GLXcontext *glxc;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyContextReq);
 +
 +    if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
 +			 &glxc, &err))
 +	    return err;
 +
 +    FreeResourceByType(req->context, __glXContextRes, FALSE);
 +    return Success;
 +}
 +
 +/*****************************************************************************/
 +
 +/*
 +** For each client, the server keeps a table of all the contexts that are
 +** current for that client (each thread of a client may have its own current
 +** context).  These routines add, change, and lookup contexts in the table.
 +*/
 +
 +/*
 +** Add a current context, and return the tag that will be used to refer to it.
 +*/
 +static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc)
 +{
 +    int i;
 +    int num = cl->numCurrentContexts;
 +    __GLXcontext **table = cl->currentContexts;
 +
 +    if (!glxc) return -1;
 +    
 +    /*
 +    ** Try to find an empty slot and use it.
 +    */
 +    for (i=0; i < num; i++) {
 +	if (!table[i]) {
 +	    table[i] = glxc;
 +	    return i+1;
 +	}
 +    }
 +    /*
 +    ** Didn't find a free slot, so we'll have to grow the table.
 +    */
 +    if (!num) {
 +	table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
 +    } else {
 +	table = (__GLXcontext **) realloc(table,
 +					   (num+1)*sizeof(__GLXcontext *));
 +    }
 +    table[num] = glxc;
 +    cl->currentContexts = table;
 +    cl->numCurrentContexts++;
 +    return num+1;
 +}
 +
 +/*
 +** Given a tag, change the current context for the corresponding entry.
 +*/
 +static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
 +				GLXContextTag tag)
 +{
 +    __GLXcontext **table = cl->currentContexts;
 +    table[tag-1] = glxc;
 +}
 +
 +/*
 +** For this implementation we have chosen to simply use the index of the
 +** context's entry in the table as the context tag.  A tag must be greater
 +** than 0.
 +*/
 +__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
 +{
 +    int num = cl->numCurrentContexts;
 +
 +    if (tag < 1 || tag > num) {
 +	return 0;
 +    } else {
 +	return cl->currentContexts[tag-1];
 +    }
 +}
 +
 +/*****************************************************************************/
 +
 +static void StopUsingContext(__GLXcontext *glxc)
 +{
 +    if (glxc) {
 +	if (glxc == __glXLastContext) {
 +	    /* Tell server GL library */
 +	    __glXLastContext = 0;
 +	}
 +	glxc->isCurrent = GL_FALSE;
 +	if (!glxc->idExists) {
 +	    __glXFreeContext(glxc);
 +	}
 +    }
 +}
 +
 +static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
 +{
 +    glxc->isCurrent = GL_TRUE;
 +    __glXLastContext = glxc;	
 +}
 +
 +/**
 + * This is a helper function to handle the legacy (pre GLX 1.3) cases
 + * where passing an X window to glXMakeCurrent is valid.  Given a
 + * resource ID, look up the GLX drawable if available, otherwise, make
 + * sure it's an X window and create a GLX drawable one the fly.
 + */
 +static __GLXdrawable *
 +__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
 +		 int *error)
 +{
 +    DrawablePtr pDraw;
 +    __GLXdrawable *pGlxDraw;
 +    int rc;
 +
 +    if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
 +			 DixWriteAccess, &pGlxDraw, &rc)) {
 +	if (glxc != NULL && pGlxDraw->config != glxc->config) {
 +	    client->errorValue = drawId;
 +	    *error = BadMatch;
 +	    return NULL;
 +	}
 +
 +	return pGlxDraw;
 +    }
 +
 +    /* No active context and an unknown drawable, bail. */
 +    if (glxc == NULL) {
 +	    client->errorValue = drawId;
 +	    *error = BadMatch;
 +	    return NULL;
 +    }
 +
 +    /* The drawId wasn't a GLX drawable.  Make sure it's a window and
 +     * create a GLXWindow for it.  Check that the drawable screen
 +     * matches the context screen and that the context fbconfig is
 +     * compatible with the window visual. */
 +
 +    rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
 +    if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
 +	client->errorValue = drawId;
 +	*error = __glXError(GLXBadDrawable);
 +	return NULL;
 +    }
 +
 +    if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
 +	client->errorValue = pDraw->pScreen->myNum;
 +	*error = BadMatch;
 +	return NULL;
 +    }
 +
 +    if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
 +	return NULL;
 +
 +    pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
 +						pDraw, drawId,
 +						GLX_DRAWABLE_WINDOW,
 +						drawId, glxc->config);
 +
 +    /* since we are creating the drawablePrivate, drawId should be new */
 +    if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
 +	pGlxDraw->destroy (pGlxDraw);
 +	*error = BadAlloc;
 +	return NULL;
 +    }
 +
 +    return pGlxDraw;
 +}
 +
 +/*****************************************************************************/
 +/*
 +** Make an OpenGL context and drawable current.
 +*/
 +
 +static int
 +DoMakeCurrent(__GLXclientState *cl,
 +	      GLXDrawable drawId, GLXDrawable readId,
 +	      GLXContextID contextId, GLXContextTag tag)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeCurrentReply reply;
 +    __GLXcontext *glxc, *prevglxc;
 +    __GLXdrawable *drawPriv = NULL;
 +    __GLXdrawable *readPriv = NULL;
 +    int error;
 +    GLuint  mask;
 +
 +    /*
 +    ** If one is None and the other isn't, it's a bad match.
 +    */
 +
 +    mask  = (drawId == None)    ? (1 << 0) : 0;
 +    mask |= (readId == None)    ? (1 << 1) : 0;
 +    mask |= (contextId == None) ? (1 << 2) : 0;
 +
 +    if ( (mask != 0x00) && (mask != 0x07) ) {
 +	return BadMatch;
 +    }
 +    
 +    /*
 +    ** Lookup old context.  If we have one, it must be in a usable state.
 +    */
 +    if (tag != 0) {
 +	prevglxc = __glXLookupContextByTag(cl, tag);
 +	if (!prevglxc) {
 +	    /*
 +	    ** Tag for previous context is invalid.
 +	    */
 +	    return __glXError(GLXBadContextTag);
 +	}
 +	if (prevglxc->renderMode != GL_RENDER) {
 +	    /* Oops.  Not in render mode render. */
 +	    client->errorValue = prevglxc->id;
 +	    return __glXError(GLXBadContextState);
 +	}
 +    } else {
 +	prevglxc = 0;
 +    }
 +
 +    /*
 +    ** Lookup new context.  It must not be current for someone else.
 +    */
 +    if (contextId != None) {
 +	int  status;
 +
 +	if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
 +	    return error;
 +	if ((glxc != prevglxc) && glxc->isCurrent) {
 +	    /* Context is current to somebody else */
 +	    return BadAccess;
 +	}
 +
 +	assert( drawId != None );
 +	assert( readId != None );
 +
 +	drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
 +	if (drawPriv == NULL)
 +	    return status;
 +
 +	readPriv = __glXGetDrawable(glxc, readId, client, &status);
 +	if (readPriv == NULL)
 +	    return status;
 +
 +    } else {
 +	/* Switching to no context.  Ignore new drawable. */
 +	glxc = 0;
 +	drawPriv = 0;
 +	readPriv = 0;
 +    }
 +
 +
 +    if (prevglxc) {
 +	/*
 +	** Flush the previous context if needed.
 +	*/
 +	if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) {
 +	    if (__glXForceCurrent(cl, tag, (int *)&error)) {
 +		CALL_Flush( GET_DISPATCH(), () );
 +		__GLX_NOTE_FLUSHED_CMDS(prevglxc);
 +	    } else {
 +		return error;
 +	    }
 +	}
 +
 +	/*
 +	** Make the previous context not current.
 +	*/
 +	if (!(*prevglxc->loseCurrent)(prevglxc)) {
 +	    return __glXError(GLXBadContext);
 +	}
 +	__glXFlushContextCache();
 +	if (!prevglxc->isDirect) {
 +	    prevglxc->drawPriv = NULL;
 +	    prevglxc->readPriv = NULL;
 +	}
 +    }
 +	
 +
 +    if ((glxc != 0) && !glxc->isDirect) {
 +
 +	glxc->drawPriv = drawPriv;
 +	glxc->readPriv = readPriv;
 +
 +	/* make the context current */
 +	if (!(*glxc->makeCurrent)(glxc)) {
 +	    glxc->drawPriv = NULL;
 +	    glxc->readPriv = NULL;
 +	    return __glXError(GLXBadContext);
 +	}
 +
 +	glxc->isCurrent = GL_TRUE;
 +    }
 +
 +    if (prevglxc) {
 +	ChangeCurrentContext(cl, glxc, tag);
 +	StopUsingContext(prevglxc);
 +    } else {
 +	tag = AddCurrentContext(cl, glxc);
 +    }
 +
 +    if (glxc) {
 +	StartUsingContext(cl, glxc);
 +	reply.contextTag = tag;
 +    } else {
 +	reply.contextTag = 0;
 +    }
 +
 +    reply.length = 0;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +
 +    if (client->swapped) {
 +	__glXSwapMakeCurrentReply(client, &reply);
 +    } else {
 +	WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply);
 +    }
 +    return Success;
 +}
 +
 +int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeCurrentReq);
 +
 +    return DoMakeCurrent( cl, req->drawable, req->drawable,
 +			  req->context, req->oldContextTag );
 +}
 +
 +int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq);
 +
 +    return DoMakeCurrent( cl, req->drawable, req->readdrawable,
 +			  req->context, req->oldContextTag );
 +}
 +
 +int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq);
 +
 +    return DoMakeCurrent( cl, req->drawable, req->readable,
 +			  req->context, req->oldContextTag );
 +}
 +
 +int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
 +    xGLXIsDirectReply reply;
 +    __GLXcontext *glxc;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXIsDirectReq);
 +
 +    if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
 +	return err;
 +
 +    reply.isDirect = glxc->isDirect;
 +    reply.length = 0;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +
 +    if (client->swapped) {
 +	__glXSwapIsDirectReply(client, &reply);
 +    } else {
 +	WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
 +    }
 +
 +    return Success;
 +}
 +
 +int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
 +    xGLXQueryVersionReply reply;
 +    GLuint major, minor;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
 +
 +    major = req->majorVersion;
 +    minor = req->minorVersion;
 +    (void)major;
 +    (void)minor;
 +
 +    /*
 +    ** Server should take into consideration the version numbers sent by the
 +    ** client if it wants to work with older clients; however, in this
 +    ** implementation the server just returns its version number.
 +    */
 +    reply.majorVersion = glxMajorVersion;
 +    reply.minorVersion = glxMinorVersion;
 +    reply.length = 0;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +
 +    if (client->swapped) {
 +	__glXSwapQueryVersionReply(client, &reply);
 +    } else {
 +	WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
 +    }
 +    return Success;
 +}
 +
 +int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
 +    GLXContextTag tag;
 +    __GLXcontext *glxc = NULL;
 +    int error;
 +
 +    REQUEST_SIZE_MATCH(xGLXWaitGLReq);
 +
 +    tag = req->contextTag;
 +    if (tag) {
 +	glxc = __glXLookupContextByTag(cl, tag);
 +	if (!glxc)
 +	    return __glXError(GLXBadContextTag);
 +    
 +	if (!__glXForceCurrent(cl, req->contextTag, &error))
 +	    return error;
 +
 +	CALL_Finish( GET_DISPATCH(), () );
 +    }
 +
 +    if (glxc && glxc->drawPriv->waitGL)
 +	(*glxc->drawPriv->waitGL)(glxc->drawPriv);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
 +    GLXContextTag tag;
 +    __GLXcontext *glxc = NULL;
 +    int error;
 +
 +    REQUEST_SIZE_MATCH(xGLXWaitXReq);
 +
 +    tag = req->contextTag;
 +    if (tag) {
 +	glxc = __glXLookupContextByTag(cl, tag);
 +	if (!glxc)
 +	    return __glXError(GLXBadContextTag);
 +    
 +	if (!__glXForceCurrent(cl, req->contextTag, &error))
 +	    return error;
 +    }
 +
 +    if (glxc && glxc->drawPriv->waitX)
 +	(*glxc->drawPriv->waitX)(glxc->drawPriv);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
 +    GLXContextID source;
 +    GLXContextID dest;
 +    GLXContextTag tag;
 +    unsigned long mask;
 +    __GLXcontext *src, *dst;
 +    int error;
 +
 +    REQUEST_SIZE_MATCH(xGLXCopyContextReq);
 +
 +    source = req->source;
 +    dest = req->dest;
 +    tag = req->contextTag;
 +    mask = req->mask;
 +    if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
 +	return error;
 +    if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
 +	return error;
 +
 +    /*
 +    ** They must be in the same address space, and same screen.
 +    ** NOTE: no support for direct rendering contexts here.
 +    */
 +    if (src->isDirect || dst->isDirect ||
 +	(src->pGlxScreen != dst->pGlxScreen)) {
 +	client->errorValue = source;
 +	return BadMatch;
 +    }
 +
 +    /*
 +    ** The destination context must not be current for any client.
 +    */
 +    if (dst->isCurrent) {
 +	client->errorValue = dest;
 +	return BadAccess;
 +    }
 +
 +    if (tag) {
 +	__GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
 +	
 +	if (!tagcx) {
 +	    return __glXError(GLXBadContextTag);
 +	}
 +	if (tagcx != src) {
 +	    /*
 +	    ** This would be caused by a faulty implementation of the client
 +	    ** library.
 +	    */
 +	    return BadMatch;
 +	}
 +	/*
 +	** In this case, glXCopyContext is in both GL and X streams, in terms
 +	** of sequentiality.
 +	*/
 +	if (__glXForceCurrent(cl, tag, &error)) {
 +	    /*
 +	    ** Do whatever is needed to make sure that all preceding requests
 +	    ** in both streams are completed before the copy is executed.
 +	    */
 +	    CALL_Finish( GET_DISPATCH(), () );
 +	    __GLX_NOTE_FLUSHED_CMDS(tagcx);
 +	} else {
 +	    return error;
 +	}
 +    }
 +    /*
 +    ** Issue copy.  The only reason for failure is a bad mask.
 +    */
 +    if (!(*dst->copy)(dst, src, mask)) {
 +	client->errorValue = mask;
 +	return BadValue;
 +    }
 +    return Success;
 +}
 +
 +enum {
 +    GLX_VIS_CONFIG_UNPAIRED = 18,
 +    GLX_VIS_CONFIG_PAIRED = 20
 +};
 +
 +enum {
 +    GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
 +};
 +
 +int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
 +    ClientPtr client = cl->client;
 +    xGLXGetVisualConfigsReply reply;
 +    __GLXscreen *pGlxScreen;
 +    __GLXconfig *modes;
 +    CARD32 buf[GLX_VIS_CONFIG_TOTAL];
 +    int p, i, err;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +
 +    reply.numVisuals = pGlxScreen->numVisuals;
 +    reply.numProps = GLX_VIS_CONFIG_TOTAL;
 +    reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +
 +    if (client->swapped) {
 +	__GLX_SWAP_SHORT(&reply.sequenceNumber);
 +	__GLX_SWAP_INT(&reply.length);
 +	__GLX_SWAP_INT(&reply.numVisuals);
 +	__GLX_SWAP_INT(&reply.numProps);
 +    }
 +
 +    WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
 +
 +    for (i = 0; i < pGlxScreen->numVisuals; i++) {
 +	modes = pGlxScreen->visuals[i];
 +
 +	p = 0;
 +	buf[p++] = modes->visualID;
 +	buf[p++] = glxConvertToXVisualType( modes->visualType );
 +	buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
 +
 +	buf[p++] = modes->redBits;
 +	buf[p++] = modes->greenBits;
 +	buf[p++] = modes->blueBits;
 +	buf[p++] = modes->alphaBits;
 +	buf[p++] = modes->accumRedBits;
 +	buf[p++] = modes->accumGreenBits;
 +	buf[p++] = modes->accumBlueBits;
 +	buf[p++] = modes->accumAlphaBits;
 +
 +	buf[p++] = modes->doubleBufferMode;
 +	buf[p++] = modes->stereoMode;
 +
 +	buf[p++] = modes->rgbBits;
 +	buf[p++] = modes->depthBits;
 +	buf[p++] = modes->stencilBits;
 +	buf[p++] = modes->numAuxBuffers;
 +	buf[p++] = modes->level;
 +
 +	assert(p == GLX_VIS_CONFIG_UNPAIRED);
 +	/* 
 +	** Add token/value pairs for extensions.
 +	*/
 +	buf[p++] = GLX_VISUAL_CAVEAT_EXT;
 +	buf[p++] = modes->visualRating;
 +	buf[p++] = GLX_TRANSPARENT_TYPE;
 +	buf[p++] = modes->transparentPixel;
 +	buf[p++] = GLX_TRANSPARENT_RED_VALUE;
 +	buf[p++] = modes->transparentRed;
 +	buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
 +	buf[p++] = modes->transparentGreen;
 +	buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
 +	buf[p++] = modes->transparentBlue;
 +	buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
 +	buf[p++] = modes->transparentAlpha;
 +	buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
 +	buf[p++] = modes->transparentIndex;
 +	buf[p++] = GLX_SAMPLES_SGIS;
 +	buf[p++] = modes->samples;
 +	buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
 +	buf[p++] = modes->sampleBuffers;
 +	buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */
 +	buf[p++] = 0;
 +
 +	assert(p == GLX_VIS_CONFIG_TOTAL);
 +	if (client->swapped) {
 +	    __GLX_SWAP_INT_ARRAY(buf, p);
 +	}
 +	WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf);
 +    }
 +    return Success;
 +}
 +
 +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36)
 +#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
 +/**
 + * Send the set of GLXFBConfigs to the client.  There is not currently
 + * and interface into the driver on the server-side to get GLXFBConfigs,
 + * so we "invent" some based on the \c __GLXvisualConfig structures that
 + * the driver does supply.
 + * 
 + * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
 + * is the same, so this routine pulls double duty.
 + */
 +
 +static int
 +DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetFBConfigsReply reply;
 +    __GLXscreen *pGlxScreen;
 +    CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
 +    int p, err;
 +    __GLXconfig *modes;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +
 +    if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
 +	return err;
 +
 +    reply.numFBConfigs = pGlxScreen->numFBConfigs;
 +    reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
 +    reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +
 +    if (client->swapped) {
 +	__GLX_SWAP_SHORT(&reply.sequenceNumber);
 +	__GLX_SWAP_INT(&reply.length);
 +	__GLX_SWAP_INT(&reply.numFBConfigs);
 +	__GLX_SWAP_INT(&reply.numAttribs);
 +    }
 +
 +    WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
 +
 +    for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
 +	p = 0;
 +
 +#define WRITE_PAIR(tag,value) \
 +    do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
 +
 +	WRITE_PAIR( GLX_VISUAL_ID,        modes->visualID );
 +	WRITE_PAIR( GLX_FBCONFIG_ID,      modes->fbconfigID );
 +	WRITE_PAIR( GLX_X_RENDERABLE,     GL_TRUE );
 +
 +	WRITE_PAIR( GLX_RGBA,
 +		    (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE );
 +	WRITE_PAIR( GLX_RENDER_TYPE,      modes->renderType );
 +	WRITE_PAIR( GLX_DOUBLEBUFFER,     modes->doubleBufferMode );
 +	WRITE_PAIR( GLX_STEREO,           modes->stereoMode );
 +
 +	WRITE_PAIR( GLX_BUFFER_SIZE,      modes->rgbBits );
 +	WRITE_PAIR( GLX_LEVEL,            modes->level );
 +	WRITE_PAIR( GLX_AUX_BUFFERS,      modes->numAuxBuffers );
 +	WRITE_PAIR( GLX_RED_SIZE,         modes->redBits );
 +	WRITE_PAIR( GLX_GREEN_SIZE,       modes->greenBits );
 +	WRITE_PAIR( GLX_BLUE_SIZE,        modes->blueBits );
 +	WRITE_PAIR( GLX_ALPHA_SIZE,       modes->alphaBits );
 +	WRITE_PAIR( GLX_ACCUM_RED_SIZE,   modes->accumRedBits );
 +	WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits );
 +	WRITE_PAIR( GLX_ACCUM_BLUE_SIZE,  modes->accumBlueBits );
 +	WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
 +	WRITE_PAIR( GLX_DEPTH_SIZE,       modes->depthBits );
 +	WRITE_PAIR( GLX_STENCIL_SIZE,     modes->stencilBits );
 +	WRITE_PAIR( GLX_X_VISUAL_TYPE,    modes->visualType );
 +	WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
 +	WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
 +	WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
 +	WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen );
 +	WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue );
 +	WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha );
 +	WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
 +	WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
 +	WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples );
 +	WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers );
 +	/* GLX_VISUAL_SELECT_GROUP_SGIX ? */
 +	WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType );
 +	WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb );
 +	WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba );
 +	WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture );
 +	WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets );
 +
 +	if (client->swapped) {
 +	    __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
 +	}
 +	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
 +		      (char *)buf);
 +    }
 +    return Success;
 +}
 +
 +
 +int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
 +    REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq);
 +    return DoGetFBConfigs(cl, req->screen);
 +}
 +
 +int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
 +    /* work around mesa bug, don't use REQUEST_SIZE_MATCH */
 +    REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
 +    return DoGetFBConfigs(cl, req->screen);
 +}
 +
 +GLboolean
 +__glXDrawableInit(__GLXdrawable *drawable,
 +		  __GLXscreen *screen, DrawablePtr pDraw, int type,
 +		  XID drawId, __GLXconfig *config)
 +{
 +    drawable->pDraw = pDraw;
 +    drawable->type = type;
 +    drawable->drawId = drawId;
 +    drawable->config = config;
 +    drawable->eventMask = 0;
 +
 +    return GL_TRUE;
 +}
 +
 +void
 +__glXDrawableRelease(__GLXdrawable *drawable)
 +{
 +}
 +
 +static int 
 +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
 +		    __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
 +		    XID glxDrawableId, int type)
 +{
 +    __GLXdrawable *pGlxDraw;
 +
 +    if (pGlxScreen->pScreen != pDraw->pScreen)
 +	return BadMatch;
 +
 +    pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
 +					  drawableId, type,
 +					  glxDrawableId, config);
 +    if (pGlxDraw == NULL)
 +	return BadAlloc;
 +
 +    if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
 +	pGlxDraw->destroy (pGlxDraw);
 +	return BadAlloc;
 +    }
 +
 +    /* Add the glx drawable under the XID of the underlying X drawable
 +     * too.  That way we'll get a callback in DrawableGone and can
 +     * clean up properly when the drawable is destroyed. */
 +    if (drawableId != glxDrawableId &&
 +	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
 +	pGlxDraw->destroy (pGlxDraw);
 +	return BadAlloc;
 +    }
 +
 +    return Success;
 +}
 +
 +static int
 +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
 +		  XID drawableId, XID glxDrawableId)
 +{
 +    DrawablePtr pDraw;
 +    int err;
 +
 +    LEGAL_NEW_RESOURCE(glxDrawableId, client);
 +
 +    err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
 +    if (err != Success) {
 +	client->errorValue = drawableId;
 +	return err;
 +    }
 +    if (pDraw->type != DRAWABLE_PIXMAP) {
 +	client->errorValue = drawableId;
 +	return BadPixmap;
 +    }
 +
 +    err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
 +			      glxDrawableId, GLX_DRAWABLE_PIXMAP);
 +
 +    return err;
 +}
 +
 +static void
 +determineTextureTarget(ClientPtr client, XID glxDrawableID,
 +		       CARD32 *attribs, CARD32 numAttribs)
 +{
 +    GLenum target = 0;
 +    GLenum format = 0;
 +    int i, err;
 +    __GLXdrawable *pGlxDraw;
 +
 +    if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
 +			  DixWriteAccess, &pGlxDraw, &err))
 +	/* We just added it in CreatePixmap, so we should never get here. */
 +	return;
 +
 +    for (i = 0; i < numAttribs; i++) {
 +	if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
 +	    switch (attribs[2 * i + 1]) {
 +	    case GLX_TEXTURE_2D_EXT:
 +		target = GL_TEXTURE_2D;
 +		break;
 +	    case GLX_TEXTURE_RECTANGLE_EXT:
 +		target = GL_TEXTURE_RECTANGLE_ARB;
 +		break;
 +	    }
 +	}
 +
 +	if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
 +		format = attribs[2 * i + 1];
 +    }
 + 
 +    if (!target) {
 +	int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
 +	
 +	if (h & (h - 1) || w & (w - 1))
 +	    target = GL_TEXTURE_RECTANGLE_ARB;
 +	else
 +	    target = GL_TEXTURE_2D;
 +    }
 +
 +    pGlxDraw->target = target;
 +    pGlxDraw->format = format;
 +}
 +
 +int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
 +	return err;
 +
 +    return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
 +			     req->pixmap, req->glxpixmap);
 +}
 +
 +int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq);
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
 +	return err;
 +
 +    err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
 +			    req->pixmap, req->glxpixmap);
 +    if (err != Success)
 +	return err;
 +
 +    determineTextureTarget(cl->client, req->glxpixmap,
 +			   (CARD32*) (req + 1), req->numAttribs);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 +	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
 +    __GLXconfig *config;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq);
 +
 +    if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
 +	return err;
 +
 +    return DoCreateGLXPixmap(cl->client, pGlxScreen,
 +			     config, req->pixmap, req->glxpixmap);
 +}
 +
 +
 +static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
 +{
 +    __GLXdrawable *pGlxDraw;
 +    int err;
 +
 +    if (!validGlxDrawable(cl->client, glxdrawable, type,
 +			  DixDestroyAccess, &pGlxDraw, &err))
 +	return err;
 +
 +    FreeResource(glxdrawable, FALSE);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq);
 +
 +    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
 +}
 +
 +int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
 +
 +    /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
 +     * length to 3 instead of 2 */
 +    REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq);
 +
 +    return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
 +}
 +
 +static int
 +DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
 +		int width, int height, XID glxDrawableId)
 +{
 +    __GLXconfig	*config;
 +    __GLXscreen		*pGlxScreen;
 +    PixmapPtr		 pPixmap;
 +    int			 err;
 +
 +    LEGAL_NEW_RESOURCE(glxDrawableId, client);
 +
 +    if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
 +	return err;
 +
 +    __glXenterServer(GL_FALSE);
 +    pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
 +						    width, height, config->rgbBits, 0);
 +    __glXleaveServer(GL_FALSE);
 +
 +    /* Assign the pixmap the same id as the pbuffer and add it as a
 +     * resource so it and the DRI2 drawable will be reclaimed when the
 +     * pbuffer is destroyed. */
 +    pPixmap->drawable.id = glxDrawableId;
 +    if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
 +	return BadAlloc;
 +
 +    return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
 +			       glxDrawableId, glxDrawableId,
 +			       GLX_DRAWABLE_PBUFFER);
 +}
 +
 +int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreatePbufferReq	*req = (xGLXCreatePbufferReq *) pc;
 +    CARD32			*attrs;
 +    int				 width, height, i;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq);
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3);
 +
 +    attrs = (CARD32 *) (req + 1);
 +    width = 0;
 +    height = 0;
 +
 +    for (i = 0; i < req->numAttribs; i++) {
 +	switch (attrs[i * 2]) {
 +	case GLX_PBUFFER_WIDTH:
 +	    width = attrs[i * 2 + 1];
 +	    break;
 +	case GLX_PBUFFER_HEIGHT:
 +	    height = attrs[i * 2 + 1];
 +	    break;
 +	case GLX_LARGEST_PBUFFER:
 +	case GLX_PRESERVED_CONTENTS:
 +	    /* FIXME: huh... */
 +	    break;
 +	}
 +    }
 +
 +    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
 +			   width, height, req->pbuffer);
 +}
 +
 +int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq);
 +
 +    return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
 +			   req->width, req->height, req->pbuffer);
 +}
 +
 +int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq);
 +
 +    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
 +}
 +
 +int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq);
 +
 +    return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
 +}
 +
 +static int
 +DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
 +			   int numAttribs, CARD32 *attribs)
 +{
 +    __GLXdrawable *pGlxDraw;
 +    int i, err;
 +
 +    if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
 +			  DixSetAttrAccess, &pGlxDraw, &err))
 +	return err;
 +
 +    for (i = 0; i < numAttribs; i++) {
 +	switch(attribs[i * 2]) {
 +	case GLX_EVENT_MASK:
 +	    /* All we do is to record the event mask so we can send it
 +	     * back when queried.  We never actually clobber the
 +	     * pbuffers, so we never need to send out the event. */
 +	    pGlxDraw->eventMask = attribs[i * 2 + 1];
 +	    break;
 +	}
 +    }
 +
 +    return Success;
 +}
 +
 +int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXChangeDrawableAttributesReq *req =
 +	(xGLXChangeDrawableAttributesReq *) pc;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq);
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +#if 0
 +    /* mesa sends an additional 8 bytes */
 +    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3);
 +#else
 +    if (((sizeof(xGLXChangeDrawableAttributesReq) + (req->numAttribs << 3)) >> 2) < client->req_len)
 +	    return BadLength;
 +#endif
 +
 +    return DoChangeDrawableAttributes(cl->client, req->drawable,
 +				      req->numAttribs, (CARD32 *) (req + 1));
 +}
 +
 +int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXChangeDrawableAttributesSGIXReq *req =
 +	(xGLXChangeDrawableAttributesSGIXReq *)pc;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq);
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3);
 +
 +    return DoChangeDrawableAttributes(cl->client, req->drawable,
 +				      req->numAttribs, (CARD32 *) (req + 1));
 +}
 +
 +int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXCreateWindowReq	*req = (xGLXCreateWindowReq *) pc;
 +    __GLXconfig	*config;
 +    __GLXscreen		*pGlxScreen;
 +    ClientPtr		 client = cl->client;
 +    DrawablePtr		 pDraw;
 +    int			 err;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq);
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3);
 +
 +    LEGAL_NEW_RESOURCE(req->glxwindow, client);
 +
 +    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
 +	return err;
 +    if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
 +	return err;
 +
 +    err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
 +    if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
 +	client->errorValue = req->window;
 +	return BadWindow;
 +    }
 +
 +    if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
 +	return err;
 +
 +    return DoCreateGLXDrawable(client, pGlxScreen, config,
 +			       pDraw, req->window,
 +			       req->glxwindow, GLX_DRAWABLE_WINDOW);
 +}
 +
 +int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
 +
 +    /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
 +    REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
 +
 +    return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
 +}
 +
 +
 +/*****************************************************************************/
 +
 +/*
 +** NOTE: There is no portable implementation for swap buffers as of
 +** this time that is of value.  Consequently, this code must be
 +** implemented by somebody other than SGI.
 +*/
 +int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
 +    GLXContextTag tag;
 +    XID drawId;
 +    __GLXcontext *glxc = NULL;
 +    __GLXdrawable *pGlxDraw;
 +    int error;
 +
 +    REQUEST_SIZE_MATCH(xGLXSwapBuffersReq);
 +
 +    tag = req->contextTag;
 +    drawId = req->drawable;
 +    if (tag) {
 +	glxc = __glXLookupContextByTag(cl, tag);
 +	if (!glxc) {
 +	    return __glXError(GLXBadContextTag);
 +	}
 +	/*
 +	** The calling thread is swapping its current drawable.  In this case,
 +	** glxSwapBuffers is in both GL and X streams, in terms of
 +	** sequentiality.
 +	*/
 +	if (__glXForceCurrent(cl, tag, &error)) {
 +	    /*
 +	    ** Do whatever is needed to make sure that all preceding requests
 +	    ** in both streams are completed before the swap is executed.
 +	    */
 +	    CALL_Finish( GET_DISPATCH(), () );
 +	    __GLX_NOTE_FLUSHED_CMDS(glxc);
 +	} else {
 +	    return error;
 +	}
 +    }
 +
 +    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
 +    if (pGlxDraw == NULL)
 +	return error;
 +
 +    if (pGlxDraw->type == DRAWABLE_WINDOW &&
 +	(*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
 +	return __glXError(GLXBadDrawable);
 +
 +    return Success;
 +}
 +
 +
 +static int
 +DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
 +{
 +    ClientPtr client = cl->client;
 +    __GLXcontext *ctx;
 +    xGLXQueryContextInfoEXTReply reply;
 +    int nProps;
 +    int *sendBuf, *pSendBuf;
 +    int nReplyBytes;
 +    int err;
 +
 +    if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
 +	return err;
 +
 +    nProps = 3;
 +    reply.length = nProps << 1;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +    reply.n = nProps;
 +
 +    nReplyBytes = reply.length << 2;
 +    sendBuf = (int *)malloc((size_t)nReplyBytes);
 +    if (sendBuf == NULL) {
 +	return __glXError(GLXBadContext);	/* XXX: Is this correct? */
 +    }
 +    pSendBuf = sendBuf;
 +    *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
 +    *pSendBuf++ = (int)(ctx->share_id);
 +    *pSendBuf++ = GLX_VISUAL_ID_EXT;
 +    *pSendBuf++ = (int)(ctx->config->visualID);
 +    *pSendBuf++ = GLX_SCREEN_EXT;
 +    *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum);
 +
 +    if (client->swapped) {
 +	__glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
 +    } else {
 +	WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
 +	WriteToClient(client, nReplyBytes, (char *)sendBuf);
 +    }
 +    free((char *)sendBuf);
 +
 +    return Success;
 +}
 +
 +int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq);
 +
 +    return DoQueryContext(cl, req->context);
 +}
 +
 +int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryContextReq);
 +
 +    return DoQueryContext(cl, req->context);
 +}
 +
 +int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    ClientPtr		 client = cl->client;
 +    __GLXcontext	*context;
 +    __GLXdrawable	*pGlxDraw;
 +    GLXDrawable		 drawId;
 +    int			 buffer;
 +    int			 error;
 +    CARD32		 num_attribs;
 +
 +    if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
 +	return BadLength;
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    drawId = *((CARD32 *) (pc));
 +    buffer = *((INT32 *)  (pc + 4));
 +    num_attribs = *((CARD32 *) (pc + 8));
 +    if (num_attribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = num_attribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3));
 +
 +    if (buffer != GLX_FRONT_LEFT_EXT)
 +	return __glXError(GLXBadPixmap);
 +
 +    context = __glXForceCurrent (cl, req->contextTag, &error);
 +    if (!context)
 +	return error;
 +
 +    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
 +			  DixReadAccess, &pGlxDraw, &error))
 +	return error;
 +
 +    if (!context->textureFromPixmap)
 +	return __glXError(GLXUnsupportedPrivateRequest);
 +
 +    return context->textureFromPixmap->bindTexImage(context,
 +						    buffer,
 +						    pGlxDraw);
 +}
 +
 +int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    ClientPtr		 client = cl->client;
 +    __GLXdrawable	*pGlxDraw;
 +    __GLXcontext	*context;
 +    GLXDrawable		 drawId;
 +    int			 buffer;
 +    int			 error;
 +
 +    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8);
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    drawId = *((CARD32 *) (pc));
 +    buffer = *((INT32 *)  (pc + 4));
 +    
 +    context = __glXForceCurrent (cl, req->contextTag, &error);
 +    if (!context)
 +	return error;
 +
 +    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
 +			  DixReadAccess, &pGlxDraw, &error))
 +	return error;
 +
 +    if (!context->textureFromPixmap)
 +	return __glXError(GLXUnsupportedPrivateRequest);
 +
 +    return context->textureFromPixmap->releaseTexImage(context,
 +						       buffer,
 +						       pGlxDraw);
 +}
 +
 +int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLXContextTag         tag = req->contextTag;
 +    __GLXcontext         *glxc = NULL;
 +    __GLXdrawable        *pGlxDraw;
 +    ClientPtr		  client = cl->client;
 +    GLXDrawable		  drawId;
 +    int                   error;
 +    int                   x, y, width, height;
 +
 +    (void) client;
 +    (void) req;
 +
 +    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20);
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    drawId = *((CARD32 *) (pc));
 +    x      = *((INT32 *)  (pc + 4));
 +    y      = *((INT32 *)  (pc + 8));
 +    width  = *((INT32 *)  (pc + 12));
 +    height = *((INT32 *)  (pc + 16));
 +
 +    if (tag) {
 +	glxc = __glXLookupContextByTag(cl, tag);
 +	if (!glxc) {
 +	    return __glXError(GLXBadContextTag);
 +	}
 +	/*
 +	** The calling thread is swapping its current drawable.  In this case,
 +	** glxSwapBuffers is in both GL and X streams, in terms of
 +	** sequentiality.
 +	*/
 +	if (__glXForceCurrent(cl, tag, &error)) {
 +	    /*
 +	    ** Do whatever is needed to make sure that all preceding requests
 +	    ** in both streams are completed before the swap is executed.
 +	    */
 +	    CALL_Finish( GET_DISPATCH(), () );
 +	    __GLX_NOTE_FLUSHED_CMDS(glxc);
 +	} else {
 +	    return error;
 +	}
 +    }
 +
 +    pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
 +    if (!pGlxDraw)
 +	return error;
 +
 +    if (pGlxDraw == NULL ||
 +	pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
 +	pGlxDraw->copySubBuffer == NULL)
 +	return __glXError(GLXBadDrawable);
 +
 +    (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height);
 +
 +    return Success;
 +}
 +
 +/*
 +** Get drawable attributes
 +*/
 +static int
 +DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetDrawableAttributesReply reply;
 +    __GLXdrawable *pGlxDraw;
 +    CARD32 attributes[6];
 +    int numAttribs, error;
 +
 +    if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
 +			  DixGetAttrAccess, &pGlxDraw, &error))
 +	return error;
 +
 +    numAttribs = 3;
 +    reply.length = numAttribs << 1;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +    reply.numAttribs = numAttribs;
 +
 +    attributes[0] = GLX_TEXTURE_TARGET_EXT;
 +    attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
 +	GLX_TEXTURE_RECTANGLE_EXT;
 +    attributes[2] = GLX_Y_INVERTED_EXT;
 +    attributes[3] = GL_FALSE;
 +    attributes[4] = GLX_EVENT_MASK;
 +    attributes[5] = pGlxDraw->eventMask;
 +
 +    if (client->swapped) {
 +	__glXSwapGetDrawableAttributesReply(client, &reply, attributes);
 +    } else {
 +	WriteToClient(client, sz_xGLXGetDrawableAttributesReply,
 +		      (char *)&reply);
 +	WriteToClient(client, reply.length * sizeof (CARD32),
 +		      (char *)attributes);
 +    }
 +
 +    return Success;
 +}
 +
 +int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
 +
 +    /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
 +    REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
 +
 +    return DoGetDrawableAttributes(cl, req->drawable);
 +}
 +
 +int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetDrawableAttributesSGIXReq *req =
 +	(xGLXGetDrawableAttributesSGIXReq *)pc;
 +    
 +    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq);
 +
 +    return DoGetDrawableAttributes(cl, req->drawable);
 +}
 +
 +/************************************************************************/
 +
 +/*
 +** Render and Renderlarge are not in the GLX API.  They are used by the GLX
 +** client library to send batches of GL rendering commands.
 +*/
 +
 +/*
 +** Execute all the drawing commands in a request.
 +*/
 +int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXRenderReq *req;
 +    ClientPtr client= cl->client;
 +    int left, cmdlen, error;
 +    int commandsDone;
 +    CARD16 opcode;
 +    __GLXrenderHeader *hdr;
 +    __GLXcontext *glxc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXRenderReq);
 +
 +    req = (xGLXRenderReq *) pc;
 +    if (client->swapped) {
 +	__GLX_SWAP_SHORT(&req->length);
 +	__GLX_SWAP_INT(&req->contextTag);
 +    }
 +
 +    glxc = __glXForceCurrent(cl, req->contextTag, &error);
 +    if (!glxc) {
 +	return error;
 +    }
 +
 +    commandsDone = 0;
 +    pc += sz_xGLXRenderReq;
 +    left = (req->length << 2) - sz_xGLXRenderReq;
 +    while (left > 0) {
 +        __GLXrenderSizeData entry;
 +        int extra;
 +	__GLXdispatchRenderProcPtr proc;
 +	int err;
 +
 +	if (left < sizeof(__GLXrenderHeader))
 +	    return BadLength;
 +
 +	/*
 +	** Verify that the header length and the overall length agree.
 +	** Also, each command must be word aligned.
 +	*/
 +	hdr = (__GLXrenderHeader *) pc;
 +	if (client->swapped) {
 +	    __GLX_SWAP_SHORT(&hdr->length);
 +	    __GLX_SWAP_SHORT(&hdr->opcode);
 +	}
 +	cmdlen = hdr->length;
 +	opcode = hdr->opcode;
 +
 +	/*
 +	** Check for core opcodes and grab entry data.
 +	*/
 +	err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
 +	proc = (__GLXdispatchRenderProcPtr)
 +	    __glXGetProtocolDecodeFunction(& Render_dispatch_info,
 +					   opcode, client->swapped);
 +
 +	if ((err < 0) || (proc == NULL)) {
 +	    client->errorValue = commandsDone;
 +	    return __glXError(GLXBadRenderRequest);
 +	}
 +
 +        if (entry.varsize) {
 +            /* variable size command */
 +            extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
 +				     client->swapped);
 +            if (extra < 0) {
 +                extra = 0;
 +            }
 +            if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
 +                return BadLength;
 +            }
 +        } else {
 +            /* constant size command */
 +            if (cmdlen != __GLX_PAD(entry.bytes)) {
 +                return BadLength;
 +            }
 +        }
 +	if (left < cmdlen) {
 +	    return BadLength;
 +	}
 +
 +	/*
 +	** Skip over the header and execute the command.  We allow the
 +	** caller to trash the command memory.  This is useful especially
 +	** for things that require double alignment - they can just shift
 +	** the data towards lower memory (trashing the header) by 4 bytes
 +	** and achieve the required alignment.
 +	*/
 +	(*proc)(pc + __GLX_RENDER_HDR_SIZE);
 +	pc += cmdlen;
 +	left -= cmdlen;
 +	commandsDone++;
 +    }
 +    __GLX_NOTE_UNFLUSHED_CMDS(glxc);
 +    return Success;
 +}
 +
 +
 +/*
 +** Execute a large rendering request (one that spans multiple X requests).
 +*/
 +int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXRenderLargeReq *req;
 +    ClientPtr client= cl->client;
 +    size_t dataBytes;
 +    __GLXrenderLargeHeader *hdr;
 +    __GLXcontext *glxc;
 +    int error;
 +    CARD16 opcode;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    
 +    req = (xGLXRenderLargeReq *) pc;
 +    if (client->swapped) {
 +	__GLX_SWAP_SHORT(&req->length);
 +	__GLX_SWAP_INT(&req->contextTag);
 +	__GLX_SWAP_INT(&req->dataBytes);
 +	__GLX_SWAP_SHORT(&req->requestNumber);
 +	__GLX_SWAP_SHORT(&req->requestTotal);
 +    }
 +
 +    glxc = __glXForceCurrent(cl, req->contextTag, &error);
 +    if (!glxc) {
 +	/* Reset in case this isn't 1st request. */
 +	__glXResetLargeCommandStatus(cl);
 +	return error;
 +    }
 +    dataBytes = req->dataBytes;
 +
 +    /*
 +    ** Check the request length.
 +    */
 +    if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
 +	client->errorValue = req->length;
 +	/* Reset in case this isn't 1st request. */
 +	__glXResetLargeCommandStatus(cl);
 +	return BadLength;
 +    }
 +    pc += sz_xGLXRenderLargeReq;
 +    
 +    if (cl->largeCmdRequestsSoFar == 0) {
 +	__GLXrenderSizeData entry;
 +	int extra;
 +	size_t cmdlen;
 +	int err;
 +
 +	/*
 +	** This is the first request of a multi request command.
 +	** Make enough space in the buffer, then copy the entire request.
 +	*/
 +	if (req->requestNumber != 1) {
 +	    client->errorValue = req->requestNumber;
 +	    return __glXError(GLXBadLargeRequest);
 +	}
 +
 +	hdr = (__GLXrenderLargeHeader *) pc;
 +	if (client->swapped) {
 +	    __GLX_SWAP_INT(&hdr->length);
 +	    __GLX_SWAP_INT(&hdr->opcode);
 +	}
 +	cmdlen = hdr->length;
 +	opcode = hdr->opcode;
 +
 +	/*
 +	** Check for core opcodes and grab entry data.
 +	*/
 +	err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
 +	if (err < 0) {
 +	    client->errorValue = opcode;
 +	    return __glXError(GLXBadLargeRequest);
 +	}
 +
 +	if (entry.varsize) {
 +	    /*
 +	    ** If it's a variable-size command (a command whose length must
 +	    ** be computed from its parameters), all the parameters needed
 +	    ** will be in the 1st request, so it's okay to do this.
 +	    */
 +	    extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
 +				     client->swapped);
 +	    if (extra < 0) {
 +		extra = 0;
 +	    }
 +	    /* large command's header is 4 bytes longer, so add 4 */
 +	    if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
 +		return BadLength;
 +	    }
 +	} else {
 +	    /* constant size command */
 +	    if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
 +		return BadLength;
 +	    }
 +	}
 +	/*
 +	** Make enough space in the buffer, then copy the entire request.
 +	*/
 +	if (cl->largeCmdBufSize < cmdlen) {
 +	    if (!cl->largeCmdBuf) {
 +		cl->largeCmdBuf = (GLbyte *) malloc(cmdlen);
 +	    } else {
 +		cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen);
 +	    }
 +	    if (!cl->largeCmdBuf) {
 +		return BadAlloc;
 +	    }
 +	    cl->largeCmdBufSize = cmdlen;
 +	}
 +	memcpy(cl->largeCmdBuf, pc, dataBytes);
 +
 +	cl->largeCmdBytesSoFar = dataBytes;
 +	cl->largeCmdBytesTotal = cmdlen;
 +	cl->largeCmdRequestsSoFar = 1;
 +	cl->largeCmdRequestsTotal = req->requestTotal;
 +	return Success;
 +	
 +    } else {
 +	/*
 +	** We are receiving subsequent (i.e. not the first) requests of a
 +	** multi request command.
 +	*/
 +
 +	/*
 +	** Check the request number and the total request count.
 +	*/
 +	if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
 +	    client->errorValue = req->requestNumber;
 +	    __glXResetLargeCommandStatus(cl);
 +	    return __glXError(GLXBadLargeRequest);
 +	}
 +	if (req->requestTotal != cl->largeCmdRequestsTotal) {
 +	    client->errorValue = req->requestTotal;
 +	    __glXResetLargeCommandStatus(cl);
 +	    return __glXError(GLXBadLargeRequest);
 +	}
 +
 +	/*
 +	** Check that we didn't get too much data.
 +	*/
 +	if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
 +	    client->errorValue = dataBytes;
 +	    __glXResetLargeCommandStatus(cl);
 +	    return __glXError(GLXBadLargeRequest);
 +	}
 +	memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
 +	cl->largeCmdBytesSoFar += dataBytes;
 +	cl->largeCmdRequestsSoFar++;
 +
 +	if (req->requestNumber == cl->largeCmdRequestsTotal) {
 +	    __GLXdispatchRenderProcPtr proc;
 +
 +	    /*
 +	    ** This is the last request; it must have enough bytes to complete
 +	    ** the command.
 +	    */
 +	    /* NOTE: the two pad macros have been added below; they are needed
 +	    ** because the client library pads the total byte count, but not
 +	    ** the per-request byte counts.  The Protocol Encoding says the
 +	    ** total byte count should not be padded, so a proposal will be 
 +	    ** made to the ARB to relax the padding constraint on the total 
 +	    ** byte count, thus preserving backward compatibility.  Meanwhile, 
 +	    ** the padding done below fixes a bug that did not allow
 +	    ** large commands of odd sizes to be accepted by the server.
 +	    */
 +	    if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
 +		__GLX_PAD(cl->largeCmdBytesTotal)) {
 +		client->errorValue = dataBytes;
 +		__glXResetLargeCommandStatus(cl);
 +		return __glXError(GLXBadLargeRequest);
 +	    }
 +	    hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
 +	    /*
 +	    ** The opcode and length field in the header had already been
 +	    ** swapped when the first request was received.
 +	    **
 +	    ** Use the opcode to index into the procedure table.
 +	    */
 +	    opcode = hdr->opcode;
 +
 +	    proc = (__GLXdispatchRenderProcPtr)
 +	      __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
 +					     client->swapped);
 +	    if (proc == NULL) {
 +		client->errorValue = opcode;
 +		return __glXError(GLXBadLargeRequest);
 +	    }
 +
 +	    /*
 +	    ** Skip over the header and execute the command.
 +	    */
 +	    (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
 +	    __GLX_NOTE_UNFLUSHED_CMDS(glxc);
 +
 +	    /*
 +	    ** Reset for the next RenderLarge series.
 +	    */
 +	    __glXResetLargeCommandStatus(cl);
 +	} else {
 +	    /*
 +	    ** This is neither the first nor the last request.
 +	    */
 +	}
 +	return Success;
 +    }
 +}
 +
 +/************************************************************************/
 +
 +/*
 +** No support is provided for the vendor-private requests other than
 +** allocating the entry points in the dispatch table.
 +*/
 +
 +int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLint vendorcode = req->vendorCode;
 +    __GLXdispatchVendorPrivProcPtr proc;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
 +
 +    proc = (__GLXdispatchVendorPrivProcPtr)
 +      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
 +				     vendorcode, 0);
 +    if (proc != NULL) {
 +	(*proc)(cl, (GLbyte*)req);
 +	return Success;
 +    }
 +
 +    cl->client->errorValue = req->vendorCode;
 +    return __glXError(GLXUnsupportedPrivateRequest);
 +}
 +
 +int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLint vendorcode = req->vendorCode;
 +    __GLXdispatchVendorPrivProcPtr proc;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
 +
 +    proc = (__GLXdispatchVendorPrivProcPtr)
 +      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
 +				     vendorcode, 0);
 +    if (proc != NULL) {
 +	return (*proc)(cl, (GLbyte*)req);
 +    }
 +
 +    cl->client->errorValue = vendorcode;
 +    return __glXError(GLXUnsupportedPrivateRequest);
 +}
 +
 +int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
 +    xGLXQueryExtensionsStringReply reply;
 +    __GLXscreen *pGlxScreen;
 +    size_t n, length;
 +    char *buf;
 +    int err;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq);
 +
 +    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
 +	return err;
 +
 +    n = strlen(pGlxScreen->GLXextensions) + 1;
 +    length = __GLX_PAD(n) >> 2;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +    reply.length = length;
 +    reply.n = n;
 +
 +    /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/
 +    buf = (char *) malloc(length << 2);
 +    if (buf == NULL)
 +        return BadAlloc;
 +    memcpy(buf, pGlxScreen->GLXextensions, n);
 +
 +    if (client->swapped) {
 +        glxSwapQueryExtensionsStringReply(client, &reply, buf);
 +    } else {
 +        WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
 +        WriteToClient(client, (int)(length << 2), (char *)buf);
 +    }
 +
 +    free(buf);
 +    return Success;
 +}
 +
 +int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
 +    xGLXQueryServerStringReply reply;
 +    size_t n, length;
 +    const char *ptr;
 +    char *buf;
 +    __GLXscreen *pGlxScreen;
 +    int err;
 +    char ver_str[16];
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryServerStringReq);
 +
 +    if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
 +	return err;
 +
 +    switch(req->name) {
 +	case GLX_VENDOR:
 +	    ptr = pGlxScreen->GLXvendor;
 +	    break;
 +	case GLX_VERSION:
 +	    /* Return to the server version rather than the screen version
 +	     * to prevent confusion when they do not match.
 +	     */
 +	    snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion);
 +	    ptr = ver_str;
 +	    break;
 +	case GLX_EXTENSIONS:
 +	    ptr = pGlxScreen->GLXextensions;
 +	    break;
 +	default:
 +	    return BadValue; 
 +    }
 +
 +    n = strlen(ptr) + 1;
 +    length = __GLX_PAD(n) >> 2;
 +    reply.type = X_Reply;
 +    reply.sequenceNumber = client->sequence;
 +    reply.length = length;
 +    reply.n = n;
 +
 +    buf = (char *) malloc(length << 2);
 +    if (buf == NULL) {
 +        return BadAlloc;
 +    }
 +    memcpy(buf, ptr, n);
 +
 +    if (client->swapped) {
 +        glxSwapQueryServerStringReply(client, &reply, buf);
 +    } else {
 +        WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
 +        WriteToClient(client, (int)(length << 2), buf);
 +    }
 +
 +    free(buf);
 +    return Success;
 +}
 +
 +int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
 +    const char *buf;
 +   
 +    REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
 +
 +    buf = (const char *)(req+1);
 +    if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq)))
 +	return BadLength;
 +
 +    cl->GLClientmajorVersion = req->major;
 +    cl->GLClientminorVersion = req->minor;
 +    free(cl->GLClientextensions);
 +    cl->GLClientextensions = strdup(buf);
 +
 +    return Success;
 +}
 diff --git a/xorg-server/glx/glxcmdsswap.c b/xorg-server/glx/glxcmdsswap.c index 3bb4cade9..a7689ed46 100644 --- a/xorg-server/glx/glxcmdsswap.c +++ b/xorg-server/glx/glxcmdsswap.c @@ -1,915 +1,921 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. 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. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> -#include "glxserver.h" -#include "glxutil.h" -#include <GL/glxtokens.h> -#include <unpack.h> -#include <pixmapstr.h> -#include <windowstr.h> -#include "glxext.h" -#include "glapitable.h" -#include "glapi.h" -#include "glthread.h" -#include "dispatch.h" -#include "indirect_dispatch.h" -#include "indirect_table.h" -#include "indirect_util.h" - - -/************************************************************************/ - -/* -** Byteswapping versions of GLX commands.  In most cases they just swap -** the incoming arguments and then call the unswapped routine.  For commands -** that have replies, a separate swapping routine for the reply is provided; -** it is called at the end of the unswapped routine. -*/ - -int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateContextReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->visual); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->shareList); - -    return __glXDisp_CreateContext(cl, pc); -} - -int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateNewContextReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->renderType); -    __GLX_SWAP_INT(&req->shareList); - -    return __glXDisp_CreateNewContext(cl, pc); -} - -int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateContextWithConfigSGIXReq *req = -	(xGLXCreateContextWithConfigSGIXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->renderType); -    __GLX_SWAP_INT(&req->shareList); - -    return __glXDisp_CreateContextWithConfigSGIX(cl, pc); -} - -int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyContextReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); - -    return __glXDisp_DestroyContext(cl, pc); -} - -int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXMakeCurrentReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->drawable); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->oldContextTag); - -    return __glXDisp_MakeCurrent(cl, pc); -} - -int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->drawable); -    __GLX_SWAP_INT(&req->readdrawable); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->oldContextTag); - -    return __glXDisp_MakeContextCurrent(cl, pc); -} - -int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->drawable); -    __GLX_SWAP_INT(&req->readable); -    __GLX_SWAP_INT(&req->context); -    __GLX_SWAP_INT(&req->oldContextTag); - -    return __glXDisp_MakeCurrentReadSGI(cl, pc); -} - -int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXIsDirectReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); - -    return __glXDisp_IsDirect(cl, pc); -} - -int __glXDispSwap_QueryVersion(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXQueryVersionReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->majorVersion); -    __GLX_SWAP_INT(&req->minorVersion); - -    return __glXDisp_QueryVersion(cl, pc); -} - -int __glXDispSwap_WaitGL(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXWaitGLReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); - -    return __glXDisp_WaitGL(cl, pc); -} - -int __glXDispSwap_WaitX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXWaitXReq *req = (xGLXWaitXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXWaitXReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); - -    return __glXDisp_WaitX(cl, pc); -} - -int __glXDispSwap_CopyContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCopyContextReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->source); -    __GLX_SWAP_INT(&req->dest); -    __GLX_SWAP_INT(&req->mask); - -    return __glXDisp_CopyContext(cl, pc); -} - -int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq); - -    __GLX_SWAP_INT(&req->screen); -    return __glXDisp_GetVisualConfigs(cl, pc); -} - -int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq); - -    __GLX_SWAP_INT(&req->screen); -    return __glXDisp_GetFBConfigs(cl, pc); -} - -int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetFBConfigsSGIXReq); - -    __GLX_SWAP_INT(&req->screen); -    return __glXDisp_GetFBConfigsSGIX(cl, pc); -} - -int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->visual); -    __GLX_SWAP_INT(&req->pixmap); -    __GLX_SWAP_INT(&req->glxpixmap); - -    return __glXDisp_CreateGLXPixmap(cl, pc); -} - -int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; -    CARD32 *attribs; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - -    REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->pixmap); -    __GLX_SWAP_INT(&req->glxpixmap); -    __GLX_SWAP_INT(&req->numAttribs); - -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); -    attribs = (CARD32*)(req + 1); -    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); - -    return __glXDisp_CreatePixmap(cl, pc); -} - -int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPixmapWithConfigSGIXReq *req =  -	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->pixmap); -    __GLX_SWAP_INT(&req->glxpixmap); - -    return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc); -} - -int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->glxpixmap); - -    return __glXDisp_DestroyGLXPixmap(cl, pc); -} - -int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->glxpixmap); - -    return __glXDisp_DestroyGLXPixmap(cl, pc); -} - -int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;     -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXQueryContextReq); - -    __GLX_SWAP_INT(&req->context); - -    return __glXDisp_QueryContext(cl, pc); -} - -int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;     -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    CARD32 *attribs; - -    REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); - -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->pbuffer); -    __GLX_SWAP_INT(&req->numAttribs); - -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); -    attribs = (CARD32*)(req + 1); -    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); - -    return __glXDisp_CreatePbuffer(cl, pc); -} - -int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;     -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXCreateGLXPbufferSGIXReq); - -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->pbuffer); -    __GLX_SWAP_INT(&req->width); -    __GLX_SWAP_INT(&req->height); - -    return __glXDisp_CreateGLXPbufferSGIX(cl, pc); -} - -int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); - -    __GLX_SWAP_INT(&req->pbuffer); - -    return __glXDisp_DestroyPbuffer(cl, pc); -} - -int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); - -    __GLX_SWAP_INT(&req->pbuffer); - -    return __glXDisp_DestroyGLXPbufferSGIX(cl, pc); -} - -int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXChangeDrawableAttributesReq *req = -	(xGLXChangeDrawableAttributesReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    CARD32 *attribs; - -    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); - -    __GLX_SWAP_INT(&req->drawable); -    __GLX_SWAP_INT(&req->numAttribs); - -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); -    attribs = (CARD32*)(req + 1); -    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); - -    return __glXDisp_ChangeDrawableAttributes(cl, pc); -} - -int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl, -					       GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXChangeDrawableAttributesSGIXReq *req = -	(xGLXChangeDrawableAttributesSGIXReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    CARD32 *attribs; - -    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); - -    __GLX_SWAP_INT(&req->drawable); -    __GLX_SWAP_INT(&req->numAttribs); - -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3); -    attribs = (CARD32*)(req + 1); -    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); - -    return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc); -} - -int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    CARD32 *attribs; - -    REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); - -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->fbconfig); -    __GLX_SWAP_INT(&req->window); -    __GLX_SWAP_INT(&req->glxwindow); -    __GLX_SWAP_INT(&req->numAttribs); - -    if (req->numAttribs > (UINT32_MAX >> 3)) { -	client->errorValue = req->numAttribs; -	return BadValue; -    } -    REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); -    attribs = (CARD32*)(req + 1); -    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1); - -    return __glXDisp_CreateWindow(cl, pc); -} - -int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXDestroyWindowReq); - -    __GLX_SWAP_INT(&req->glxwindow); - -    return __glXDisp_DestroyWindow(cl, pc); -} - -int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXSwapBuffersReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(&req->drawable); - -    return __glXDisp_SwapBuffers(cl, pc); -} - -int __glXDispSwap_UseXFont(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXUseXFontReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(&req->font); -    __GLX_SWAP_INT(&req->first); -    __GLX_SWAP_INT(&req->count); -    __GLX_SWAP_INT(&req->listBase); - -    return __glXDisp_UseXFont(cl, pc); -} - - -int __glXDispSwap_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *)pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->screen); - -    return __glXDisp_QueryExtensionsString(cl, pc); -} - -int __glXDispSwap_QueryServerString(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXQueryServerStringReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->screen); -    __GLX_SWAP_INT(&req->name); - -    return __glXDisp_QueryServerString(cl, pc); -} - -int __glXDispSwap_ClientInfo(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->major); -    __GLX_SWAP_INT(&req->minor); -    __GLX_SWAP_INT(&req->numbytes); - -    return __glXDisp_ClientInfo(cl, pc); -} - -int __glXDispSwap_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->context); - -    return __glXDisp_QueryContextInfoEXT(cl, pc); -} - -int __glXDispSwap_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLXDrawable		 *drawId; -    int			 *buffer; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    drawId = ((GLXDrawable *) (pc)); -    buffer = ((int *)	      (pc + 4)); -     -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(drawId); -    __GLX_SWAP_INT(buffer); - -    return __glXDisp_BindTexImageEXT(cl, (GLbyte *)pc); -} - -int __glXDispSwap_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLXDrawable		 *drawId; -    int			 *buffer; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    drawId = ((GLXDrawable *) (pc)); -    buffer = ((int *)	      (pc + 4)); -     -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(drawId); -    __GLX_SWAP_INT(buffer); - -    return __glXDisp_ReleaseTexImageEXT(cl, (GLbyte *)pc); -} - -int __glXDispSwap_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; -    GLXDrawable		 *drawId; -    int			 *buffer; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); - -    (void) drawId; -    (void) buffer; - -    pc += __GLX_VENDPRIV_HDR_SIZE; - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(pc); -    __GLX_SWAP_INT(pc + 4); -    __GLX_SWAP_INT(pc + 8); -    __GLX_SWAP_INT(pc + 12); -    __GLX_SWAP_INT(pc + 16); - -    return __glXDisp_CopySubBufferMESA(cl, pc); - -} - -int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc; -    CARD32 *data; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); - -    data = (CARD32 *) (req + 1); -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->contextTag); -    __GLX_SWAP_INT(data); - -    return __glXDisp_GetDrawableAttributesSGIX(cl, pc); -} - -int __glXDispSwap_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ -    ClientPtr client = cl->client; -    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; -    __GLX_DECLARE_SWAP_VARIABLES; - -    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesReq); - -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->drawable); - -    return __glXDisp_GetDrawableAttributes(cl, pc); -} - - -/************************************************************************/ - -/* -** Swap replies. -*/ - -void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReply *reply) -{ -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->contextTag); -    WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)reply); -} - -void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply) -{ -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply); -} - -void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply) -{ -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->majorVersion); -    __GLX_SWAP_INT(&reply->minorVersion); -    WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply); -} - -void glxSwapQueryExtensionsStringReply(ClientPtr client, -				       xGLXQueryExtensionsStringReply *reply, char *buf) -{ -    int length = reply->length; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->n); -    WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply); -    __GLX_SWAP_INT_ARRAY((int *)buf, length); -    WriteToClient(client, length << 2, buf); -} - -void glxSwapQueryServerStringReply(ClientPtr client, -				   xGLXQueryServerStringReply *reply, char *buf) -{ -    int length = reply->length; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->n); -    WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply); -    /** no swap is needed for an array of chars **/ -    /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */ -    WriteToClient(client, length << 2, buf); -} - -void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf) -{ -    int length = reply->length; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->n); -    WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply); -    __GLX_SWAP_INT_ARRAY((int *)buf, length); -    WriteToClient(client, length << 2, (char *)buf); -} - -void __glXSwapGetDrawableAttributesReply(ClientPtr client, -					 xGLXGetDrawableAttributesReply *reply, CARD32 *buf) -{ -    int length = reply->length; -    __GLX_DECLARE_SWAP_VARIABLES; -    __GLX_DECLARE_SWAP_ARRAY_VARIABLES; -    __GLX_SWAP_SHORT(&reply->sequenceNumber); -    __GLX_SWAP_INT(&reply->length); -    __GLX_SWAP_INT(&reply->numAttribs); -    WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply); -    __GLX_SWAP_INT_ARRAY((int *)buf, length); -    WriteToClient(client, length << 2, (char *)buf); -} - -/************************************************************************/ - -/* -** Render and Renderlarge are not in the GLX API.  They are used by the GLX -** client library to send batches of GL rendering commands. -*/ - -int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc) -{ -    return __glXDisp_Render(cl, pc); -} - -/* -** Execute a large rendering request (one that spans multiple X requests). -*/ -int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc) -{ -    return __glXDisp_RenderLarge(cl, pc); -} - -/************************************************************************/ - -/* -** No support is provided for the vendor-private requests other than -** allocating these entry points in the dispatch table. -*/ - -int __glXDispSwap_VendorPrivate(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXVendorPrivateReq *req; -    GLint vendorcode; -    __GLXdispatchVendorPrivProcPtr proc; - -    __GLX_DECLARE_SWAP_VARIABLES; - -    req = (xGLXVendorPrivateReq *) pc; -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->vendorCode); - -    vendorcode = req->vendorCode; - -    proc = (__GLXdispatchVendorPrivProcPtr) -      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, -				     vendorcode, 1); -    if (proc != NULL) { -	(*proc)(cl, (GLbyte*)req); -	return Success; -    } - -    cl->client->errorValue = req->vendorCode; -    return __glXError(GLXUnsupportedPrivateRequest); -} - - -int __glXDispSwap_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) -{ -    xGLXVendorPrivateWithReplyReq *req; -    GLint vendorcode; -    __GLXdispatchVendorPrivProcPtr proc; - -    __GLX_DECLARE_SWAP_VARIABLES; - -    req = (xGLXVendorPrivateWithReplyReq *) pc; -    __GLX_SWAP_SHORT(&req->length); -    __GLX_SWAP_INT(&req->vendorCode); - -    vendorcode = req->vendorCode; - -    proc = (__GLXdispatchVendorPrivProcPtr) -      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, -				     vendorcode, 1); -    if (proc != NULL) { -	return (*proc)(cl, (GLbyte*)req); -    } - -    cl->client->errorValue = req->vendorCode; -    return __glXError(GLXUnsupportedPrivateRequest); -} +/*
 + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 + * Copyright (C) 1991-2000 Silicon Graphics, Inc. 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
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * 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 including the dates of first publication and
 + * either this permission notice or a reference to
 + * http://oss.sgi.com/projects/FreeB/
 + * 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 NONINFRINGEMENT. IN NO EVENT SHALL
 + * SILICON GRAPHICS, INC. 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.
 + *
 + * Except as contained in this notice, the name of Silicon Graphics, Inc.
 + * shall not be used in advertising or otherwise to promote the sale, use or
 + * other dealings in this Software without prior written authorization from
 + * Silicon Graphics, Inc.
 + */
 +
 +#ifdef HAVE_DIX_CONFIG_H
 +#include <dix-config.h>
 +#endif
 +
 +#include <string.h>
 +#include "glxserver.h"
 +#include "glxutil.h"
 +#include <GL/glxtokens.h>
 +#include <unpack.h>
 +#include <pixmapstr.h>
 +#include <windowstr.h>
 +#include "glxext.h"
 +#include "glapitable.h"
 +#include "glapi.h"
 +#include "glthread.h"
 +#include "dispatch.h"
 +#include "indirect_dispatch.h"
 +#include "indirect_table.h"
 +#include "indirect_util.h"
 +
 +
 +/************************************************************************/
 +
 +/*
 +** Byteswapping versions of GLX commands.  In most cases they just swap
 +** the incoming arguments and then call the unswapped routine.  For commands
 +** that have replies, a separate swapping routine for the reply is provided;
 +** it is called at the end of the unswapped routine.
 +*/
 +
 +int __glXDispSwap_CreateContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateContextReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->visual);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->shareList);
 +
 +    return __glXDisp_CreateContext(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateNewContextReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->renderType);
 +    __GLX_SWAP_INT(&req->shareList);
 +
 +    return __glXDisp_CreateNewContext(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateContextWithConfigSGIXReq *req =
 +	(xGLXCreateContextWithConfigSGIXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->renderType);
 +    __GLX_SWAP_INT(&req->shareList);
 +
 +    return __glXDisp_CreateContextWithConfigSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyContextReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +
 +    return __glXDisp_DestroyContext(cl, pc);
 +}
 +
 +int __glXDispSwap_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeCurrentReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->drawable);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->oldContextTag);
 +
 +    return __glXDisp_MakeCurrent(cl, pc);
 +}
 +
 +int __glXDispSwap_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->drawable);
 +    __GLX_SWAP_INT(&req->readdrawable);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->oldContextTag);
 +
 +    return __glXDisp_MakeContextCurrent(cl, pc);
 +}
 +
 +int __glXDispSwap_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->drawable);
 +    __GLX_SWAP_INT(&req->readable);
 +    __GLX_SWAP_INT(&req->context);
 +    __GLX_SWAP_INT(&req->oldContextTag);
 +
 +    return __glXDisp_MakeCurrentReadSGI(cl, pc);
 +}
 +
 +int __glXDispSwap_IsDirect(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXIsDirectReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +
 +    return __glXDisp_IsDirect(cl, pc);
 +}
 +
 +int __glXDispSwap_QueryVersion(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryVersionReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->majorVersion);
 +    __GLX_SWAP_INT(&req->minorVersion);
 +
 +    return __glXDisp_QueryVersion(cl, pc);
 +}
 +
 +int __glXDispSwap_WaitGL(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXWaitGLReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +
 +    return __glXDisp_WaitGL(cl, pc);
 +}
 +
 +int __glXDispSwap_WaitX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXWaitXReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +
 +    return __glXDisp_WaitX(cl, pc);
 +}
 +
 +int __glXDispSwap_CopyContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCopyContextReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->source);
 +    __GLX_SWAP_INT(&req->dest);
 +    __GLX_SWAP_INT(&req->mask);
 +
 +    return __glXDisp_CopyContext(cl, pc);
 +}
 +
 +int __glXDispSwap_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    return __glXDisp_GetVisualConfigs(cl, pc);
 +}
 +
 +int __glXDispSwap_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    return __glXDisp_GetFBConfigs(cl, pc);
 +}
 +
 +int __glXDispSwap_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    return __glXDisp_GetFBConfigsSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->visual);
 +    __GLX_SWAP_INT(&req->pixmap);
 +    __GLX_SWAP_INT(&req->glxpixmap);
 +
 +    return __glXDisp_CreateGLXPixmap(cl, pc);
 +}
 +
 +int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
 +    CARD32 *attribs;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->pixmap);
 +    __GLX_SWAP_INT(&req->glxpixmap);
 +    __GLX_SWAP_INT(&req->numAttribs);
 +
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3);
 +    attribs = (CARD32*)(req + 1);
 +    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
 +
 +    return __glXDisp_CreatePixmap(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 +	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->pixmap);
 +    __GLX_SWAP_INT(&req->glxpixmap);
 +
 +    return __glXDisp_CreateGLXPixmapWithConfigSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->glxpixmap);
 +
 +    return __glXDisp_DestroyGLXPixmap(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXDestroyGLXPixmapReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->glxpixmap);
 +
 +    return __glXDisp_DestroyGLXPixmap(cl, pc);
 +}
 +
 +int __glXDispSwap_QueryContext(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;    
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryContextReq);
 +
 +    __GLX_SWAP_INT(&req->context);
 +
 +    return __glXDisp_QueryContext(cl, pc);
 +}
 +
 +int __glXDispSwap_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;    
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    CARD32 *attribs;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->pbuffer);
 +    __GLX_SWAP_INT(&req->numAttribs);
 +
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3);
 +    attribs = (CARD32*)(req + 1);
 +    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
 +
 +    return __glXDisp_CreatePbuffer(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;    
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->pbuffer);
 +    __GLX_SWAP_INT(&req->width);
 +    __GLX_SWAP_INT(&req->height);
 +
 +    return __glXDisp_CreateGLXPbufferSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq);
 +
 +    __GLX_SWAP_INT(&req->pbuffer);
 +
 +    return __glXDisp_DestroyPbuffer(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq);
 +
 +    __GLX_SWAP_INT(&req->pbuffer);
 +
 +    return __glXDisp_DestroyGLXPbufferSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXChangeDrawableAttributesReq *req =
 +	(xGLXChangeDrawableAttributesReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    CARD32 *attribs;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq);
 +
 +    __GLX_SWAP_INT(&req->drawable);
 +    __GLX_SWAP_INT(&req->numAttribs);
 +
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    if (((sizeof(xGLXChangeDrawableAttributesReq) + (req->numAttribs << 3)) >> 2) < client->req_len)
 +	return BadLength;
 +
 +    attribs = (CARD32*)(req + 1);
 +    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
 +
 +    return __glXDisp_ChangeDrawableAttributes(cl, pc);
 +}
 +
 +int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl,
 +					       GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXChangeDrawableAttributesSGIXReq *req =
 +	(xGLXChangeDrawableAttributesSGIXReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    CARD32 *attribs;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq);
 +
 +    __GLX_SWAP_INT(&req->drawable);
 +    __GLX_SWAP_INT(&req->numAttribs);
 +
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, req->numAttribs << 3);
 +    attribs = (CARD32*)(req + 1);
 +    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
 +
 +    return __glXDisp_ChangeDrawableAttributesSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    CARD32 *attribs;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq);
 +
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->fbconfig);
 +    __GLX_SWAP_INT(&req->window);
 +    __GLX_SWAP_INT(&req->glxwindow);
 +    __GLX_SWAP_INT(&req->numAttribs);
 +
 +    if (req->numAttribs > (UINT32_MAX >> 3)) {
 +	client->errorValue = req->numAttribs;
 +	return BadValue;
 +    }
 +    REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3);
 +    attribs = (CARD32*)(req + 1);
 +    __GLX_SWAP_INT_ARRAY(attribs, req->numAttribs << 1);
 +
 +    return __glXDisp_CreateWindow(cl, pc);
 +}
 +
 +int __glXDispSwap_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq);
 +
 +    __GLX_SWAP_INT(&req->glxwindow);
 +
 +    return __glXDisp_DestroyWindow(cl, pc);
 +}
 +
 +int __glXDispSwap_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXSwapBuffersReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(&req->drawable);
 +
 +    return __glXDisp_SwapBuffers(cl, pc);
 +}
 +
 +int __glXDispSwap_UseXFont(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXUseXFontReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(&req->font);
 +    __GLX_SWAP_INT(&req->first);
 +    __GLX_SWAP_INT(&req->count);
 +    __GLX_SWAP_INT(&req->listBase);
 +
 +    return __glXDisp_UseXFont(cl, pc);
 +}
 +
 +
 +int __glXDispSwap_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *)pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->screen);
 +
 +    return __glXDisp_QueryExtensionsString(cl, pc);
 +}
 +
 +int __glXDispSwap_QueryServerString(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryServerStringReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->screen);
 +    __GLX_SWAP_INT(&req->name);
 +
 +    return __glXDisp_QueryServerString(cl, pc);
 +}
 +
 +int __glXDispSwap_ClientInfo(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->major);
 +    __GLX_SWAP_INT(&req->minor);
 +    __GLX_SWAP_INT(&req->numbytes);
 +
 +    return __glXDisp_ClientInfo(cl, pc);
 +}
 +
 +int __glXDispSwap_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->context);
 +
 +    return __glXDisp_QueryContextInfoEXT(cl, pc);
 +}
 +
 +int __glXDispSwap_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLXDrawable		 *drawId;
 +    int			 *buffer;
 +    CARD32		 *num_attribs;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len)
 +	return BadLength;
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    drawId = ((GLXDrawable *) (pc));
 +    buffer = ((int *)	      (pc + 4));
 +    num_attribs = ((CARD32 *) (pc + 8));
 +    
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(drawId);
 +    __GLX_SWAP_INT(buffer);
 +    __GLX_SWAP_INT(num_attribs);
 +
 +    return __glXDisp_BindTexImageEXT(cl, (GLbyte *)pc);
 +}
 +
 +int __glXDispSwap_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLXDrawable		 *drawId;
 +    int			 *buffer;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8);
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    drawId = ((GLXDrawable *) (pc));
 +    buffer = ((int *)	      (pc + 4));
 +    
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(drawId);
 +    __GLX_SWAP_INT(buffer);
 +
 +    return __glXDisp_ReleaseTexImageEXT(cl, (GLbyte *)pc);
 +}
 +
 +int __glXDispSwap_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
 +    GLXDrawable		 *drawId;
 +    int			 *buffer;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20);
 +
 +    (void) drawId;
 +    (void) buffer;
 +
 +    pc += __GLX_VENDPRIV_HDR_SIZE;
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(pc);
 +    __GLX_SWAP_INT(pc + 4);
 +    __GLX_SWAP_INT(pc + 8);
 +    __GLX_SWAP_INT(pc + 12);
 +    __GLX_SWAP_INT(pc + 16);
 +
 +    return __glXDisp_CopySubBufferMESA(cl, pc);
 +
 +}
 +
 +int __glXDispSwap_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXVendorPrivateWithReplyReq *req = (xGLXVendorPrivateWithReplyReq *)pc;
 +    CARD32 *data;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq);
 +
 +    data = (CARD32 *) (req + 1);
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->contextTag);
 +    __GLX_SWAP_INT(data);
 +
 +    return __glXDisp_GetDrawableAttributesSGIX(cl, pc);
 +}
 +
 +int __glXDispSwap_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
 +{
 +    ClientPtr client = cl->client;
 +    xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq);
 +
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->drawable);
 +
 +    return __glXDisp_GetDrawableAttributes(cl, pc);
 +}
 +
 +
 +/************************************************************************/
 +
 +/*
 +** Swap replies.
 +*/
 +
 +void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReply *reply)
 +{
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->contextTag);
 +    WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)reply);
 +}
 +
 +void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply)
 +{
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    WriteToClient(client, sz_xGLXIsDirectReply, (char *)reply);
 +}
 +
 +void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply)
 +{
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->majorVersion);
 +    __GLX_SWAP_INT(&reply->minorVersion);
 +    WriteToClient(client, sz_xGLXQueryVersionReply, (char *)reply);
 +}
 +
 +void glxSwapQueryExtensionsStringReply(ClientPtr client,
 +				       xGLXQueryExtensionsStringReply *reply, char *buf)
 +{
 +    int length = reply->length;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->n);
 +    WriteToClient(client, sz_xGLXQueryExtensionsStringReply, (char *)reply);
 +    __GLX_SWAP_INT_ARRAY((int *)buf, length);
 +    WriteToClient(client, length << 2, buf);
 +}
 +
 +void glxSwapQueryServerStringReply(ClientPtr client,
 +				   xGLXQueryServerStringReply *reply, char *buf)
 +{
 +    int length = reply->length;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->n);
 +    WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)reply);
 +    /** no swap is needed for an array of chars **/
 +    /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
 +    WriteToClient(client, length << 2, buf);
 +}
 +
 +void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf)
 +{
 +    int length = reply->length;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->n);
 +    WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)reply);
 +    __GLX_SWAP_INT_ARRAY((int *)buf, length);
 +    WriteToClient(client, length << 2, (char *)buf);
 +}
 +
 +void __glXSwapGetDrawableAttributesReply(ClientPtr client,
 +					 xGLXGetDrawableAttributesReply *reply, CARD32 *buf)
 +{
 +    int length = reply->length;
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +    __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 +    __GLX_SWAP_SHORT(&reply->sequenceNumber);
 +    __GLX_SWAP_INT(&reply->length);
 +    __GLX_SWAP_INT(&reply->numAttribs);
 +    WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply);
 +    __GLX_SWAP_INT_ARRAY((int *)buf, length);
 +    WriteToClient(client, length << 2, (char *)buf);
 +}
 +
 +/************************************************************************/
 +
 +/*
 +** Render and Renderlarge are not in the GLX API.  They are used by the GLX
 +** client library to send batches of GL rendering commands.
 +*/
 +
 +int __glXDispSwap_Render(__GLXclientState *cl, GLbyte *pc)
 +{
 +    return __glXDisp_Render(cl, pc);
 +}
 +
 +/*
 +** Execute a large rendering request (one that spans multiple X requests).
 +*/
 +int __glXDispSwap_RenderLarge(__GLXclientState *cl, GLbyte *pc)
 +{
 +    return __glXDisp_RenderLarge(cl, pc);
 +}
 +
 +/************************************************************************/
 +
 +/*
 +** No support is provided for the vendor-private requests other than
 +** allocating these entry points in the dispatch table.
 +*/
 +
 +int __glXDispSwap_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXVendorPrivateReq *req;
 +    GLint vendorcode;
 +    __GLXdispatchVendorPrivProcPtr proc;
 +
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    req = (xGLXVendorPrivateReq *) pc;
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->vendorCode);
 +
 +    vendorcode = req->vendorCode;
 +
 +    proc = (__GLXdispatchVendorPrivProcPtr)
 +      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
 +				     vendorcode, 1);
 +    if (proc != NULL) {
 +	(*proc)(cl, (GLbyte*)req);
 +	return Success;
 +    }
 +
 +    cl->client->errorValue = req->vendorCode;
 +    return __glXError(GLXUnsupportedPrivateRequest);
 +}
 +
 +
 +int __glXDispSwap_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
 +{
 +    xGLXVendorPrivateWithReplyReq *req;
 +    GLint vendorcode;
 +    __GLXdispatchVendorPrivProcPtr proc;
 +
 +    __GLX_DECLARE_SWAP_VARIABLES;
 +
 +    req = (xGLXVendorPrivateWithReplyReq *) pc;
 +    __GLX_SWAP_SHORT(&req->length);
 +    __GLX_SWAP_INT(&req->vendorCode);
 +
 +    vendorcode = req->vendorCode;
 +
 +    proc = (__GLXdispatchVendorPrivProcPtr)
 +      __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
 +				     vendorcode, 1);
 +    if (proc != NULL) {
 +	return (*proc)(cl, (GLbyte*)req);
 +    }
 +
 +    cl->client->errorValue = req->vendorCode;
 +    return __glXError(GLXUnsupportedPrivateRequest);
 +}
 | 
