/*
 * 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"
#include "glapi.h"
#ifdef USE_XCB
#include <xcb/xcb.h>
#include <xcb/glx.h>
#include <X11/Xlib-xcb.h>
#endif /* USE_XCB */

#if !defined(__GNUC__)
#  define __builtin_expect(x, y) x
#endif

/* 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(struct glx_context * 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)
{
   struct glx_context *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 *) __glXGetString(dpy, gc->majorOpcode, 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)
{
   struct glx_context *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;
   }
}



/**
 * This was previously auto-generated, but we need to special-case
 * how we handle writing into the 'residences' buffer when n%4!=0.
 */
#define X_GLsop_AreTexturesResident 143
GLboolean
__indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
                                 GLboolean * residences)
{
   struct glx_context *const gc = __glXGetCurrentContext();
   Display *const dpy = gc->currentDpy;
   GLboolean retval = (GLboolean) 0;
   if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
      xcb_connection_t *c = XGetXCBConnection(dpy);
      (void) __glXFlushRenderBuffer(gc, gc->pc);
      xcb_glx_are_textures_resident_reply_t *reply =
         xcb_glx_are_textures_resident_reply(c,
                                             xcb_glx_are_textures_resident
                                             (c, gc->currentContextTag, n,
                                              textures), NULL);
      (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
                    xcb_glx_are_textures_resident_data_length(reply) *
                    sizeof(GLboolean));
      retval = reply->ret_val;
      free(reply);
#else
      const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
      GLubyte const *pc =
         __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen);
      (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
      (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
      if (n & 3) {
         /* n is not a multiple of four.
          * When reply_is_always_array is TRUE, __glXReadReply() will
          * put a multiple of four bytes into the dest buffer.  If the
          * caller's buffer is not a multiple of four in size, we'll write
          * out of bounds.  So use a temporary buffer that's a few bytes
          * larger.
          */
         GLboolean *res4 = malloc((n + 3) & ~3);
         retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
         memcpy(residences, res4, n);
         free(res4);
      }
      else {
         retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
      }
      UnlockDisplay(dpy);
      SyncHandle();
#endif /* USE_XCB */
   }
   return retval;
}


/**
 * This was previously auto-generated, but we need to special-case
 * how we handle writing into the 'residences' buffer when n%4!=0.
 */
#define X_GLvop_AreTexturesResidentEXT 11
GLboolean
glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
                         GLboolean * residences)
{
   struct glx_context *const gc = __glXGetCurrentContext();

   if (gc->isDirect) {
      const _glapi_proc *const table = (_glapi_proc *) GET_DISPATCH();
      PFNGLARETEXTURESRESIDENTEXTPROC p =
         (PFNGLARETEXTURESRESIDENTEXTPROC) table[332];

      return p(n, textures, residences);
   }
   else {
      struct glx_context *const gc = __glXGetCurrentContext();
      Display *const dpy = gc->currentDpy;
      GLboolean retval = (GLboolean) 0;
      const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
      if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
            __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
                                    X_GLvop_AreTexturesResidentEXT,
                                    cmdlen);
         (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
         (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
         if (n & 3) {
            /* see comments in __indirect_glAreTexturesResident() */
            GLboolean *res4 = malloc((n + 3) & ~3);
            retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
            memcpy(residences, res4, n);
            free(res4);
         }
         else {
            retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
         }
         UnlockDisplay(dpy);
         SyncHandle();
      }
      return retval;
   }
}
