/*
 * 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.
 */

#include <stdio.h>
#include <assert.h>
#include "glxclient.h"
#include "packsingle.h"
#include "glxextensions.h"
#include "indirect.h"
#include "indirect_vertex_array.h"

/* Used for GL_ARB_transpose_matrix */
static void TransposeMatrixf(GLfloat m[16])
{
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < i; j++) {
            GLfloat tmp = m[i*4+j];
            m[i*4+j] = m[j*4+i];
            m[j*4+i] = tmp;
        }
    }
}

/* Used for GL_ARB_transpose_matrix */
static void TransposeMatrixb(GLboolean m[16])
{
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < i; j++) {
            GLboolean tmp = m[i*4+j];
            m[i*4+j] = m[j*4+i];
            m[j*4+i] = tmp;
        }
    }
}

/* Used for GL_ARB_transpose_matrix */
static void TransposeMatrixd(GLdouble m[16])
{
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < i; j++) {
            GLdouble tmp = m[i*4+j];
            m[i*4+j] = m[j*4+i];
            m[j*4+i] = tmp;
        }
    }
}

/* Used for GL_ARB_transpose_matrix */
static void TransposeMatrixi(GLint m[16])
{
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 0; j < i; j++) {
            GLint tmp = m[i*4+j];
            m[i*4+j] = m[j*4+i];
            m[j*4+i] = tmp;
        }
    }
}


/**
 * Remap a transpose-matrix enum to a non-transpose-matrix enum.  Enums
 * that are not transpose-matrix enums are unaffected.
 */
static GLenum
RemapTransposeEnum( GLenum e )
{
    switch( e ) {
    case GL_TRANSPOSE_MODELVIEW_MATRIX:
    case GL_TRANSPOSE_PROJECTION_MATRIX:
    case GL_TRANSPOSE_TEXTURE_MATRIX:
	return e - (GL_TRANSPOSE_MODELVIEW_MATRIX - GL_MODELVIEW_MATRIX);
    case GL_TRANSPOSE_COLOR_MATRIX:
	return GL_COLOR_MATRIX;
    default:
	return e;
    };
}


GLenum __indirect_glGetError(void)
{
    __GLX_SINGLE_DECLARE_VARIABLES();
    GLuint retval = GL_NO_ERROR;
    xGLXGetErrorReply reply;

    if (gc->error) {
	/* Use internal error first */
	retval = gc->error;
	gc->error = GL_NO_ERROR;
	return retval;
    }

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_GetError,0);
    __GLX_SINGLE_READ_XREPLY();
    retval = reply.error;
    __GLX_SINGLE_END();

    return retval;
}


/**
 * Get the selected attribute from the client state.
 * 
 * \returns
 * On success \c GL_TRUE is returned.  Otherwise, \c GL_FALSE is returned.
 */
static GLboolean
get_client_data( __GLXcontext * gc, GLenum cap, GLintptr * data )
{
    GLboolean retval = GL_TRUE;
    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
    const GLint tex_unit = __glXGetActiveTextureUnit( state );


    switch( cap ) {
    case GL_VERTEX_ARRAY:
    case GL_NORMAL_ARRAY:
    case GL_COLOR_ARRAY:
    case GL_INDEX_ARRAY:
    case GL_EDGE_FLAG_ARRAY:
    case GL_SECONDARY_COLOR_ARRAY:
    case GL_FOG_COORD_ARRAY:
	retval = __glXGetArrayEnable( state, cap, 0, data );
	break;

    case GL_VERTEX_ARRAY_SIZE:
	retval = __glXGetArraySize( state, GL_VERTEX_ARRAY, 0, data );
	break;
    case GL_COLOR_ARRAY_SIZE:
	retval = __glXGetArraySize( state, GL_COLOR_ARRAY, 0, data );
	break;
    case GL_SECONDARY_COLOR_ARRAY_SIZE:
	retval = __glXGetArraySize( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
	break;

    case GL_VERTEX_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_VERTEX_ARRAY, 0, data );
	break;
    case GL_NORMAL_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_NORMAL_ARRAY, 0, data );
	break;
    case GL_INDEX_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_INDEX_ARRAY, 0, data );
	break;
    case GL_COLOR_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_COLOR_ARRAY, 0, data );
	break;
    case GL_SECONDARY_COLOR_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
	break;
    case GL_FOG_COORD_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_FOG_COORD_ARRAY, 0, data );
	break;

    case GL_VERTEX_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_VERTEX_ARRAY, 0, data );
	break;
    case GL_NORMAL_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_NORMAL_ARRAY, 0, data );
	break;
    case GL_INDEX_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_INDEX_ARRAY, 0, data );
	break;
    case GL_EDGE_FLAG_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_EDGE_FLAG_ARRAY, 0, data );
	break;
    case GL_COLOR_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_COLOR_ARRAY, 0, data );
	break;
    case GL_SECONDARY_COLOR_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_SECONDARY_COLOR_ARRAY, 0, data );
	break;
    case GL_FOG_COORD_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_FOG_COORD_ARRAY, 0, data );
	break;

    case GL_TEXTURE_COORD_ARRAY:
	retval = __glXGetArrayEnable( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
	break;
    case GL_TEXTURE_COORD_ARRAY_SIZE:
	retval = __glXGetArraySize( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
	break;
    case GL_TEXTURE_COORD_ARRAY_TYPE:
	retval = __glXGetArrayType( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
	break;
    case GL_TEXTURE_COORD_ARRAY_STRIDE:
	retval = __glXGetArrayStride( state, GL_TEXTURE_COORD_ARRAY, tex_unit, data );
	break;

    case GL_MAX_ELEMENTS_VERTICES:
    case GL_MAX_ELEMENTS_INDICES:
	retval = GL_TRUE;
	*data = ~0UL;
	break;

    
    case GL_PACK_ROW_LENGTH:
	*data = (GLintptr)state->storePack.rowLength;
	break;
    case GL_PACK_IMAGE_HEIGHT:
	*data = (GLintptr)state->storePack.imageHeight;
	break;
    case GL_PACK_SKIP_ROWS:
	*data = (GLintptr)state->storePack.skipRows;
	break;
    case GL_PACK_SKIP_PIXELS:
	*data = (GLintptr)state->storePack.skipPixels;
	break;
    case GL_PACK_SKIP_IMAGES:
	*data = (GLintptr)state->storePack.skipImages;
	break;
    case GL_PACK_ALIGNMENT:
	*data = (GLintptr)state->storePack.alignment;
	break;
    case GL_PACK_SWAP_BYTES:
	*data = (GLintptr)state->storePack.swapEndian;
	break;
    case GL_PACK_LSB_FIRST:
	*data = (GLintptr)state->storePack.lsbFirst;
	break;
    case GL_UNPACK_ROW_LENGTH:
	*data = (GLintptr)state->storeUnpack.rowLength;
	break;
    case GL_UNPACK_IMAGE_HEIGHT:
	*data = (GLintptr)state->storeUnpack.imageHeight;
	break;
    case GL_UNPACK_SKIP_ROWS:
	*data = (GLintptr)state->storeUnpack.skipRows;
	break;
    case GL_UNPACK_SKIP_PIXELS:
	*data = (GLintptr)state->storeUnpack.skipPixels;
	break;
    case GL_UNPACK_SKIP_IMAGES:
	*data = (GLintptr)state->storeUnpack.skipImages;
	break;
    case GL_UNPACK_ALIGNMENT:
	*data = (GLintptr)state->storeUnpack.alignment;
	break;
    case GL_UNPACK_SWAP_BYTES:
	*data = (GLintptr)state->storeUnpack.swapEndian;
	break;
    case GL_UNPACK_LSB_FIRST:
	*data = (GLintptr)state->storeUnpack.lsbFirst;
	break;
    case GL_CLIENT_ATTRIB_STACK_DEPTH:
        *data = (GLintptr)(gc->attributes.stackPointer - gc->attributes.stack);
	break;
    case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
	*data = (GLintptr)__GL_CLIENT_ATTRIB_STACK_DEPTH;
	break;
    case GL_CLIENT_ACTIVE_TEXTURE:
	*data = (GLintptr)(tex_unit + GL_TEXTURE0);
	break;

    default:
	retval = GL_FALSE;
	break;
    }


    return retval;
}


void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
{
    const GLenum origVal = val;
    __GLX_SINGLE_DECLARE_VARIABLES();
    xGLXSingleReply reply;

    val = RemapTransposeEnum( val );

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_GetBooleanv,4);
    __GLX_SINGLE_PUT_LONG(0,val);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_SIZE(compsize);

    if (compsize == 0) {
	/*
	** Error occured; don't modify user's buffer.
	*/
    } else {
	GLintptr data;

	/*
	** We still needed to send the request to the server in order to
	** find out whether it was legal to make a query (it's illegal,
	** for example, to call a query between glBegin() and glEnd()).
	*/

	if ( get_client_data( gc, val, & data ) ) {
	    *b = (GLboolean) data;
	}
	else {
	    /*
	     ** Not a local value, so use what we got from the server.
	     */
	    if (compsize == 1) {
		__GLX_SINGLE_GET_CHAR(b);
	    } else {
		__GLX_SINGLE_GET_CHAR_ARRAY(b,compsize);
		if (val != origVal) {
		    /* matrix transpose */
		    TransposeMatrixb(b);
                }
	    }
	}
    }
    __GLX_SINGLE_END();
}

void __indirect_glGetDoublev(GLenum val, GLdouble *d)
{
    const GLenum origVal = val;
    __GLX_SINGLE_DECLARE_VARIABLES();
    xGLXSingleReply reply;

    val = RemapTransposeEnum( val );

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_GetDoublev,4);
    __GLX_SINGLE_PUT_LONG(0,val);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_SIZE(compsize);

    if (compsize == 0) {
	/*
	** Error occured; don't modify user's buffer.
	*/
    } else {
	GLintptr data;

	/*
	** We still needed to send the request to the server in order to
	** find out whether it was legal to make a query (it's illegal,
	** for example, to call a query between glBegin() and glEnd()).
	*/

	if ( get_client_data( gc, val, & data ) ) {
	    *d = (GLdouble) data;
	}
	else {
	    /*
	     ** Not a local value, so use what we got from the server.
	     */
	    if (compsize == 1) {
		__GLX_SINGLE_GET_DOUBLE(d);
	    } else {
		__GLX_SINGLE_GET_DOUBLE_ARRAY(d,compsize);
		if (val != origVal) {
		    /* matrix transpose */
		    TransposeMatrixd(d);
		}
	    }
	}
    }
    __GLX_SINGLE_END();
}

void __indirect_glGetFloatv(GLenum val, GLfloat *f)
{
    const GLenum origVal = val;
    __GLX_SINGLE_DECLARE_VARIABLES();
    xGLXSingleReply reply;

    val = RemapTransposeEnum( val );

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_GetFloatv,4);
    __GLX_SINGLE_PUT_LONG(0,val);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_SIZE(compsize);

    if (compsize == 0) {
	/*
	** Error occured; don't modify user's buffer.
	*/
    } else {
	GLintptr data;

	/*
	** We still needed to send the request to the server in order to
	** find out whether it was legal to make a query (it's illegal,
	** for example, to call a query between glBegin() and glEnd()).
	*/

	if ( get_client_data( gc, val, & data ) ) {
	    *f = (GLfloat) data;
	}
	else {
	    /*
	     ** Not a local value, so use what we got from the server.
	     */
	    if (compsize == 1) {
		__GLX_SINGLE_GET_FLOAT(f);
	    } else {
		__GLX_SINGLE_GET_FLOAT_ARRAY(f,compsize);
		if (val != origVal) {
		    /* matrix transpose */
		    TransposeMatrixf(f);
                }
	    }
	}
    }
    __GLX_SINGLE_END();
}

void __indirect_glGetIntegerv(GLenum val, GLint *i)
{
    const GLenum origVal = val;
    __GLX_SINGLE_DECLARE_VARIABLES();
    xGLXSingleReply reply;

    val = RemapTransposeEnum( val );

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_GetIntegerv,4);
    __GLX_SINGLE_PUT_LONG(0,val);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_SIZE(compsize);

    if (compsize == 0) {
	/*
	** Error occured; don't modify user's buffer.
	*/
    } else {
	GLintptr data;

	/*
	** We still needed to send the request to the server in order to
	** find out whether it was legal to make a query (it's illegal,
	** for example, to call a query between glBegin() and glEnd()).
	*/

	if ( get_client_data( gc, val, & data ) ) {
	    *i = (GLint) data;
	}
	else {
	    /*
	     ** Not a local value, so use what we got from the server.
	     */
	    if (compsize == 1) {
		__GLX_SINGLE_GET_LONG(i);
	    } else {
		__GLX_SINGLE_GET_LONG_ARRAY(i,compsize);
		if (val != origVal) {
		    /* matrix transpose */
		    TransposeMatrixi(i);
                }
	    }
	}
    }
    __GLX_SINGLE_END();
}

/*
** Send all pending commands to server.
*/
void __indirect_glFlush(void)
{
    __GLX_SINGLE_DECLARE_VARIABLES();

    if (!dpy) return;

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_Flush,0);
    __GLX_SINGLE_END();

    /* And finally flush the X protocol data */
    XFlush(dpy);
}

void __indirect_glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
{
    __GLX_SINGLE_DECLARE_VARIABLES();

    if (!dpy) return;

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_FeedbackBuffer,8);
    __GLX_SINGLE_PUT_LONG(0,size);
    __GLX_SINGLE_PUT_LONG(4,type);
    __GLX_SINGLE_END();

    gc->feedbackBuf = buffer;
}

void __indirect_glSelectBuffer(GLsizei numnames, GLuint *buffer)
{
    __GLX_SINGLE_DECLARE_VARIABLES();

    if (!dpy) return;

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_SelectBuffer,4);
    __GLX_SINGLE_PUT_LONG(0,numnames);
    __GLX_SINGLE_END();

    gc->selectBuf = buffer;
}

GLint __indirect_glRenderMode(GLenum mode)
{
    __GLX_SINGLE_DECLARE_VARIABLES();
    GLint retval = 0;
    xGLXRenderModeReply reply;

    if (!dpy) return -1;

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_RenderMode,4);
    __GLX_SINGLE_PUT_LONG(0,mode);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_RETVAL(retval,GLint);

    if (reply.newMode != mode) {
	/*
	** Switch to new mode did not take effect, therefore an error
	** occured.  When an error happens the server won't send us any
	** other data.
	*/
    } else {
	/* Read the feedback or selection data */
	if (gc->renderMode == GL_FEEDBACK) {
	    __GLX_SINGLE_GET_SIZE(compsize);
	    __GLX_SINGLE_GET_FLOAT_ARRAY(gc->feedbackBuf, compsize);
	} else
	if (gc->renderMode == GL_SELECT) {
	    __GLX_SINGLE_GET_SIZE(compsize);
	    __GLX_SINGLE_GET_LONG_ARRAY(gc->selectBuf, compsize);
	}
	gc->renderMode = mode;
    }
    __GLX_SINGLE_END();

    return retval;
}

void __indirect_glFinish(void)
{
    __GLX_SINGLE_DECLARE_VARIABLES();
    xGLXSingleReply reply;

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_Finish,0);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_END();
}


/**
 * Extract the major and minor version numbers from a version string.
 */
static void
version_from_string( const char * ver, 
		     int * major_version, int * minor_version )
{
    const char * end;
    long major;
    long minor;

    major = strtol( ver, (char **) & end, 10 );
    minor = strtol( end + 1, NULL, 10 );
    *major_version = major;
    *minor_version = minor;
}


const GLubyte *__indirect_glGetString(GLenum name)
{
    __GLXcontext *gc = __glXGetCurrentContext();
    Display *dpy = gc->currentDpy;
    GLubyte *s = NULL;

    if (!dpy) return 0;

    /*
    ** Return the cached copy if the string has already been fetched
    */
    switch(name) {
      case GL_VENDOR:
	if (gc->vendor) return gc->vendor;
	break;
      case GL_RENDERER:
	if (gc->renderer) return gc->renderer;
	break;
      case GL_VERSION:
	if (gc->version) return gc->version;
	break;
      case GL_EXTENSIONS:
	if (gc->extensions) return gc->extensions;
	break;
      default:
	__glXSetError(gc, GL_INVALID_ENUM);
	return 0;
    }

    /*
    ** Get requested string from server
    */

    (void) __glXFlushRenderBuffer( gc, gc->pc );
    s = (GLubyte *) __glXGetStringFromServer( dpy, gc->majorOpcode,
				  X_GLsop_GetString, gc->currentContextTag,
				  name );
    if (!s) {
	/* Throw data on the floor */
	__glXSetError(gc, GL_OUT_OF_MEMORY);
    } else {
	/*
	** Update local cache
	*/
	switch(name) {
	case GL_VENDOR:
	    gc->vendor = s;
	    break;

	case GL_RENDERER:
	    gc->renderer = s;
	    break;

	case GL_VERSION: {
	    int client_major;
	    int client_minor;

	    version_from_string( (char *) s, 
				 & gc->server_major, & gc->server_minor );
	    __glXGetGLVersion( & client_major, & client_minor );

	    if ( (gc->server_major < client_major)
		 || ((gc->server_major == client_major) 
		     && (gc->server_minor <= client_minor)) ) {
		gc->version = s;
	    }
	    else {
		/* Allow 7 bytes for the client-side GL version.  This allows
		 * for upto version 999.999.  I'm not holding my breath for
		 * that one!  The extra 4 is for the ' ()\0' that will be
		 * added.
		 */
		const size_t size = 7 + strlen( (char *) s ) + 4;

		gc->version = Xmalloc( size );
		if ( gc->version == NULL ) {
		    /* If we couldn't allocate memory for the new string,
		     * make a best-effort and just copy the client-side version
		     * to the string and use that.  It probably doesn't
		     * matter what is done here.  If there not memory available
		     * for a short string, the system is probably going to die
		     * soon anyway.
		     */
		    snprintf( (char *) s, strlen( (char *) s ) + 1, "%u.%u",
			      client_major, client_minor );
		    gc->version = s;
		}
		else {
		    snprintf( (char *)gc->version, size, "%u.%u (%s)",
			      client_major, client_minor, s );
		    Xfree( s );
		    s = gc->version;
		}
	    }
	    break;
	}

	case GL_EXTENSIONS: {
	    int major = 1;
	    int minor = 0;

	    /* This code is currently disabled.  I was reminded that some
	     * vendors intentionally exclude some extensions from their
	     * extension string that are part of the core version they
	     * advertise.  In particular, on Nvidia drivers this means that
	     * the functionality is supported by the driver, but is not
	     * hardware accelerated.  For example, a TNT will show core
	     * version 1.5, but most of the post-1.2 functionality is a
	     * software fallback.
	     * 
	     * I don't want to break applications that rely on this odd
	     * behavior.  At the same time, the code is written and tested,
	     * so I didn't want to throw it away.  Therefore, the code is here
	     * but disabled.  In the future, we may wish to and an environment
	     * variable to enable it.
	     */
	    
#if 0
	    /* Call glGetString just to make sure that gc->server_major and
	     * gc->server_minor are set.  This version may be higher than we
	     * can completely support, but it may imply support for some
	     * extensions that we can support.
	     * 
	     * For example, at the time of this writing, the client-side
	     * library only supports upto core GL version 1.2.  However, cubic
	     * textures, multitexture, multisampling, and some other 1.3
	     * features are supported.  If the server reports back version
	     * 1.3, but does not report all of those extensions, we will
	     * enable them.
	     */
	    (void *) glGetString( GL_VERSION );
	    major = gc->server_major,
	    minor = gc->server_minor;
#endif

	    __glXCalculateUsableGLExtensions( gc, (char *) s, major, minor );
	    XFree( s );
	    s = gc->extensions;
	    break;
	}
	}
    }
    return s;
}

GLboolean __indirect_glIsEnabled(GLenum cap)
{
    __GLX_SINGLE_DECLARE_VARIABLES();
    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
    xGLXSingleReply reply;
    GLboolean retval = 0;
    GLintptr enable;

    if (!dpy) return 0;

    switch(cap) {
    case GL_VERTEX_ARRAY:
    case GL_NORMAL_ARRAY:
    case GL_COLOR_ARRAY:
    case GL_INDEX_ARRAY:
    case GL_EDGE_FLAG_ARRAY:
    case GL_SECONDARY_COLOR_ARRAY:
    case GL_FOG_COORD_ARRAY:
	retval = __glXGetArrayEnable( state, cap, 0, & enable );
	assert( retval );
	return (GLboolean) enable;
	break;
    case GL_TEXTURE_COORD_ARRAY:
	retval = __glXGetArrayEnable( state, GL_TEXTURE_COORD_ARRAY,
				      __glXGetActiveTextureUnit( state ), & enable );
	assert( retval );
	return (GLboolean) enable;
	break;
    }

    __GLX_SINGLE_LOAD_VARIABLES();
    __GLX_SINGLE_BEGIN(X_GLsop_IsEnabled,4);
    __GLX_SINGLE_PUT_LONG(0,cap);
    __GLX_SINGLE_READ_XREPLY();
    __GLX_SINGLE_GET_RETVAL(retval, GLboolean);
    __GLX_SINGLE_END();
    return retval;
}

void __indirect_glGetPointerv(GLenum pname, void **params)
{
    __GLXcontext *gc = __glXGetCurrentContext();
    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
    Display *dpy = gc->currentDpy;

    if (!dpy) return;

    switch(pname) {
    case GL_VERTEX_ARRAY_POINTER:
    case GL_NORMAL_ARRAY_POINTER:
    case GL_COLOR_ARRAY_POINTER:
    case GL_INDEX_ARRAY_POINTER:
    case GL_EDGE_FLAG_ARRAY_POINTER:
	__glXGetArrayPointer( state, pname - GL_VERTEX_ARRAY_POINTER 
			      + GL_VERTEX_ARRAY,
			      0, params );
	return;
    case GL_TEXTURE_COORD_ARRAY_POINTER:
	__glXGetArrayPointer( state, GL_TEXTURE_COORD_ARRAY, 
			      __glXGetActiveTextureUnit( state ), params );
	return;
    case GL_SECONDARY_COLOR_ARRAY_POINTER:
    case GL_FOG_COORD_ARRAY_POINTER:
	__glXGetArrayPointer( state, pname - GL_FOG_COORD_ARRAY_POINTER
			      + GL_FOG_COORD_ARRAY, 
			      0, params );
	return;
    case GL_FEEDBACK_BUFFER_POINTER:
	*params = (void *)gc->feedbackBuf;
	return;
    case GL_SELECTION_BUFFER_POINTER:
	*params = (void *)gc->selectBuf;
	return;
    default:
	__glXSetError(gc, GL_INVALID_ENUM);
	return;
    }
}

