single2.c revision cdc920a0
1cdc920a0Smrg/*
2cdc920a0Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3cdc920a0Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4cdc920a0Smrg *
5cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6cdc920a0Smrg * copy of this software and associated documentation files (the "Software"),
7cdc920a0Smrg * to deal in the Software without restriction, including without limitation
8cdc920a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the
10cdc920a0Smrg * Software is furnished to do so, subject to the following conditions:
11cdc920a0Smrg *
12cdc920a0Smrg * The above copyright notice including the dates of first publication and
13cdc920a0Smrg * either this permission notice or a reference to
14cdc920a0Smrg * http://oss.sgi.com/projects/FreeB/
15cdc920a0Smrg * shall be included in all copies or substantial portions of the Software.
16cdc920a0Smrg *
17cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20cdc920a0Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21cdc920a0Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22cdc920a0Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23cdc920a0Smrg * SOFTWARE.
24cdc920a0Smrg *
25cdc920a0Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26cdc920a0Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27cdc920a0Smrg * other dealings in this Software without prior written authorization from
28cdc920a0Smrg * Silicon Graphics, Inc.
29cdc920a0Smrg */
30cdc920a0Smrg
31cdc920a0Smrg#include <stdio.h>
32cdc920a0Smrg#include <assert.h>
33cdc920a0Smrg#include "glxclient.h"
34cdc920a0Smrg#include "packsingle.h"
35cdc920a0Smrg#include "glxextensions.h"
36cdc920a0Smrg#include "indirect.h"
37cdc920a0Smrg#include "indirect_vertex_array.h"
38cdc920a0Smrg#include "glapitable.h"
39cdc920a0Smrg#include "glapidispatch.h"
40cdc920a0Smrg#include "glapi.h"
41cdc920a0Smrg#ifdef USE_XCB
42cdc920a0Smrg#include <xcb/xcb.h>
43cdc920a0Smrg#include <xcb/glx.h>
44cdc920a0Smrg#include <X11/Xlib-xcb.h>
45cdc920a0Smrg#endif /* USE_XCB */
46cdc920a0Smrg
47cdc920a0Smrg
48cdc920a0Smrg/* Used for GL_ARB_transpose_matrix */
49cdc920a0Smrgstatic void
50cdc920a0SmrgTransposeMatrixf(GLfloat m[16])
51cdc920a0Smrg{
52cdc920a0Smrg   int i, j;
53cdc920a0Smrg   for (i = 0; i < 4; i++) {
54cdc920a0Smrg      for (j = 0; j < i; j++) {
55cdc920a0Smrg         GLfloat tmp = m[i * 4 + j];
56cdc920a0Smrg         m[i * 4 + j] = m[j * 4 + i];
57cdc920a0Smrg         m[j * 4 + i] = tmp;
58cdc920a0Smrg      }
59cdc920a0Smrg   }
60cdc920a0Smrg}
61cdc920a0Smrg
62cdc920a0Smrg/* Used for GL_ARB_transpose_matrix */
63cdc920a0Smrgstatic void
64cdc920a0SmrgTransposeMatrixb(GLboolean m[16])
65cdc920a0Smrg{
66cdc920a0Smrg   int i, j;
67cdc920a0Smrg   for (i = 0; i < 4; i++) {
68cdc920a0Smrg      for (j = 0; j < i; j++) {
69cdc920a0Smrg         GLboolean tmp = m[i * 4 + j];
70cdc920a0Smrg         m[i * 4 + j] = m[j * 4 + i];
71cdc920a0Smrg         m[j * 4 + i] = tmp;
72cdc920a0Smrg      }
73cdc920a0Smrg   }
74cdc920a0Smrg}
75cdc920a0Smrg
76cdc920a0Smrg/* Used for GL_ARB_transpose_matrix */
77cdc920a0Smrgstatic void
78cdc920a0SmrgTransposeMatrixd(GLdouble m[16])
79cdc920a0Smrg{
80cdc920a0Smrg   int i, j;
81cdc920a0Smrg   for (i = 0; i < 4; i++) {
82cdc920a0Smrg      for (j = 0; j < i; j++) {
83cdc920a0Smrg         GLdouble tmp = m[i * 4 + j];
84cdc920a0Smrg         m[i * 4 + j] = m[j * 4 + i];
85cdc920a0Smrg         m[j * 4 + i] = tmp;
86cdc920a0Smrg      }
87cdc920a0Smrg   }
88cdc920a0Smrg}
89cdc920a0Smrg
90cdc920a0Smrg/* Used for GL_ARB_transpose_matrix */
91cdc920a0Smrgstatic void
92cdc920a0SmrgTransposeMatrixi(GLint m[16])
93cdc920a0Smrg{
94cdc920a0Smrg   int i, j;
95cdc920a0Smrg   for (i = 0; i < 4; i++) {
96cdc920a0Smrg      for (j = 0; j < i; j++) {
97cdc920a0Smrg         GLint tmp = m[i * 4 + j];
98cdc920a0Smrg         m[i * 4 + j] = m[j * 4 + i];
99cdc920a0Smrg         m[j * 4 + i] = tmp;
100cdc920a0Smrg      }
101cdc920a0Smrg   }
102cdc920a0Smrg}
103cdc920a0Smrg
104cdc920a0Smrg
105cdc920a0Smrg/**
106cdc920a0Smrg * Remap a transpose-matrix enum to a non-transpose-matrix enum.  Enums
107cdc920a0Smrg * that are not transpose-matrix enums are unaffected.
108cdc920a0Smrg */
109cdc920a0Smrgstatic GLenum
110cdc920a0SmrgRemapTransposeEnum(GLenum e)
111cdc920a0Smrg{
112cdc920a0Smrg   switch (e) {
113cdc920a0Smrg   case GL_TRANSPOSE_MODELVIEW_MATRIX:
114cdc920a0Smrg   case GL_TRANSPOSE_PROJECTION_MATRIX:
115cdc920a0Smrg   case GL_TRANSPOSE_TEXTURE_MATRIX:
116cdc920a0Smrg      return e - (GL_TRANSPOSE_MODELVIEW_MATRIX - GL_MODELVIEW_MATRIX);
117cdc920a0Smrg   case GL_TRANSPOSE_COLOR_MATRIX:
118cdc920a0Smrg      return GL_COLOR_MATRIX;
119cdc920a0Smrg   default:
120cdc920a0Smrg      return e;
121cdc920a0Smrg   };
122cdc920a0Smrg}
123cdc920a0Smrg
124cdc920a0Smrg
125cdc920a0SmrgGLenum
126cdc920a0Smrg__indirect_glGetError(void)
127cdc920a0Smrg{
128cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
129cdc920a0Smrg   GLuint retval = GL_NO_ERROR;
130cdc920a0Smrg   xGLXGetErrorReply reply;
131cdc920a0Smrg
132cdc920a0Smrg   if (gc->error) {
133cdc920a0Smrg      /* Use internal error first */
134cdc920a0Smrg      retval = gc->error;
135cdc920a0Smrg      gc->error = GL_NO_ERROR;
136cdc920a0Smrg      return retval;
137cdc920a0Smrg   }
138cdc920a0Smrg
139cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
140cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetError, 0);
141cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
142cdc920a0Smrg   retval = reply.error;
143cdc920a0Smrg   __GLX_SINGLE_END();
144cdc920a0Smrg
145cdc920a0Smrg   return retval;
146cdc920a0Smrg}
147cdc920a0Smrg
148cdc920a0Smrg
149cdc920a0Smrg/**
150cdc920a0Smrg * Get the selected attribute from the client state.
151cdc920a0Smrg *
152cdc920a0Smrg * \returns
153cdc920a0Smrg * On success \c GL_TRUE is returned.  Otherwise, \c GL_FALSE is returned.
154cdc920a0Smrg */
155cdc920a0Smrgstatic GLboolean
156cdc920a0Smrgget_client_data(__GLXcontext * gc, GLenum cap, GLintptr * data)
157cdc920a0Smrg{
158cdc920a0Smrg   GLboolean retval = GL_TRUE;
159cdc920a0Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
160cdc920a0Smrg   const GLint tex_unit = __glXGetActiveTextureUnit(state);
161cdc920a0Smrg
162cdc920a0Smrg
163cdc920a0Smrg   switch (cap) {
164cdc920a0Smrg   case GL_VERTEX_ARRAY:
165cdc920a0Smrg   case GL_NORMAL_ARRAY:
166cdc920a0Smrg   case GL_COLOR_ARRAY:
167cdc920a0Smrg   case GL_INDEX_ARRAY:
168cdc920a0Smrg   case GL_EDGE_FLAG_ARRAY:
169cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY:
170cdc920a0Smrg   case GL_FOG_COORD_ARRAY:
171cdc920a0Smrg      retval = __glXGetArrayEnable(state, cap, 0, data);
172cdc920a0Smrg      break;
173cdc920a0Smrg
174cdc920a0Smrg   case GL_VERTEX_ARRAY_SIZE:
175cdc920a0Smrg      retval = __glXGetArraySize(state, GL_VERTEX_ARRAY, 0, data);
176cdc920a0Smrg      break;
177cdc920a0Smrg   case GL_COLOR_ARRAY_SIZE:
178cdc920a0Smrg      retval = __glXGetArraySize(state, GL_COLOR_ARRAY, 0, data);
179cdc920a0Smrg      break;
180cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY_SIZE:
181cdc920a0Smrg      retval = __glXGetArraySize(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
182cdc920a0Smrg      break;
183cdc920a0Smrg
184cdc920a0Smrg   case GL_VERTEX_ARRAY_TYPE:
185cdc920a0Smrg      retval = __glXGetArrayType(state, GL_VERTEX_ARRAY, 0, data);
186cdc920a0Smrg      break;
187cdc920a0Smrg   case GL_NORMAL_ARRAY_TYPE:
188cdc920a0Smrg      retval = __glXGetArrayType(state, GL_NORMAL_ARRAY, 0, data);
189cdc920a0Smrg      break;
190cdc920a0Smrg   case GL_INDEX_ARRAY_TYPE:
191cdc920a0Smrg      retval = __glXGetArrayType(state, GL_INDEX_ARRAY, 0, data);
192cdc920a0Smrg      break;
193cdc920a0Smrg   case GL_COLOR_ARRAY_TYPE:
194cdc920a0Smrg      retval = __glXGetArrayType(state, GL_COLOR_ARRAY, 0, data);
195cdc920a0Smrg      break;
196cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY_TYPE:
197cdc920a0Smrg      retval = __glXGetArrayType(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
198cdc920a0Smrg      break;
199cdc920a0Smrg   case GL_FOG_COORD_ARRAY_TYPE:
200cdc920a0Smrg      retval = __glXGetArrayType(state, GL_FOG_COORD_ARRAY, 0, data);
201cdc920a0Smrg      break;
202cdc920a0Smrg
203cdc920a0Smrg   case GL_VERTEX_ARRAY_STRIDE:
204cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_VERTEX_ARRAY, 0, data);
205cdc920a0Smrg      break;
206cdc920a0Smrg   case GL_NORMAL_ARRAY_STRIDE:
207cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_NORMAL_ARRAY, 0, data);
208cdc920a0Smrg      break;
209cdc920a0Smrg   case GL_INDEX_ARRAY_STRIDE:
210cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_INDEX_ARRAY, 0, data);
211cdc920a0Smrg      break;
212cdc920a0Smrg   case GL_EDGE_FLAG_ARRAY_STRIDE:
213cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_EDGE_FLAG_ARRAY, 0, data);
214cdc920a0Smrg      break;
215cdc920a0Smrg   case GL_COLOR_ARRAY_STRIDE:
216cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_COLOR_ARRAY, 0, data);
217cdc920a0Smrg      break;
218cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY_STRIDE:
219cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
220cdc920a0Smrg      break;
221cdc920a0Smrg   case GL_FOG_COORD_ARRAY_STRIDE:
222cdc920a0Smrg      retval = __glXGetArrayStride(state, GL_FOG_COORD_ARRAY, 0, data);
223cdc920a0Smrg      break;
224cdc920a0Smrg
225cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY:
226cdc920a0Smrg      retval =
227cdc920a0Smrg         __glXGetArrayEnable(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
228cdc920a0Smrg      break;
229cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY_SIZE:
230cdc920a0Smrg      retval =
231cdc920a0Smrg         __glXGetArraySize(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
232cdc920a0Smrg      break;
233cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY_TYPE:
234cdc920a0Smrg      retval =
235cdc920a0Smrg         __glXGetArrayType(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
236cdc920a0Smrg      break;
237cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY_STRIDE:
238cdc920a0Smrg      retval =
239cdc920a0Smrg         __glXGetArrayStride(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
240cdc920a0Smrg      break;
241cdc920a0Smrg
242cdc920a0Smrg   case GL_MAX_ELEMENTS_VERTICES:
243cdc920a0Smrg   case GL_MAX_ELEMENTS_INDICES:
244cdc920a0Smrg      retval = GL_TRUE;
245cdc920a0Smrg      *data = ~0UL;
246cdc920a0Smrg      break;
247cdc920a0Smrg
248cdc920a0Smrg
249cdc920a0Smrg   case GL_PACK_ROW_LENGTH:
250cdc920a0Smrg      *data = (GLintptr) state->storePack.rowLength;
251cdc920a0Smrg      break;
252cdc920a0Smrg   case GL_PACK_IMAGE_HEIGHT:
253cdc920a0Smrg      *data = (GLintptr) state->storePack.imageHeight;
254cdc920a0Smrg      break;
255cdc920a0Smrg   case GL_PACK_SKIP_ROWS:
256cdc920a0Smrg      *data = (GLintptr) state->storePack.skipRows;
257cdc920a0Smrg      break;
258cdc920a0Smrg   case GL_PACK_SKIP_PIXELS:
259cdc920a0Smrg      *data = (GLintptr) state->storePack.skipPixels;
260cdc920a0Smrg      break;
261cdc920a0Smrg   case GL_PACK_SKIP_IMAGES:
262cdc920a0Smrg      *data = (GLintptr) state->storePack.skipImages;
263cdc920a0Smrg      break;
264cdc920a0Smrg   case GL_PACK_ALIGNMENT:
265cdc920a0Smrg      *data = (GLintptr) state->storePack.alignment;
266cdc920a0Smrg      break;
267cdc920a0Smrg   case GL_PACK_SWAP_BYTES:
268cdc920a0Smrg      *data = (GLintptr) state->storePack.swapEndian;
269cdc920a0Smrg      break;
270cdc920a0Smrg   case GL_PACK_LSB_FIRST:
271cdc920a0Smrg      *data = (GLintptr) state->storePack.lsbFirst;
272cdc920a0Smrg      break;
273cdc920a0Smrg   case GL_UNPACK_ROW_LENGTH:
274cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.rowLength;
275cdc920a0Smrg      break;
276cdc920a0Smrg   case GL_UNPACK_IMAGE_HEIGHT:
277cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.imageHeight;
278cdc920a0Smrg      break;
279cdc920a0Smrg   case GL_UNPACK_SKIP_ROWS:
280cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.skipRows;
281cdc920a0Smrg      break;
282cdc920a0Smrg   case GL_UNPACK_SKIP_PIXELS:
283cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.skipPixels;
284cdc920a0Smrg      break;
285cdc920a0Smrg   case GL_UNPACK_SKIP_IMAGES:
286cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.skipImages;
287cdc920a0Smrg      break;
288cdc920a0Smrg   case GL_UNPACK_ALIGNMENT:
289cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.alignment;
290cdc920a0Smrg      break;
291cdc920a0Smrg   case GL_UNPACK_SWAP_BYTES:
292cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.swapEndian;
293cdc920a0Smrg      break;
294cdc920a0Smrg   case GL_UNPACK_LSB_FIRST:
295cdc920a0Smrg      *data = (GLintptr) state->storeUnpack.lsbFirst;
296cdc920a0Smrg      break;
297cdc920a0Smrg   case GL_CLIENT_ATTRIB_STACK_DEPTH:
298cdc920a0Smrg      *data = (GLintptr) (gc->attributes.stackPointer - gc->attributes.stack);
299cdc920a0Smrg      break;
300cdc920a0Smrg   case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
301cdc920a0Smrg      *data = (GLintptr) __GL_CLIENT_ATTRIB_STACK_DEPTH;
302cdc920a0Smrg      break;
303cdc920a0Smrg   case GL_CLIENT_ACTIVE_TEXTURE:
304cdc920a0Smrg      *data = (GLintptr) (tex_unit + GL_TEXTURE0);
305cdc920a0Smrg      break;
306cdc920a0Smrg
307cdc920a0Smrg   default:
308cdc920a0Smrg      retval = GL_FALSE;
309cdc920a0Smrg      break;
310cdc920a0Smrg   }
311cdc920a0Smrg
312cdc920a0Smrg
313cdc920a0Smrg   return retval;
314cdc920a0Smrg}
315cdc920a0Smrg
316cdc920a0Smrg
317cdc920a0Smrgvoid
318cdc920a0Smrg__indirect_glGetBooleanv(GLenum val, GLboolean * b)
319cdc920a0Smrg{
320cdc920a0Smrg   const GLenum origVal = val;
321cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
322cdc920a0Smrg   xGLXSingleReply reply;
323cdc920a0Smrg
324cdc920a0Smrg   val = RemapTransposeEnum(val);
325cdc920a0Smrg
326cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
327cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetBooleanv, 4);
328cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, val);
329cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
330cdc920a0Smrg   __GLX_SINGLE_GET_SIZE(compsize);
331cdc920a0Smrg
332cdc920a0Smrg   if (compsize == 0) {
333cdc920a0Smrg      /*
334cdc920a0Smrg       ** Error occured; don't modify user's buffer.
335cdc920a0Smrg       */
336cdc920a0Smrg   }
337cdc920a0Smrg   else {
338cdc920a0Smrg      GLintptr data;
339cdc920a0Smrg
340cdc920a0Smrg      /*
341cdc920a0Smrg       ** We still needed to send the request to the server in order to
342cdc920a0Smrg       ** find out whether it was legal to make a query (it's illegal,
343cdc920a0Smrg       ** for example, to call a query between glBegin() and glEnd()).
344cdc920a0Smrg       */
345cdc920a0Smrg
346cdc920a0Smrg      if (get_client_data(gc, val, &data)) {
347cdc920a0Smrg         *b = (GLboolean) data;
348cdc920a0Smrg      }
349cdc920a0Smrg      else {
350cdc920a0Smrg         /*
351cdc920a0Smrg          ** Not a local value, so use what we got from the server.
352cdc920a0Smrg          */
353cdc920a0Smrg         if (compsize == 1) {
354cdc920a0Smrg            __GLX_SINGLE_GET_CHAR(b);
355cdc920a0Smrg         }
356cdc920a0Smrg         else {
357cdc920a0Smrg            __GLX_SINGLE_GET_CHAR_ARRAY(b, compsize);
358cdc920a0Smrg            if (val != origVal) {
359cdc920a0Smrg               /* matrix transpose */
360cdc920a0Smrg               TransposeMatrixb(b);
361cdc920a0Smrg            }
362cdc920a0Smrg         }
363cdc920a0Smrg      }
364cdc920a0Smrg   }
365cdc920a0Smrg   __GLX_SINGLE_END();
366cdc920a0Smrg}
367cdc920a0Smrg
368cdc920a0Smrgvoid
369cdc920a0Smrg__indirect_glGetDoublev(GLenum val, GLdouble * d)
370cdc920a0Smrg{
371cdc920a0Smrg   const GLenum origVal = val;
372cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
373cdc920a0Smrg   xGLXSingleReply reply;
374cdc920a0Smrg
375cdc920a0Smrg   val = RemapTransposeEnum(val);
376cdc920a0Smrg
377cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
378cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetDoublev, 4);
379cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, val);
380cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
381cdc920a0Smrg   __GLX_SINGLE_GET_SIZE(compsize);
382cdc920a0Smrg
383cdc920a0Smrg   if (compsize == 0) {
384cdc920a0Smrg      /*
385cdc920a0Smrg       ** Error occured; don't modify user's buffer.
386cdc920a0Smrg       */
387cdc920a0Smrg   }
388cdc920a0Smrg   else {
389cdc920a0Smrg      GLintptr data;
390cdc920a0Smrg
391cdc920a0Smrg      /*
392cdc920a0Smrg       ** We still needed to send the request to the server in order to
393cdc920a0Smrg       ** find out whether it was legal to make a query (it's illegal,
394cdc920a0Smrg       ** for example, to call a query between glBegin() and glEnd()).
395cdc920a0Smrg       */
396cdc920a0Smrg
397cdc920a0Smrg      if (get_client_data(gc, val, &data)) {
398cdc920a0Smrg         *d = (GLdouble) data;
399cdc920a0Smrg      }
400cdc920a0Smrg      else {
401cdc920a0Smrg         /*
402cdc920a0Smrg          ** Not a local value, so use what we got from the server.
403cdc920a0Smrg          */
404cdc920a0Smrg         if (compsize == 1) {
405cdc920a0Smrg            __GLX_SINGLE_GET_DOUBLE(d);
406cdc920a0Smrg         }
407cdc920a0Smrg         else {
408cdc920a0Smrg            __GLX_SINGLE_GET_DOUBLE_ARRAY(d, compsize);
409cdc920a0Smrg            if (val != origVal) {
410cdc920a0Smrg               /* matrix transpose */
411cdc920a0Smrg               TransposeMatrixd(d);
412cdc920a0Smrg            }
413cdc920a0Smrg         }
414cdc920a0Smrg      }
415cdc920a0Smrg   }
416cdc920a0Smrg   __GLX_SINGLE_END();
417cdc920a0Smrg}
418cdc920a0Smrg
419cdc920a0Smrgvoid
420cdc920a0Smrg__indirect_glGetFloatv(GLenum val, GLfloat * f)
421cdc920a0Smrg{
422cdc920a0Smrg   const GLenum origVal = val;
423cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
424cdc920a0Smrg   xGLXSingleReply reply;
425cdc920a0Smrg
426cdc920a0Smrg   val = RemapTransposeEnum(val);
427cdc920a0Smrg
428cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
429cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetFloatv, 4);
430cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, val);
431cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
432cdc920a0Smrg   __GLX_SINGLE_GET_SIZE(compsize);
433cdc920a0Smrg
434cdc920a0Smrg   if (compsize == 0) {
435cdc920a0Smrg      /*
436cdc920a0Smrg       ** Error occured; don't modify user's buffer.
437cdc920a0Smrg       */
438cdc920a0Smrg   }
439cdc920a0Smrg   else {
440cdc920a0Smrg      GLintptr data;
441cdc920a0Smrg
442cdc920a0Smrg      /*
443cdc920a0Smrg       ** We still needed to send the request to the server in order to
444cdc920a0Smrg       ** find out whether it was legal to make a query (it's illegal,
445cdc920a0Smrg       ** for example, to call a query between glBegin() and glEnd()).
446cdc920a0Smrg       */
447cdc920a0Smrg
448cdc920a0Smrg      if (get_client_data(gc, val, &data)) {
449cdc920a0Smrg         *f = (GLfloat) data;
450cdc920a0Smrg      }
451cdc920a0Smrg      else {
452cdc920a0Smrg         /*
453cdc920a0Smrg          ** Not a local value, so use what we got from the server.
454cdc920a0Smrg          */
455cdc920a0Smrg         if (compsize == 1) {
456cdc920a0Smrg            __GLX_SINGLE_GET_FLOAT(f);
457cdc920a0Smrg         }
458cdc920a0Smrg         else {
459cdc920a0Smrg            __GLX_SINGLE_GET_FLOAT_ARRAY(f, compsize);
460cdc920a0Smrg            if (val != origVal) {
461cdc920a0Smrg               /* matrix transpose */
462cdc920a0Smrg               TransposeMatrixf(f);
463cdc920a0Smrg            }
464cdc920a0Smrg         }
465cdc920a0Smrg      }
466cdc920a0Smrg   }
467cdc920a0Smrg   __GLX_SINGLE_END();
468cdc920a0Smrg}
469cdc920a0Smrg
470cdc920a0Smrgvoid
471cdc920a0Smrg__indirect_glGetIntegerv(GLenum val, GLint * i)
472cdc920a0Smrg{
473cdc920a0Smrg   const GLenum origVal = val;
474cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
475cdc920a0Smrg   xGLXSingleReply reply;
476cdc920a0Smrg
477cdc920a0Smrg   val = RemapTransposeEnum(val);
478cdc920a0Smrg
479cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
480cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_GetIntegerv, 4);
481cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, val);
482cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
483cdc920a0Smrg   __GLX_SINGLE_GET_SIZE(compsize);
484cdc920a0Smrg
485cdc920a0Smrg   if (compsize == 0) {
486cdc920a0Smrg      /*
487cdc920a0Smrg       ** Error occured; don't modify user's buffer.
488cdc920a0Smrg       */
489cdc920a0Smrg   }
490cdc920a0Smrg   else {
491cdc920a0Smrg      GLintptr data;
492cdc920a0Smrg
493cdc920a0Smrg      /*
494cdc920a0Smrg       ** We still needed to send the request to the server in order to
495cdc920a0Smrg       ** find out whether it was legal to make a query (it's illegal,
496cdc920a0Smrg       ** for example, to call a query between glBegin() and glEnd()).
497cdc920a0Smrg       */
498cdc920a0Smrg
499cdc920a0Smrg      if (get_client_data(gc, val, &data)) {
500cdc920a0Smrg         *i = (GLint) data;
501cdc920a0Smrg      }
502cdc920a0Smrg      else {
503cdc920a0Smrg         /*
504cdc920a0Smrg          ** Not a local value, so use what we got from the server.
505cdc920a0Smrg          */
506cdc920a0Smrg         if (compsize == 1) {
507cdc920a0Smrg            __GLX_SINGLE_GET_LONG(i);
508cdc920a0Smrg         }
509cdc920a0Smrg         else {
510cdc920a0Smrg            __GLX_SINGLE_GET_LONG_ARRAY(i, compsize);
511cdc920a0Smrg            if (val != origVal) {
512cdc920a0Smrg               /* matrix transpose */
513cdc920a0Smrg               TransposeMatrixi(i);
514cdc920a0Smrg            }
515cdc920a0Smrg         }
516cdc920a0Smrg      }
517cdc920a0Smrg   }
518cdc920a0Smrg   __GLX_SINGLE_END();
519cdc920a0Smrg}
520cdc920a0Smrg
521cdc920a0Smrg/*
522cdc920a0Smrg** Send all pending commands to server.
523cdc920a0Smrg*/
524cdc920a0Smrgvoid
525cdc920a0Smrg__indirect_glFlush(void)
526cdc920a0Smrg{
527cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
528cdc920a0Smrg
529cdc920a0Smrg   if (!dpy)
530cdc920a0Smrg      return;
531cdc920a0Smrg
532cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
533cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_Flush, 0);
534cdc920a0Smrg   __GLX_SINGLE_END();
535cdc920a0Smrg
536cdc920a0Smrg   /* And finally flush the X protocol data */
537cdc920a0Smrg   XFlush(dpy);
538cdc920a0Smrg}
539cdc920a0Smrg
540cdc920a0Smrgvoid
541cdc920a0Smrg__indirect_glFeedbackBuffer(GLsizei size, GLenum type, GLfloat * buffer)
542cdc920a0Smrg{
543cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
544cdc920a0Smrg
545cdc920a0Smrg   if (!dpy)
546cdc920a0Smrg      return;
547cdc920a0Smrg
548cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
549cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_FeedbackBuffer, 8);
550cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, size);
551cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(4, type);
552cdc920a0Smrg   __GLX_SINGLE_END();
553cdc920a0Smrg
554cdc920a0Smrg   gc->feedbackBuf = buffer;
555cdc920a0Smrg}
556cdc920a0Smrg
557cdc920a0Smrgvoid
558cdc920a0Smrg__indirect_glSelectBuffer(GLsizei numnames, GLuint * buffer)
559cdc920a0Smrg{
560cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
561cdc920a0Smrg
562cdc920a0Smrg   if (!dpy)
563cdc920a0Smrg      return;
564cdc920a0Smrg
565cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
566cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_SelectBuffer, 4);
567cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, numnames);
568cdc920a0Smrg   __GLX_SINGLE_END();
569cdc920a0Smrg
570cdc920a0Smrg   gc->selectBuf = buffer;
571cdc920a0Smrg}
572cdc920a0Smrg
573cdc920a0SmrgGLint
574cdc920a0Smrg__indirect_glRenderMode(GLenum mode)
575cdc920a0Smrg{
576cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
577cdc920a0Smrg   GLint retval = 0;
578cdc920a0Smrg   xGLXRenderModeReply reply;
579cdc920a0Smrg
580cdc920a0Smrg   if (!dpy)
581cdc920a0Smrg      return -1;
582cdc920a0Smrg
583cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
584cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_RenderMode, 4);
585cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, mode);
586cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
587cdc920a0Smrg   __GLX_SINGLE_GET_RETVAL(retval, GLint);
588cdc920a0Smrg
589cdc920a0Smrg   if (reply.newMode != mode) {
590cdc920a0Smrg      /*
591cdc920a0Smrg       ** Switch to new mode did not take effect, therefore an error
592cdc920a0Smrg       ** occured.  When an error happens the server won't send us any
593cdc920a0Smrg       ** other data.
594cdc920a0Smrg       */
595cdc920a0Smrg   }
596cdc920a0Smrg   else {
597cdc920a0Smrg      /* Read the feedback or selection data */
598cdc920a0Smrg      if (gc->renderMode == GL_FEEDBACK) {
599cdc920a0Smrg         __GLX_SINGLE_GET_SIZE(compsize);
600cdc920a0Smrg         __GLX_SINGLE_GET_FLOAT_ARRAY(gc->feedbackBuf, compsize);
601cdc920a0Smrg      }
602cdc920a0Smrg      else if (gc->renderMode == GL_SELECT) {
603cdc920a0Smrg         __GLX_SINGLE_GET_SIZE(compsize);
604cdc920a0Smrg         __GLX_SINGLE_GET_LONG_ARRAY(gc->selectBuf, compsize);
605cdc920a0Smrg      }
606cdc920a0Smrg      gc->renderMode = mode;
607cdc920a0Smrg   }
608cdc920a0Smrg   __GLX_SINGLE_END();
609cdc920a0Smrg
610cdc920a0Smrg   return retval;
611cdc920a0Smrg}
612cdc920a0Smrg
613cdc920a0Smrgvoid
614cdc920a0Smrg__indirect_glFinish(void)
615cdc920a0Smrg{
616cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
617cdc920a0Smrg   xGLXSingleReply reply;
618cdc920a0Smrg
619cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
620cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_Finish, 0);
621cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
622cdc920a0Smrg   __GLX_SINGLE_END();
623cdc920a0Smrg}
624cdc920a0Smrg
625cdc920a0Smrg
626cdc920a0Smrg/**
627cdc920a0Smrg * Extract the major and minor version numbers from a version string.
628cdc920a0Smrg */
629cdc920a0Smrgstatic void
630cdc920a0Smrgversion_from_string(const char *ver, int *major_version, int *minor_version)
631cdc920a0Smrg{
632cdc920a0Smrg   const char *end;
633cdc920a0Smrg   long major;
634cdc920a0Smrg   long minor;
635cdc920a0Smrg
636cdc920a0Smrg   major = strtol(ver, (char **) &end, 10);
637cdc920a0Smrg   minor = strtol(end + 1, NULL, 10);
638cdc920a0Smrg   *major_version = major;
639cdc920a0Smrg   *minor_version = minor;
640cdc920a0Smrg}
641cdc920a0Smrg
642cdc920a0Smrg
643cdc920a0Smrgconst GLubyte *
644cdc920a0Smrg__indirect_glGetString(GLenum name)
645cdc920a0Smrg{
646cdc920a0Smrg   __GLXcontext *gc = __glXGetCurrentContext();
647cdc920a0Smrg   Display *dpy = gc->currentDpy;
648cdc920a0Smrg   GLubyte *s = NULL;
649cdc920a0Smrg
650cdc920a0Smrg   if (!dpy)
651cdc920a0Smrg      return 0;
652cdc920a0Smrg
653cdc920a0Smrg   /*
654cdc920a0Smrg    ** Return the cached copy if the string has already been fetched
655cdc920a0Smrg    */
656cdc920a0Smrg   switch (name) {
657cdc920a0Smrg   case GL_VENDOR:
658cdc920a0Smrg      if (gc->vendor)
659cdc920a0Smrg         return gc->vendor;
660cdc920a0Smrg      break;
661cdc920a0Smrg   case GL_RENDERER:
662cdc920a0Smrg      if (gc->renderer)
663cdc920a0Smrg         return gc->renderer;
664cdc920a0Smrg      break;
665cdc920a0Smrg   case GL_VERSION:
666cdc920a0Smrg      if (gc->version)
667cdc920a0Smrg         return gc->version;
668cdc920a0Smrg      break;
669cdc920a0Smrg   case GL_EXTENSIONS:
670cdc920a0Smrg      if (gc->extensions)
671cdc920a0Smrg         return gc->extensions;
672cdc920a0Smrg      break;
673cdc920a0Smrg   default:
674cdc920a0Smrg      __glXSetError(gc, GL_INVALID_ENUM);
675cdc920a0Smrg      return 0;
676cdc920a0Smrg   }
677cdc920a0Smrg
678cdc920a0Smrg   /*
679cdc920a0Smrg    ** Get requested string from server
680cdc920a0Smrg    */
681cdc920a0Smrg
682cdc920a0Smrg   (void) __glXFlushRenderBuffer(gc, gc->pc);
683cdc920a0Smrg   s = (GLubyte *) __glXGetString(dpy, gc->majorOpcode, gc->currentContextTag,
684cdc920a0Smrg                                  name);
685cdc920a0Smrg   if (!s) {
686cdc920a0Smrg      /* Throw data on the floor */
687cdc920a0Smrg      __glXSetError(gc, GL_OUT_OF_MEMORY);
688cdc920a0Smrg   }
689cdc920a0Smrg   else {
690cdc920a0Smrg      /*
691cdc920a0Smrg       ** Update local cache
692cdc920a0Smrg       */
693cdc920a0Smrg      switch (name) {
694cdc920a0Smrg      case GL_VENDOR:
695cdc920a0Smrg         gc->vendor = s;
696cdc920a0Smrg         break;
697cdc920a0Smrg
698cdc920a0Smrg      case GL_RENDERER:
699cdc920a0Smrg         gc->renderer = s;
700cdc920a0Smrg         break;
701cdc920a0Smrg
702cdc920a0Smrg      case GL_VERSION:{
703cdc920a0Smrg            int client_major;
704cdc920a0Smrg            int client_minor;
705cdc920a0Smrg
706cdc920a0Smrg            version_from_string((char *) s,
707cdc920a0Smrg                                &gc->server_major, &gc->server_minor);
708cdc920a0Smrg            __glXGetGLVersion(&client_major, &client_minor);
709cdc920a0Smrg
710cdc920a0Smrg            if ((gc->server_major < client_major)
711cdc920a0Smrg                || ((gc->server_major == client_major)
712cdc920a0Smrg                    && (gc->server_minor <= client_minor))) {
713cdc920a0Smrg               gc->version = s;
714cdc920a0Smrg            }
715cdc920a0Smrg            else {
716cdc920a0Smrg               /* Allow 7 bytes for the client-side GL version.  This allows
717cdc920a0Smrg                * for upto version 999.999.  I'm not holding my breath for
718cdc920a0Smrg                * that one!  The extra 4 is for the ' ()\0' that will be
719cdc920a0Smrg                * added.
720cdc920a0Smrg                */
721cdc920a0Smrg               const size_t size = 7 + strlen((char *) s) + 4;
722cdc920a0Smrg
723cdc920a0Smrg               gc->version = Xmalloc(size);
724cdc920a0Smrg               if (gc->version == NULL) {
725cdc920a0Smrg                  /* If we couldn't allocate memory for the new string,
726cdc920a0Smrg                   * make a best-effort and just copy the client-side version
727cdc920a0Smrg                   * to the string and use that.  It probably doesn't
728cdc920a0Smrg                   * matter what is done here.  If there not memory available
729cdc920a0Smrg                   * for a short string, the system is probably going to die
730cdc920a0Smrg                   * soon anyway.
731cdc920a0Smrg                   */
732cdc920a0Smrg                  snprintf((char *) s, strlen((char *) s) + 1, "%u.%u",
733cdc920a0Smrg                           client_major, client_minor);
734cdc920a0Smrg                  gc->version = s;
735cdc920a0Smrg               }
736cdc920a0Smrg               else {
737cdc920a0Smrg                  snprintf((char *) gc->version, size, "%u.%u (%s)",
738cdc920a0Smrg                           client_major, client_minor, s);
739cdc920a0Smrg                  Xfree(s);
740cdc920a0Smrg                  s = gc->version;
741cdc920a0Smrg               }
742cdc920a0Smrg            }
743cdc920a0Smrg            break;
744cdc920a0Smrg         }
745cdc920a0Smrg
746cdc920a0Smrg      case GL_EXTENSIONS:{
747cdc920a0Smrg            int major = 1;
748cdc920a0Smrg            int minor = 0;
749cdc920a0Smrg
750cdc920a0Smrg            /* This code is currently disabled.  I was reminded that some
751cdc920a0Smrg             * vendors intentionally exclude some extensions from their
752cdc920a0Smrg             * extension string that are part of the core version they
753cdc920a0Smrg             * advertise.  In particular, on Nvidia drivers this means that
754cdc920a0Smrg             * the functionality is supported by the driver, but is not
755cdc920a0Smrg             * hardware accelerated.  For example, a TNT will show core
756cdc920a0Smrg             * version 1.5, but most of the post-1.2 functionality is a
757cdc920a0Smrg             * software fallback.
758cdc920a0Smrg             *
759cdc920a0Smrg             * I don't want to break applications that rely on this odd
760cdc920a0Smrg             * behavior.  At the same time, the code is written and tested,
761cdc920a0Smrg             * so I didn't want to throw it away.  Therefore, the code is here
762cdc920a0Smrg             * but disabled.  In the future, we may wish to and an environment
763cdc920a0Smrg             * variable to enable it.
764cdc920a0Smrg             */
765cdc920a0Smrg
766cdc920a0Smrg#if 0
767cdc920a0Smrg            /* Call glGetString just to make sure that gc->server_major and
768cdc920a0Smrg             * gc->server_minor are set.  This version may be higher than we
769cdc920a0Smrg             * can completely support, but it may imply support for some
770cdc920a0Smrg             * extensions that we can support.
771cdc920a0Smrg             *
772cdc920a0Smrg             * For example, at the time of this writing, the client-side
773cdc920a0Smrg             * library only supports upto core GL version 1.2.  However, cubic
774cdc920a0Smrg             * textures, multitexture, multisampling, and some other 1.3
775cdc920a0Smrg             * features are supported.  If the server reports back version
776cdc920a0Smrg             * 1.3, but does not report all of those extensions, we will
777cdc920a0Smrg             * enable them.
778cdc920a0Smrg             */
779cdc920a0Smrg            (void *) glGetString(GL_VERSION);
780cdc920a0Smrg            major = gc->server_major, minor = gc->server_minor;
781cdc920a0Smrg#endif
782cdc920a0Smrg
783cdc920a0Smrg            __glXCalculateUsableGLExtensions(gc, (char *) s, major, minor);
784cdc920a0Smrg            XFree(s);
785cdc920a0Smrg            s = gc->extensions;
786cdc920a0Smrg            break;
787cdc920a0Smrg         }
788cdc920a0Smrg      }
789cdc920a0Smrg   }
790cdc920a0Smrg   return s;
791cdc920a0Smrg}
792cdc920a0Smrg
793cdc920a0SmrgGLboolean
794cdc920a0Smrg__indirect_glIsEnabled(GLenum cap)
795cdc920a0Smrg{
796cdc920a0Smrg   __GLX_SINGLE_DECLARE_VARIABLES();
797cdc920a0Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
798cdc920a0Smrg   xGLXSingleReply reply;
799cdc920a0Smrg   GLboolean retval = 0;
800cdc920a0Smrg   GLintptr enable;
801cdc920a0Smrg
802cdc920a0Smrg   if (!dpy)
803cdc920a0Smrg      return 0;
804cdc920a0Smrg
805cdc920a0Smrg   switch (cap) {
806cdc920a0Smrg   case GL_VERTEX_ARRAY:
807cdc920a0Smrg   case GL_NORMAL_ARRAY:
808cdc920a0Smrg   case GL_COLOR_ARRAY:
809cdc920a0Smrg   case GL_INDEX_ARRAY:
810cdc920a0Smrg   case GL_EDGE_FLAG_ARRAY:
811cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY:
812cdc920a0Smrg   case GL_FOG_COORD_ARRAY:
813cdc920a0Smrg      retval = __glXGetArrayEnable(state, cap, 0, &enable);
814cdc920a0Smrg      assert(retval);
815cdc920a0Smrg      return (GLboolean) enable;
816cdc920a0Smrg      break;
817cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY:
818cdc920a0Smrg      retval = __glXGetArrayEnable(state, GL_TEXTURE_COORD_ARRAY,
819cdc920a0Smrg                                   __glXGetActiveTextureUnit(state), &enable);
820cdc920a0Smrg      assert(retval);
821cdc920a0Smrg      return (GLboolean) enable;
822cdc920a0Smrg      break;
823cdc920a0Smrg   }
824cdc920a0Smrg
825cdc920a0Smrg   __GLX_SINGLE_LOAD_VARIABLES();
826cdc920a0Smrg   __GLX_SINGLE_BEGIN(X_GLsop_IsEnabled, 4);
827cdc920a0Smrg   __GLX_SINGLE_PUT_LONG(0, cap);
828cdc920a0Smrg   __GLX_SINGLE_READ_XREPLY();
829cdc920a0Smrg   __GLX_SINGLE_GET_RETVAL(retval, GLboolean);
830cdc920a0Smrg   __GLX_SINGLE_END();
831cdc920a0Smrg   return retval;
832cdc920a0Smrg}
833cdc920a0Smrg
834cdc920a0Smrgvoid
835cdc920a0Smrg__indirect_glGetPointerv(GLenum pname, void **params)
836cdc920a0Smrg{
837cdc920a0Smrg   __GLXcontext *gc = __glXGetCurrentContext();
838cdc920a0Smrg   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
839cdc920a0Smrg   Display *dpy = gc->currentDpy;
840cdc920a0Smrg
841cdc920a0Smrg   if (!dpy)
842cdc920a0Smrg      return;
843cdc920a0Smrg
844cdc920a0Smrg   switch (pname) {
845cdc920a0Smrg   case GL_VERTEX_ARRAY_POINTER:
846cdc920a0Smrg   case GL_NORMAL_ARRAY_POINTER:
847cdc920a0Smrg   case GL_COLOR_ARRAY_POINTER:
848cdc920a0Smrg   case GL_INDEX_ARRAY_POINTER:
849cdc920a0Smrg   case GL_EDGE_FLAG_ARRAY_POINTER:
850cdc920a0Smrg      __glXGetArrayPointer(state, pname - GL_VERTEX_ARRAY_POINTER
851cdc920a0Smrg                           + GL_VERTEX_ARRAY, 0, params);
852cdc920a0Smrg      return;
853cdc920a0Smrg   case GL_TEXTURE_COORD_ARRAY_POINTER:
854cdc920a0Smrg      __glXGetArrayPointer(state, GL_TEXTURE_COORD_ARRAY,
855cdc920a0Smrg                           __glXGetActiveTextureUnit(state), params);
856cdc920a0Smrg      return;
857cdc920a0Smrg   case GL_SECONDARY_COLOR_ARRAY_POINTER:
858cdc920a0Smrg   case GL_FOG_COORD_ARRAY_POINTER:
859cdc920a0Smrg      __glXGetArrayPointer(state, pname - GL_FOG_COORD_ARRAY_POINTER
860cdc920a0Smrg                           + GL_FOG_COORD_ARRAY, 0, params);
861cdc920a0Smrg      return;
862cdc920a0Smrg   case GL_FEEDBACK_BUFFER_POINTER:
863cdc920a0Smrg      *params = (void *) gc->feedbackBuf;
864cdc920a0Smrg      return;
865cdc920a0Smrg   case GL_SELECTION_BUFFER_POINTER:
866cdc920a0Smrg      *params = (void *) gc->selectBuf;
867cdc920a0Smrg      return;
868cdc920a0Smrg   default:
869cdc920a0Smrg      __glXSetError(gc, GL_INVALID_ENUM);
870cdc920a0Smrg      return;
871cdc920a0Smrg   }
872cdc920a0Smrg}
873cdc920a0Smrg
874cdc920a0Smrg
875cdc920a0Smrg
876cdc920a0Smrg/**
877cdc920a0Smrg * This was previously auto-generated, but we need to special-case
878cdc920a0Smrg * how we handle writing into the 'residences' buffer when n%4!=0.
879cdc920a0Smrg */
880cdc920a0Smrg#define X_GLsop_AreTexturesResident 143
881cdc920a0SmrgGLboolean
882cdc920a0Smrg__indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
883cdc920a0Smrg                                 GLboolean * residences)
884cdc920a0Smrg{
885cdc920a0Smrg   __GLXcontext *const gc = __glXGetCurrentContext();
886cdc920a0Smrg   Display *const dpy = gc->currentDpy;
887cdc920a0Smrg   GLboolean retval = (GLboolean) 0;
888cdc920a0Smrg   const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
889cdc920a0Smrg   if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
890cdc920a0Smrg#ifdef USE_XCB
891cdc920a0Smrg      xcb_connection_t *c = XGetXCBConnection(dpy);
892cdc920a0Smrg      (void) __glXFlushRenderBuffer(gc, gc->pc);
893cdc920a0Smrg      xcb_glx_are_textures_resident_reply_t *reply =
894cdc920a0Smrg         xcb_glx_are_textures_resident_reply(c,
895cdc920a0Smrg                                             xcb_glx_are_textures_resident
896cdc920a0Smrg                                             (c, gc->currentContextTag, n,
897cdc920a0Smrg                                              textures), NULL);
898cdc920a0Smrg      (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
899cdc920a0Smrg                    xcb_glx_are_textures_resident_data_length(reply) *
900cdc920a0Smrg                    sizeof(GLboolean));
901cdc920a0Smrg      retval = reply->ret_val;
902cdc920a0Smrg      free(reply);
903cdc920a0Smrg#else
904cdc920a0Smrg      GLubyte const *pc =
905cdc920a0Smrg         __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen);
906cdc920a0Smrg      (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
907cdc920a0Smrg      (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
908cdc920a0Smrg      if (n & 3) {
909cdc920a0Smrg         /* n is not a multiple of four.
910cdc920a0Smrg          * When reply_is_always_array is TRUE, __glXReadReply() will
911cdc920a0Smrg          * put a multiple of four bytes into the dest buffer.  If the
912cdc920a0Smrg          * caller's buffer is not a multiple of four in size, we'll write
913cdc920a0Smrg          * out of bounds.  So use a temporary buffer that's a few bytes
914cdc920a0Smrg          * larger.
915cdc920a0Smrg          */
916cdc920a0Smrg         GLboolean *res4 = malloc((n + 3) & ~3);
917cdc920a0Smrg         retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
918cdc920a0Smrg         memcpy(residences, res4, n);
919cdc920a0Smrg         free(res4);
920cdc920a0Smrg      }
921cdc920a0Smrg      else {
922cdc920a0Smrg         retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
923cdc920a0Smrg      }
924cdc920a0Smrg      UnlockDisplay(dpy);
925cdc920a0Smrg      SyncHandle();
926cdc920a0Smrg#endif /* USE_XCB */
927cdc920a0Smrg   }
928cdc920a0Smrg   return retval;
929cdc920a0Smrg}
930cdc920a0Smrg
931cdc920a0Smrg
932cdc920a0Smrg/**
933cdc920a0Smrg * This was previously auto-generated, but we need to special-case
934cdc920a0Smrg * how we handle writing into the 'residences' buffer when n%4!=0.
935cdc920a0Smrg */
936cdc920a0Smrg#define X_GLvop_AreTexturesResidentEXT 11
937cdc920a0SmrgGLboolean
938cdc920a0SmrgglAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
939cdc920a0Smrg                         GLboolean * residences)
940cdc920a0Smrg{
941cdc920a0Smrg   __GLXcontext *const gc = __glXGetCurrentContext();
942cdc920a0Smrg
943cdc920a0Smrg   if (gc->isDirect) {
944cdc920a0Smrg      return CALL_AreTexturesResident(GET_DISPATCH(),
945cdc920a0Smrg                                      (n, textures, residences));
946cdc920a0Smrg   }
947cdc920a0Smrg   else {
948cdc920a0Smrg      __GLXcontext *const gc = __glXGetCurrentContext();
949cdc920a0Smrg      Display *const dpy = gc->currentDpy;
950cdc920a0Smrg      GLboolean retval = (GLboolean) 0;
951cdc920a0Smrg      const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
952cdc920a0Smrg      if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
953cdc920a0Smrg         GLubyte const *pc =
954cdc920a0Smrg            __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
955cdc920a0Smrg                                    X_GLvop_AreTexturesResidentEXT,
956cdc920a0Smrg                                    cmdlen);
957cdc920a0Smrg         (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
958cdc920a0Smrg         (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
959cdc920a0Smrg         if (n & 3) {
960cdc920a0Smrg            /* see comments in __indirect_glAreTexturesResident() */
961cdc920a0Smrg            GLboolean *res4 = malloc((n + 3) & ~3);
962cdc920a0Smrg            retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
963cdc920a0Smrg            memcpy(residences, res4, n);
964cdc920a0Smrg            free(res4);
965cdc920a0Smrg         }
966cdc920a0Smrg         else {
967cdc920a0Smrg            retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
968cdc920a0Smrg         }
969cdc920a0Smrg         UnlockDisplay(dpy);
970cdc920a0Smrg         SyncHandle();
971cdc920a0Smrg      }
972cdc920a0Smrg      return retval;
973cdc920a0Smrg   }
974cdc920a0Smrg}
975