/* $XFree86: xc/programs/Xserver/GL/glx/glxcmdsswap.c,v 1.5 2001/03/21 16:29:36 dawes Exp $ */
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
** 
** http://oss.sgi.com/projects/FreeB
** 
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
** 
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
** 
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
**
*/

#define NEED_REPLIES
#define FONT_PCF
#include "glxserver.h"
#include "glxutil.h"
#include <GL/glxtokens.h>
#include <g_disptab.h>
#include <pixmapstr.h>
#include <windowstr.h>
#include "unpack.h"
#include "glxext.h"
#include "GL/glx_ansic.h"
#include "glxvendor.h"

extern int glxIsExtensionSupported( char *ext );

/************************************************************************/

/*
** 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 __glXSwapCreateContext(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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 __glXCreateContext(cl, pc);
}

int __glXSwapCreateNewContext(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);
    __GLX_SWAP_INT(&req->fbconfig);
    __GLX_SWAP_INT(&req->screen);
    __GLX_SWAP_INT(&req->shareList);

    return __glXCreateNewContext(cl, pc);
}

int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);
    __GLX_SWAP_INT(&req->fbconfig);
    __GLX_SWAP_INT(&req->screen);
    __GLX_SWAP_INT(&req->shareList);

    return __glXCreateContextWithConfigSGIX(cl, pc);
}

int __glXSwapQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
{
    xGLXQueryMaxSwapBarriersSGIXReq *req =
	(xGLXQueryMaxSwapBarriersSGIXReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->screen);

    return __glXQueryMaxSwapBarriersSGIX(cl, pc);
}

int __glXSwapBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
{
    xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->drawable);
    __GLX_SWAP_INT(&req->barrier);

    return __glXBindSwapBarrierSGIX(cl, pc);
}

int __glXSwapJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
{
    xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->drawable);
    __GLX_SWAP_INT(&req->member);

    return __glXJoinSwapGroupSGIX(cl, pc);
}

int __glXSwapDestroyContext(__GLXclientState *cl, GLbyte *pc)
{
    xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);

    return __glXDestroyContext(cl, pc);
}

int __glXSwapMakeCurrent(__GLXclientState *cl, GLbyte *pc)
{
    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->drawable);
    __GLX_SWAP_INT(&req->context);
    __GLX_SWAP_INT(&req->oldContextTag);

    return __glXMakeCurrent(cl, pc);
}

int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
{
    xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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 __glXMakeContextCurrent(cl, pc);
}

int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
{
    xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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 __glXMakeCurrentReadSGI(cl, pc);
}

int __glXSwapIsDirect(__GLXclientState *cl, GLbyte *pc)
{
    xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);

    return __glXIsDirect(cl, pc);
}

int __glXSwapQueryVersion(__GLXclientState *cl, GLbyte *pc)
{
    xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->majorVersion);
    __GLX_SWAP_INT(&req->minorVersion);

    return __glXQueryVersion(cl, pc);
}

int __glXSwapWaitGL(__GLXclientState *cl, GLbyte *pc)
{
    xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->contextTag);

    return __glXWaitGL(cl, pc);
}

int __glXSwapWaitX(__GLXclientState *cl, GLbyte *pc)
{
    xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->contextTag);

    return __glXWaitX(cl, pc);
}

int __glXSwapCopyContext(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->source);
    __GLX_SWAP_INT(&req->dest);
    __GLX_SWAP_INT(&req->mask);

    return __glXCopyContext(cl, pc);
}

int __glXSwapGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
{
   ClientPtr client = cl->client;
    xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
    xGLXGetVisualConfigsReply reply;
    __GLXscreenInfo *pGlxScreen;
    __GLXvisualConfig *pGlxVisual;
    CARD32 buf[__GLX_TOTAL_CONFIG];
    unsigned int screen;
    int i, p;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_INT(&req->screen);
    screen = req->screen;
    if (screen > screenInfo.numScreens) {
	/* The client library must send a valid screen number. */
	client->errorValue = screen;
	return BadValue;
    }
    pGlxScreen = &__glXActiveScreens[screen];

    reply.numVisuals = pGlxScreen->numGLXVisuals;
    reply.numProps = __GLX_TOTAL_CONFIG;
    reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
		    __GLX_TOTAL_CONFIG) >> 2;
    reply.type = X_Reply;
    reply.sequenceNumber = client->sequence;
    
    __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++) {
	pGlxVisual = &pGlxScreen->pGlxVisual[i];
	if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
	    /* not a usable visual */
	    continue;
	}
	p = 0;
	buf[p++] = pGlxVisual->vid;
	buf[p++] = pGlxVisual->class;
	buf[p++] = pGlxVisual->rgba;

	buf[p++] = pGlxVisual->redSize;
	buf[p++] = pGlxVisual->greenSize;
	buf[p++] = pGlxVisual->blueSize;
	buf[p++] = pGlxVisual->alphaSize;
	buf[p++] = pGlxVisual->accumRedSize;
	buf[p++] = pGlxVisual->accumGreenSize;
	buf[p++] = pGlxVisual->accumBlueSize;
	buf[p++] = pGlxVisual->accumAlphaSize;

	buf[p++] = pGlxVisual->doubleBuffer;
	buf[p++] = pGlxVisual->stereo;

	buf[p++] = pGlxVisual->bufferSize;
	buf[p++] = pGlxVisual->depthSize;
	buf[p++] = pGlxVisual->stencilSize;
	buf[p++] = pGlxVisual->auxBuffers;
	buf[p++] = pGlxVisual->level;
        /*
        ** Add token/value pairs for extensions.
        */
        buf[p++] = GLX_VISUAL_CAVEAT_EXT;
        buf[p++] = pGlxVisual->visualRating;
        buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
        buf[p++] = pGlxVisual->transparentPixel;
        buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
        buf[p++] = pGlxVisual->transparentRed;
        buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
        buf[p++] = pGlxVisual->transparentGreen;
        buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
        buf[p++] = pGlxVisual->transparentBlue;
        buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
        buf[p++] = pGlxVisual->transparentAlpha;
        buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
        buf[p++] = pGlxVisual->transparentIndex;

	__GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG);
	WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, 
			(char *)buf);
    }
    return Success;
}

int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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 __glXCreateGLXPixmap(cl, pc);
}

int __glXSwapCreatePixmap(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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);

    return __glXCreatePixmap(cl, pc);
}

int __glXSwapDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
    xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->glxpixmap);

    return __glXDestroyGLXPixmap(cl, pc);
}

int __glXSwapSwapBuffers(__GLXclientState *cl, GLbyte *pc)
{
    xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->contextTag);
    __GLX_SWAP_INT(&req->drawable);

    return __glXSwapBuffers(cl, pc);
}

int __glXSwapUseXFont(__GLXclientState *cl, GLbyte *pc)
{
    xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __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 __glXUseXFont(cl, pc);
}


int __glXSwapQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
{
    xGLXQueryExtensionsStringReq *req = NULL;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->screen);

    return __glXQueryExtensionsString(cl, pc);
}

int __glXSwapQueryServerString(__GLXclientState *cl, GLbyte *pc)
{
    xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->screen);
    __GLX_SWAP_INT(&req->name);

    return __glXQueryServerString(cl, pc);
}

int __glXSwapClientInfo(__GLXclientState *cl, GLbyte *pc)
{
    xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->major);
    __GLX_SWAP_INT(&req->minor);
    __GLX_SWAP_INT(&req->numbytes);

    return __glXClientInfo(cl, pc);
}

int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, char *pc)
{
    xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);

    return __glXQueryContextInfoEXT(cl, (GLbyte *)pc);
}

/************************************************************************/

/*
** Swap replies.
*/

void __glXSwapMakeCurrentReply(ClientPtr client,  xGLXMakeCurrentReadSGIReply *reply)
{
    __GLX_DECLARE_SWAP_VARIABLES;
    __GLX_SWAP_SHORT(&reply->sequenceNumber);
    __GLX_SWAP_INT(&reply->length);
    __GLX_SWAP_INT(&reply->contextTag);
    __GLX_SWAP_INT(&reply->writeVid);
    __GLX_SWAP_INT(&reply->writeType);
    __GLX_SWAP_INT(&reply->readVid);
    __GLX_SWAP_INT(&reply->readType);
    WriteToClient(client, sz_xGLXMakeCurrentReadSGIReply, (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_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_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 __glXSwapQueryContextReply(ClientPtr client,
                                xGLXQueryContextReply *reply, int *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_xGLXQueryContextReply, (char *)reply);
    __GLX_SWAP_INT_ARRAY((int *)buf, length);
    WriteToClient(client, length << 2, (char *)buf);
}

void __glXSwapGetDrawableAttributesReply(ClientPtr client,
                                 xGLXGetDrawableAttributesReply *reply, int *buf) 
{
    __GLX_DECLARE_SWAP_VARIABLES;
    __GLX_SWAP_SHORT(&reply->sequenceNumber);
    __GLX_SWAP_INT(&reply->length);
    __GLX_SWAP_INT(&reply->numAttribs);
    __GLX_SWAP_INT_ARRAY( buf, reply->length );
    WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)reply);
    WriteToClient(client, reply->length << 2, (char *)buf);
}

void __glXSwapQueryMaxSwapBarriersSGIXReply(ClientPtr client, xGLXQueryMaxSwapBarriersSGIXReply *reply)
{
    __GLX_DECLARE_SWAP_VARIABLES;
    __GLX_SWAP_SHORT(&reply->sequenceNumber);
    __GLX_SWAP_INT(&reply->length);
    __GLX_SWAP_INT(&reply->max);
    WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, (char *)reply);
}

/************************************************************************/

/*
** 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 __glXSwapRender(__GLXclientState *cl, GLbyte *pc)
{
    xGLXRenderReq *req;
    int left;
    __GLXrenderHeader *hdr;
    ClientPtr client = cl->client;
    __GLX_DECLARE_SWAP_VARIABLES;

    /*
    ** NOTE: much of this code also appears in the nonswapping version of this
    ** routine, __glXRender().  Any changes made here should also be
    ** duplicated there.
    */
    
    req = (xGLXRenderReq *) pc;
    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->contextTag);

    pc += sz_xGLXRenderReq;
    left = (req->length << 2) - sz_xGLXRenderReq;
    while (left > 0) {
	void (* proc)(GLbyte *);
	CARD16 opcode;

	/*
	** Verify that the header length and the overall length agree.
	** Also, each command must be word aligned.
	*/
	hdr = (__GLXrenderHeader *) pc;
	__GLX_SWAP_SHORT(&hdr->length);
	__GLX_SWAP_SHORT(&hdr->opcode);

	/*
         * call the command procedure to swap any arguments
	 */
	opcode = hdr->opcode;
	if ( (opcode >= __GLX_MIN_RENDER_OPCODE) && 
	     (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
	    proc = __glXSwapRenderTable[opcode];
#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
	} else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) && 
	     (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
	    int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
	    __GLXRenderSwapInfo *info = &__glXSwapRenderTable_EXT[index];
	    if (info->swapfunc) {
	       proc = info->swapfunc;
	    }
	    else {
	       proc = NULL;
	       if (info->elem_size == 4 && info->nelems > 0) {
		  __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_HDR_SIZE), 
			                info->nelems );
	       }
	       else if (info->elem_size == 2 && info->nelems > 0) {
		  __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_HDR_SIZE), 
			                info->nelems );
	       }
	       else if (info->elem_size == 8 && info->nelems > 0) {
		  __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_HDR_SIZE), 
			                info->nelems );
	       }
	    }
#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
	} else {
	    client->errorValue = 0;
	    return __glXBadRenderRequest;
	}

	if (proc != NULL) 
	   (*proc)(pc + __GLX_RENDER_HDR_SIZE);

	/*
	 * proceed to the next command
	 */ 
	pc += hdr->length;
	left -= hdr->length;
    }

    return __glXRender( cl, (GLbyte *)req );
}

/*
** Execute a large rendering request (one that spans multiple X requests).
*/
int __glXSwapRenderLarge(__GLXclientState *cl, GLbyte *pc)
{
   ClientPtr client = cl->client;
    xGLXRenderLargeReq *req;
    __GLXrenderLargeHeader *hdr;
    __GLX_DECLARE_SWAP_VARIABLES;

    req = (xGLXRenderLargeReq *) pc;
    __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);

    pc += sz_xGLXRenderLargeReq;
   
    if (req->requestNumber == 1) {
	void (* proc)(GLbyte *) = NULL;
	__GLXRenderSwapInfo *info = NULL;
	CARD16 opcode;

	hdr = (__GLXrenderLargeHeader *) pc;
	__GLX_SWAP_INT(&hdr->length);
	__GLX_SWAP_INT(&hdr->opcode);

	/*
         * call the command procedure to swap any arguments
	 * Note that we are assuming that all arguments that needs to be
	 * swaped are on the first req only !
	 */
	opcode = hdr->opcode;
	if ( (opcode >= __GLX_MIN_RENDER_OPCODE) && 
	     (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
	    proc = __glXSwapRenderTable[opcode];
#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
	} else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) && 
	     (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
	    int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
	    info = &__glXSwapRenderTable_EXT[index];
	    if (info->swapfunc) {
	       proc = info->swapfunc;
	    }
#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
	} else {
	    client->errorValue = 0;
	    cl->largeCmdRequestsTotal = 0;
	    return __glXBadLargeRequest;
	}

	/*
	** Make enough space in the buffer, then copy the entire request.
	*/
	if (cl->largeCmdBufSize < hdr->length) {
	    if (!cl->largeCmdBuf) {
		cl->largeCmdBuf = (GLbyte *) __glXMalloc(hdr->length);
	    } else {
		cl->largeCmdBuf = (GLbyte *) __glXRealloc(cl->largeCmdBuf, hdr->length);
	    }
	    if (!cl->largeCmdBuf) {
	       cl->largeCmdRequestsTotal = 0;
		return BadAlloc;
	    }
	    cl->largeCmdBufSize = hdr->length;
	}
	__glXMemcpy(cl->largeCmdBuf, pc, req->dataBytes);

	cl->largeCmdBytesSoFar = req->dataBytes;
	cl->largeCmdBytesTotal = hdr->length;
	cl->largeCmdRequestsSoFar = 1;
	cl->largeCmdRequestsTotal = req->requestTotal;
	cl->largeCmdRequestsSwapProc = proc;
	cl->largeCmdMaxReqDataSize = req->dataBytes;
	cl->largeCmdRequestsSwap_info = info;

	return Success;
	

    }
    else if (req->requestNumber < cl->largeCmdRequestsTotal) {
       /*
        * This is not the first nor last request - just copy the data
	*/
       if (  cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) {
	    cl->largeCmdRequestsTotal = 0;
	    return __glXBadLargeRequest;
       }

       __glXMemcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, 
	           pc, req->dataBytes);

       cl->largeCmdBytesSoFar += req->dataBytes;

       if (req->dataBytes > cl->largeCmdMaxReqDataSize)
	  cl->largeCmdMaxReqDataSize = req->dataBytes;

	return Success;
    }
    else if (req->requestNumber == cl->largeCmdRequestsTotal) {
       /*
        * this is the last request
        * copy the remainder bytes, call the procedure to swap any
	* needed data, and then call to transfer the command to all
	* back-end servers
	*/
       if (  cl->largeCmdBytesSoFar + req->dataBytes > cl->largeCmdBytesTotal) {
	    cl->largeCmdRequestsTotal = 0;
	    return __glXBadLargeRequest;
       }

       __glXMemcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, 
	           pc, req->dataBytes);

       cl->largeCmdBytesSoFar += req->dataBytes;

       if (req->dataBytes > cl->largeCmdMaxReqDataSize)
	  cl->largeCmdMaxReqDataSize = req->dataBytes;

	if (cl->largeCmdRequestsSwapProc != NULL) {
	   (*cl->largeCmdRequestsSwapProc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
	}
	else if (cl->largeCmdRequestsSwap_info &&
	         cl->largeCmdRequestsSwap_info->nelems > 0) {
    	   if (cl->largeCmdRequestsSwap_info->elem_size == 4) {
	      __GLX_SWAP_INT_ARRAY( (int *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), 
		       cl->largeCmdRequestsSwap_info->nelems );
	   }
	   else if (cl->largeCmdRequestsSwap_info->elem_size == 2) {
	      __GLX_SWAP_SHORT_ARRAY( (short *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), 
		       cl->largeCmdRequestsSwap_info->nelems );
	   }
	   else if (cl->largeCmdRequestsSwap_info->elem_size == 8) {
	      __GLX_SWAP_DOUBLE_ARRAY( (double *)(pc + __GLX_RENDER_LARGE_HDR_SIZE), 
		       cl->largeCmdRequestsSwap_info->nelems );
	   }
	}

	cl->largeCmdRequestsTotal = 0;
        return( __glXSendLargeCommand(cl, req->contextTag) );

    }
    else {
       cl->largeCmdRequestsTotal = 0;
       return __glXBadLargeRequest;
    }

}

/************************************************************************/

/*
** No support is provided for the vendor-private requests other than
** allocating these entry points in the dispatch table.
*/

int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc)
{
    xGLXVendorPrivateReq *req;
    CARD32 vendorCode;

    __GLX_DECLARE_SWAP_VARIABLES;

    req = (xGLXVendorPrivateReq *) pc;
    vendorCode = req->vendorCode;
    __GLX_SWAP_INT(&vendorCode);


    switch( vendorCode ) {

       case X_GLvop_DeleteTexturesEXT:
	  return __glXVForwardSingleReqSwap( cl, pc );
	  break;

       case X_GLXvop_SwapIntervalSGI:
	  if (glxIsExtensionSupported("SGI_swap_control")) {
	     return __glXVForwardSingleReqSwap( cl, pc );
	  }
	  else {
	     return Success;
	  }
	  break;

#if 0 /* glx 1.3 */
       case X_GLXvop_CreateGLXVideoSourceSGIX:
	  break;
       case X_GLXvop_DestroyGLXVideoSourceSGIX:
	  break;
       case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
	  break;
       case X_GLXvop_DestroyGLXPbufferSGIX:
	  break;
       case X_GLXvop_ChangeDrawableAttributesSGIX:
	  break;
#endif

       case X_GLXvop_JoinSwapGroupSGIX:
	  return __glXSwapJoinSwapGroupSGIX( cl, pc );
	  break;

       case X_GLXvop_BindSwapBarrierSGIX:
	  return __glXSwapBindSwapBarrierSGIX( cl, pc );
	  break;

       case X_GLXvop_CreateContextWithConfigSGIX:
	  return __glXSwapCreateContextWithConfigSGIX( cl, pc );
	  break;

       default:
	  /*
	   ** unsupported private request
	   */
	  cl->client->errorValue = req->vendorCode;
	  return __glXUnsupportedPrivateRequest;
    }

}

int __glXSwapVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
{
    xGLXVendorPrivateWithReplyReq *req;
    CARD32 vendorCode;

    __GLX_DECLARE_SWAP_VARIABLES;

    req = (xGLXVendorPrivateWithReplyReq *) pc;
    vendorCode = req->vendorCode;
    __GLX_SWAP_INT(&vendorCode);

    switch( vendorCode ) {

       case X_GLvop_GetConvolutionFilterEXT:
       case X_GLvop_GetSeparableFilterEXT:
       case X_GLvop_GetHistogramEXT:
       case X_GLvop_GetMinmaxEXT:
	  return( __glXNoSuchSingleOpcode(cl, pc) );
	  break;

       case X_GLvop_GetConvolutionParameterfvEXT:
       case X_GLvop_GetConvolutionParameterivEXT:
       case X_GLvop_GetHistogramParameterivEXT:
       case X_GLvop_GetMinmaxParameterfvEXT:
       case X_GLvop_GetMinmaxParameterivEXT:
       case X_GLvop_GenTexturesEXT:
	  return( __glXVForwardAllWithReplySwapiv(cl, pc) );
	  break;

       case X_GLvop_AreTexturesResidentEXT:
       case X_GLvop_IsTextureEXT:
	  return( __glXVForwardPipe0WithReplySwap(cl, pc) );
	  break;

#if 0 /* glx1.3 */
       case X_GLvop_GetDetailTexFuncSGIS:
       case X_GLvop_GetSharpenTexFuncSGIS:
       case X_GLvop_GetColorTableSGI:
       case X_GLvop_GetColorTableParameterfvSGI:
       case X_GLvop_GetColorTableParameterivSGI:
       case X_GLvop_GetTexFilterFuncSGIS:
       case X_GLvop_GetInstrumentsSGIX:
       case X_GLvop_InstrumentsBufferSGIX:
       case X_GLvop_PollInstrumentsSGIX:
       case X_GLvop_FlushRasterSGIX:
       case X_GLXvop_CreateGLXPbufferSGIX:
       case X_GLXvop_GetDrawableAttributesSGIX:
       case X_GLXvop_QueryHyperpipeNetworkSGIX:
       case X_GLXvop_QueryHyperpipeConfigSGIX:
       case X_GLXvop_HyperpipeConfigSGIX:
       case X_GLXvop_DestroyHyperpipeConfigSGIX:
#endif
       case X_GLXvop_QueryMaxSwapBarriersSGIX:
	  return( __glXSwapQueryMaxSwapBarriersSGIX(cl, pc) );
	  break;

       case X_GLXvop_GetFBConfigsSGIX:
	  return( __glXSwapGetFBConfigsSGIX(cl, pc) );
	  break;

       case X_GLXvop_MakeCurrentReadSGI:
	  return( __glXSwapMakeCurrentReadSGI(cl, pc) );
	  break;

       case X_GLXvop_QueryContextInfoEXT:
	  return( __glXSwapQueryContextInfoEXT(cl,(char *)pc) );
	  break;

       default:
	  /*
	   ** unsupported private request
	   */
	  cl->client->errorValue = req->vendorCode;
	  return __glXUnsupportedPrivateRequest;
    }

}

int __glXSwapGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
{
    xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->screen);

    return __glXGetFBConfigs(cl, pc);
}

int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
{
   xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
   xGLXGetFBConfigsReq new_req;

   new_req.reqType = req->reqType;
   new_req.glxCode = req->glxCode;
   new_req.length = req->length;
   new_req.screen = req->screen;

   return( __glXSwapGetFBConfigs( cl, (GLbyte *)&new_req ) );
}

int __glXSwapCreateWindow(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __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);

    return( __glXCreateWindow( cl, (GLbyte *)pc ) );
}

int __glXSwapDestroyWindow(__GLXclientState *cl, GLbyte *pc)
{
    xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->glxwindow);

    return( __glXDestroyWindow( cl, (GLbyte *)pc ) );
}

int __glXSwapQueryContext(__GLXclientState *cl, GLbyte *pc)
{
    xGLXQueryContextReq *req = (xGLXQueryContextReq *)pc;

    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->context);

    return( __glXQueryContext(cl, (GLbyte *)pc) );
 
}

int __glXSwapCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
{
    xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
    int nattr = req->numAttribs;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->screen);
    __GLX_SWAP_INT(&req->fbconfig);
    __GLX_SWAP_INT(&req->pbuffer);
    __GLX_SWAP_INT(&req->numAttribs);
    __GLX_SWAP_INT_ARRAY( (int *)(req+1), nattr*2 );

    return( __glXCreatePbuffer( cl, pc ) );
}

int __glXSwapDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
{
    xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->pbuffer);

    return( __glXDestroyPbuffer( cl, (GLbyte *)pc ) );
}

int __glXSwapGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
   xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->drawable);

    return( __glXGetDrawableAttributes(cl, pc) );
}

int __glXSwapChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
{
   xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
    __GLX_DECLARE_SWAP_VARIABLES;

    __GLX_SWAP_SHORT(&req->length);
    __GLX_SWAP_INT(&req->drawable);
    __GLX_SWAP_INT(&req->numAttribs);
    __GLX_SWAP_INT_ARRAY( (int *)(req+1), req->numAttribs * 2 );

    return( __glXChangeDrawableAttributes(cl, pc) );
}
