diff options
author | Adam Jackson <[email protected]> | 2004-10-25 21:09:16 +0000 |
---|---|---|
committer | Adam Jackson <[email protected]> | 2004-10-25 21:09:16 +0000 |
commit | cb3610e37c4c0a40520441b8515d044dabcc8854 (patch) | |
tree | 4c3a60c9381bc03c4ad58f9170e99d8237b1d81d /src/glx/x11/single2.c | |
parent | bcd8735546f3842f917f2cdc4ff530e4215f01a1 (diff) |
Import the GLX client side library, formerly from xc/lib/GL/glx. Build it
by adding 'glx/x11' to SRC_DIRS in your build config.
Diffstat (limited to 'src/glx/x11/single2.c')
-rw-r--r-- | src/glx/x11/single2.c | 1097 |
1 files changed, 1097 insertions, 0 deletions
diff --git a/src/glx/x11/single2.c b/src/glx/x11/single2.c new file mode 100644 index 00000000000..693c28df8fe --- /dev/null +++ b/src/glx/x11/single2.c @@ -0,0 +1,1097 @@ +/* $XFree86: xc/lib/GL/glx/single2.c,v 1.10 2004/02/11 19:48:16 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_GL_FUNCS_WRAPPED +#include <stdio.h> +#include "glxclient.h" +#include "packsingle.h" +#include "glxextensions.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; + } + } +} + +GLenum 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; +} + +void glGetClipPlane(GLenum plane, GLdouble *equation) +{ + __GLX_SINGLE_DECLARE_VARIABLES(); + xGLXSingleReply reply; + __GLX_SINGLE_LOAD_VARIABLES(); + __GLX_SINGLE_BEGIN(X_GLsop_GetClipPlane,4); + __GLX_SINGLE_PUT_LONG(0,plane); + __GLX_SINGLE_READ_XREPLY(); + if (reply.length == 8) { + __GLX_SINGLE_GET_DOUBLE_ARRAY(equation,4); + } + __GLX_SINGLE_END(); +} + +#define CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type) \ + case GL_ ## enum_name ## _ARRAY: \ + *dest = (gl_type) (IS_ARRAY_ENABLED(state, array)); break +#define CASE_ARRAY_SIZE(enum_name,array,dest,gl_type) \ + case GL_ ## enum_name ## _ARRAY_SIZE: \ + *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].size ; break +#define CASE_ARRAY_TYPE(enum_name,array,dest,gl_type) \ + case GL_ ## enum_name ## _ARRAY_TYPE: \ + *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].type ; break +#define CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type) \ + case GL_ ## enum_name ## _ARRAY_STRIDE: \ + *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].stride ; break + +#define CASE_ARRAY_ALL(enum_name,array,dest,gl_type) \ + CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type); \ + CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type); \ + CASE_ARRAY_TYPE(enum_name,array,dest,gl_type); \ + CASE_ARRAY_SIZE(enum_name,array,dest,gl_type) + +void glGetBooleanv(GLenum val, GLboolean *b) +{ + const GLenum origVal = val; + __GLX_SINGLE_DECLARE_VARIABLES(); + __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); + xGLXSingleReply reply; + + if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) { + val = GL_MODELVIEW_MATRIX; + } + else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) { + val = GL_PROJECTION_MATRIX; + } + else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) { + val = GL_TEXTURE_MATRIX; + } + else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) { + val = GL_COLOR_MATRIX; + } + + __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 { + /* + ** For all the queries listed here, we use the locally stored + ** values rather than the one returned by the server. Note that + ** 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()). + */ + switch (val) { + case GL_PACK_ROW_LENGTH: + *b = (GLboolean)state->storePack.rowLength; + break; + case GL_PACK_IMAGE_HEIGHT: + *b = (GLboolean)state->storePack.imageHeight; + break; + case GL_PACK_SKIP_ROWS: + *b = (GLboolean)state->storePack.skipRows; + break; + case GL_PACK_SKIP_PIXELS: + *b = (GLboolean)state->storePack.skipPixels; + break; + case GL_PACK_SKIP_IMAGES: + *b = (GLboolean)state->storePack.skipImages; + break; + case GL_PACK_ALIGNMENT: + *b = (GLboolean)state->storePack.alignment; + break; + case GL_PACK_SWAP_BYTES: + *b = (GLboolean)state->storePack.swapEndian; + break; + case GL_PACK_LSB_FIRST: + *b = (GLboolean)state->storePack.lsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *b = (GLboolean)state->storeUnpack.rowLength; + break; + case GL_UNPACK_IMAGE_HEIGHT: + *b = (GLboolean)state->storeUnpack.imageHeight; + break; + case GL_UNPACK_SKIP_ROWS: + *b = (GLboolean)state->storeUnpack.skipRows; + break; + case GL_UNPACK_SKIP_PIXELS: + *b = (GLboolean)state->storeUnpack.skipPixels; + break; + case GL_UNPACK_SKIP_IMAGES: + *b = (GLboolean)state->storeUnpack.skipImages; + break; + case GL_UNPACK_ALIGNMENT: + *b = (GLboolean)state->storeUnpack.alignment; + break; + case GL_UNPACK_SWAP_BYTES: + *b = (GLboolean)state->storeUnpack.swapEndian; + break; + case GL_UNPACK_LSB_FIRST: + *b = (GLboolean)state->storeUnpack.lsbFirst; + break; + + CASE_ARRAY_ALL(VERTEX, vertex, b, GLboolean); + + CASE_ARRAY_ENABLE(NORMAL, normal, b, GLboolean); + CASE_ARRAY_TYPE(NORMAL, normal, b, GLboolean); + CASE_ARRAY_STRIDE(NORMAL, normal, b, GLboolean); + + CASE_ARRAY_ALL(COLOR, color, b, GLboolean); + + CASE_ARRAY_ENABLE(INDEX, index, b, GLboolean); + CASE_ARRAY_TYPE(INDEX, index, b, GLboolean); + CASE_ARRAY_STRIDE(INDEX, index, b, GLboolean); + + case GL_TEXTURE_COORD_ARRAY: + *b = (GLboolean)IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture); + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].type; + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].stride; + break; + + CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, b, GLboolean); + CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, b, GLboolean); + + CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, b, GLboolean); + + CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, b, GLboolean); + CASE_ARRAY_TYPE(FOG_COORD, fogCoord, b, GLboolean); + CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, b, GLboolean); + + case GL_MAX_ELEMENTS_VERTICES: + *b = (GLboolean)state->vertArray.maxElementsVertices; + break; + case GL_MAX_ELEMENTS_INDICES: + *b = (GLboolean)state->vertArray.maxElementsIndices; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *b = (GLboolean)__GL_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *b = (GLboolean)(state->vertArray.activeTexture + GL_TEXTURE0_ARB); + break; + default: + /* + ** 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 glGetDoublev(GLenum val, GLdouble *d) +{ + const GLenum origVal = val; + __GLX_SINGLE_DECLARE_VARIABLES(); + __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); + xGLXSingleReply reply; + + if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) { + val = GL_MODELVIEW_MATRIX; + } + else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) { + val = GL_PROJECTION_MATRIX; + } + else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) { + val = GL_TEXTURE_MATRIX; + } + else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) { + val = GL_COLOR_MATRIX; + } + + __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 { + /* + ** For all the queries listed here, we use the locally stored + ** values rather than the one returned by the server. Note that + ** 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()). + */ + switch (val) { + case GL_PACK_ROW_LENGTH: + *d = (GLdouble)state->storePack.rowLength; + break; + case GL_PACK_IMAGE_HEIGHT: + *d = (GLdouble)state->storePack.imageHeight; + break; + case GL_PACK_SKIP_ROWS: + *d = (GLdouble)state->storePack.skipRows; + break; + case GL_PACK_SKIP_PIXELS: + *d = (GLdouble)state->storePack.skipPixels; + break; + case GL_PACK_SKIP_IMAGES: + *d = (GLdouble)state->storePack.skipImages; + break; + case GL_PACK_ALIGNMENT: + *d = (GLdouble)state->storePack.alignment; + break; + case GL_PACK_SWAP_BYTES: + *d = (GLdouble)state->storePack.swapEndian; + break; + case GL_PACK_LSB_FIRST: + *d = (GLdouble)state->storePack.lsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *d = (GLdouble)state->storeUnpack.rowLength; + break; + case GL_UNPACK_IMAGE_HEIGHT: + *d = (GLdouble)state->storeUnpack.imageHeight; + break; + case GL_UNPACK_SKIP_ROWS: + *d = (GLdouble)state->storeUnpack.skipRows; + break; + case GL_UNPACK_SKIP_PIXELS: + *d = (GLdouble)state->storeUnpack.skipPixels; + break; + case GL_UNPACK_SKIP_IMAGES: + *d = (GLdouble)state->storeUnpack.skipImages; + break; + case GL_UNPACK_ALIGNMENT: + *d = (GLdouble)state->storeUnpack.alignment; + break; + case GL_UNPACK_SWAP_BYTES: + *d = (GLdouble)state->storeUnpack.swapEndian; + break; + case GL_UNPACK_LSB_FIRST: + *d = (GLdouble)state->storeUnpack.lsbFirst; + break; + + CASE_ARRAY_ALL(VERTEX, vertex, d, GLdouble); + + CASE_ARRAY_ENABLE(NORMAL, normal, d, GLdouble); + CASE_ARRAY_TYPE(NORMAL, normal, d, GLdouble); + CASE_ARRAY_STRIDE(NORMAL, normal, d, GLdouble); + + CASE_ARRAY_ALL(COLOR, color, d, GLdouble); + + CASE_ARRAY_ENABLE(INDEX, index, d, GLdouble); + CASE_ARRAY_TYPE(INDEX, index, d, GLdouble); + CASE_ARRAY_STRIDE(INDEX, index, d, GLdouble); + + case GL_TEXTURE_COORD_ARRAY: + *d = (GLdouble) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture); + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].type; + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].stride; + break; + + CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, d, GLdouble); + CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, d, GLdouble); + + CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, d, GLdouble); + + CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, d, GLdouble); + CASE_ARRAY_TYPE(FOG_COORD, fogCoord, d, GLdouble); + CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, d, GLdouble); + + case GL_MAX_ELEMENTS_VERTICES: + *d = (GLdouble)state->vertArray.maxElementsVertices; + break; + case GL_MAX_ELEMENTS_INDICES: + *d = (GLdouble)state->vertArray.maxElementsIndices; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *d = (GLdouble)__GL_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *d = (GLdouble)(state->vertArray.activeTexture + GL_TEXTURE0_ARB); + break; + default: + /* + ** 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 glGetFloatv(GLenum val, GLfloat *f) +{ + const GLenum origVal = val; + __GLX_SINGLE_DECLARE_VARIABLES(); + __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); + xGLXSingleReply reply; + + if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) { + val = GL_MODELVIEW_MATRIX; + } + else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) { + val = GL_PROJECTION_MATRIX; + } + else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) { + val = GL_TEXTURE_MATRIX; + } + else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) { + val = GL_COLOR_MATRIX; + } + + __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 { + /* + ** For all the queries listed here, we use the locally stored + ** values rather than the one returned by the server. Note that + ** 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()). + */ + switch (val) { + case GL_PACK_ROW_LENGTH: + *f = (GLfloat)state->storePack.rowLength; + break; + case GL_PACK_IMAGE_HEIGHT: + *f = (GLfloat)state->storePack.imageHeight; + break; + case GL_PACK_SKIP_ROWS: + *f = (GLfloat)state->storePack.skipRows; + break; + case GL_PACK_SKIP_PIXELS: + *f = (GLfloat)state->storePack.skipPixels; + break; + case GL_PACK_SKIP_IMAGES: + *f = (GLfloat)state->storePack.skipImages; + break; + case GL_PACK_ALIGNMENT: + *f = (GLfloat)state->storePack.alignment; + break; + case GL_PACK_SWAP_BYTES: + *f = (GLfloat)state->storePack.swapEndian; + break; + case GL_PACK_LSB_FIRST: + *f = (GLfloat)state->storePack.lsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *f = (GLfloat)state->storeUnpack.rowLength; + break; + case GL_UNPACK_IMAGE_HEIGHT: + *f = (GLfloat)state->storeUnpack.imageHeight; + break; + case GL_UNPACK_SKIP_ROWS: + *f = (GLfloat)state->storeUnpack.skipRows; + break; + case GL_UNPACK_SKIP_PIXELS: + *f = (GLfloat)state->storeUnpack.skipPixels; + break; + case GL_UNPACK_SKIP_IMAGES: + *f = (GLfloat)state->storeUnpack.skipImages; + break; + case GL_UNPACK_ALIGNMENT: + *f = (GLfloat)state->storeUnpack.alignment; + break; + case GL_UNPACK_SWAP_BYTES: + *f = (GLfloat)state->storeUnpack.swapEndian; + break; + case GL_UNPACK_LSB_FIRST: + *f = (GLfloat)state->storeUnpack.lsbFirst; + break; + + CASE_ARRAY_ALL(VERTEX, vertex, f, GLfloat); + + CASE_ARRAY_ENABLE(NORMAL, normal, f, GLfloat); + CASE_ARRAY_TYPE(NORMAL, normal, f, GLfloat); + CASE_ARRAY_STRIDE(NORMAL, normal, f, GLfloat); + + CASE_ARRAY_ALL(COLOR, color, f, GLfloat); + + CASE_ARRAY_ENABLE(INDEX, index, f, GLfloat); + CASE_ARRAY_TYPE(INDEX, index, f, GLfloat); + CASE_ARRAY_STRIDE(INDEX, index, f, GLfloat); + + case GL_TEXTURE_COORD_ARRAY: + *f = (GLfloat) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture); + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].type; + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].stride; + break; + + CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, f, GLfloat); + CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, f, GLfloat); + + CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, f, GLfloat); + + CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, f, GLfloat); + CASE_ARRAY_TYPE(FOG_COORD, fogCoord, f, GLfloat); + CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, f, GLfloat); + + case GL_MAX_ELEMENTS_VERTICES: + *f = (GLfloat)state->vertArray.maxElementsVertices; + break; + case GL_MAX_ELEMENTS_INDICES: + *f = (GLfloat)state->vertArray.maxElementsIndices; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *f = (GLfloat)__GL_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *f = (GLfloat)(state->vertArray.activeTexture + GL_TEXTURE0_ARB); + break; + default: + /* + ** 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 glGetIntegerv(GLenum val, GLint *i) +{ + const GLenum origVal = val; + __GLX_SINGLE_DECLARE_VARIABLES(); + __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); + xGLXSingleReply reply; + + if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) { + val = GL_MODELVIEW_MATRIX; + } + else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) { + val = GL_PROJECTION_MATRIX; + } + else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) { + val = GL_TEXTURE_MATRIX; + } + else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) { + val = GL_COLOR_MATRIX; + } + + __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 { + /* + ** For all the queries listed here, we use the locally stored + ** values rather than the one returned by the server. Note that + ** 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()). + */ + switch (val) { + case GL_PACK_ROW_LENGTH: + *i = (GLint)state->storePack.rowLength; + break; + case GL_PACK_IMAGE_HEIGHT: + *i = (GLint)state->storePack.imageHeight; + break; + case GL_PACK_SKIP_ROWS: + *i = (GLint)state->storePack.skipRows; + break; + case GL_PACK_SKIP_PIXELS: + *i = (GLint)state->storePack.skipPixels; + break; + case GL_PACK_SKIP_IMAGES: + *i = (GLint)state->storePack.skipImages; + break; + case GL_PACK_ALIGNMENT: + *i = (GLint)state->storePack.alignment; + break; + case GL_PACK_SWAP_BYTES: + *i = (GLint)state->storePack.swapEndian; + break; + case GL_PACK_LSB_FIRST: + *i = (GLint)state->storePack.lsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *i = (GLint)state->storeUnpack.rowLength; + break; + case GL_UNPACK_IMAGE_HEIGHT: + *i = (GLint)state->storeUnpack.imageHeight; + break; + case GL_UNPACK_SKIP_ROWS: + *i = (GLint)state->storeUnpack.skipRows; + break; + case GL_UNPACK_SKIP_PIXELS: + *i = (GLint)state->storeUnpack.skipPixels; + break; + case GL_UNPACK_SKIP_IMAGES: + *i = (GLint)state->storeUnpack.skipImages; + break; + case GL_UNPACK_ALIGNMENT: + *i = (GLint)state->storeUnpack.alignment; + break; + case GL_UNPACK_SWAP_BYTES: + *i = (GLint)state->storeUnpack.swapEndian; + break; + case GL_UNPACK_LSB_FIRST: + *i = (GLint)state->storeUnpack.lsbFirst; + break; + + CASE_ARRAY_ALL(VERTEX, vertex, i, GLint); + + CASE_ARRAY_ENABLE(NORMAL, normal, i, GLint); + CASE_ARRAY_TYPE(NORMAL, normal, i, GLint); + CASE_ARRAY_STRIDE(NORMAL, normal, i, GLint); + + CASE_ARRAY_ALL(COLOR, color, i, GLint); + + CASE_ARRAY_ENABLE(INDEX, index, i, GLint); + CASE_ARRAY_TYPE(INDEX, index, i, GLint); + CASE_ARRAY_STRIDE(INDEX, index, i, GLint); + + case GL_TEXTURE_COORD_ARRAY: + *i = (GLint) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture); + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].type; + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].stride; + break; + + CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, i, GLint); + CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, i, GLint); + + CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, i, GLint); + + CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, i, GLint); + CASE_ARRAY_TYPE(FOG_COORD, fogCoord, i, GLint); + CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, i, GLint); + + case GL_MAX_ELEMENTS_VERTICES: + *i = (GLint)state->vertArray.maxElementsVertices; + break; + case GL_MAX_ELEMENTS_INDICES: + *i = (GLint)state->vertArray.maxElementsIndices; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *i = (GLint)__GL_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *i = (GLint)(state->vertArray.activeTexture + GL_TEXTURE0_ARB); + break; + default: + /* + ** 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 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 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 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 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 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 *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 glIsEnabled(GLenum cap) +{ + __GLX_SINGLE_DECLARE_VARIABLES(); + __GLXattribute * state = (__GLXattribute *)(gc->client_state_private); + xGLXSingleReply reply; + GLboolean retval = 0; + + if (!dpy) return 0; + + switch(cap) { + case GL_VERTEX_ARRAY: + return IS_ARRAY_ENABLED(state, vertex); + case GL_NORMAL_ARRAY: + return IS_ARRAY_ENABLED(state, normal); + case GL_COLOR_ARRAY: + return IS_ARRAY_ENABLED(state, color); + case GL_INDEX_ARRAY: + return IS_ARRAY_ENABLED(state, index); + case GL_TEXTURE_COORD_ARRAY: + return IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture); + case GL_EDGE_FLAG_ARRAY: + return IS_ARRAY_ENABLED(state, edgeFlag); + case GL_SECONDARY_COLOR_ARRAY: + return IS_ARRAY_ENABLED(state, secondaryColor); + case GL_FOG_COORD_ARRAY: + return IS_ARRAY_ENABLED(state, fogCoord); + } + + __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 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: + *params = (void *)state->vertArray.arrays[ vertex_ARRAY ].ptr; + return; + case GL_NORMAL_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ normal_ARRAY ].ptr; + return; + case GL_COLOR_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ color_ARRAY ].ptr; + return; + case GL_INDEX_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ index_ARRAY ].ptr; + return; + case GL_TEXTURE_COORD_ARRAY_POINTER: + *params = (void *)state->vertArray.texCoord[state->vertArray.activeTexture].ptr; + return; + case GL_EDGE_FLAG_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ edgeFlag_ARRAY ].ptr; + return; + case GL_SECONDARY_COLOR_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ secondaryColor_ARRAY ].ptr; + return; + case GL_FOG_COORD_ARRAY_POINTER: + *params = (void *)state->vertArray.arrays[ fogCoord_ARRAY ].ptr; + 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; + } +} + |