Make the transition to script-genereated GLX code easier.
[profile/ivi/mesa.git] / src / glx / x11 / single2.c
1 /* $XFree86: xc/lib/GL/glx/single2.c,v 1.10 2004/02/11 19:48:16 dawes Exp $ */
2 /*
3 ** License Applicability. Except to the extent portions of this file are
4 ** made subject to an alternative license as permitted in the SGI Free
5 ** Software License B, Version 1.1 (the "License"), the contents of this
6 ** file are subject only to the provisions of the License. You may not use
7 ** this file except in compliance with the License. You may obtain a copy
8 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** 
11 ** http://oss.sgi.com/projects/FreeB
12 ** 
13 ** Note that, as provided in the License, the Software is distributed on an
14 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** 
19 ** Original Code. The Original Code is: OpenGL Sample Implementation,
20 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22 ** Copyright in any portions created by third parties is as indicated
23 ** elsewhere herein. All Rights Reserved.
24 ** 
25 ** Additional Notice Provisions: The application programming interfaces
26 ** established by SGI in conjunction with the Original Code are The
27 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30 ** Window System(R) (Version 1.3), released October 19, 1998. This software
31 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32 ** published by SGI, but has not been independently verified as being
33 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 **
35 */
36
37 #include <stdio.h>
38 #include "glxclient.h"
39 #include "packsingle.h"
40 #include "glxextensions.h"
41
42 /* Used for GL_ARB_transpose_matrix */
43 static void TransposeMatrixf(GLfloat m[16])
44 {
45     int i, j;
46     for (i = 0; i < 4; i++) {
47         for (j = 0; j < i; j++) {
48             GLfloat tmp = m[i*4+j];
49             m[i*4+j] = m[j*4+i];
50             m[j*4+i] = tmp;
51         }
52     }
53 }
54
55 /* Used for GL_ARB_transpose_matrix */
56 static void TransposeMatrixb(GLboolean m[16])
57 {
58     int i, j;
59     for (i = 0; i < 4; i++) {
60         for (j = 0; j < i; j++) {
61             GLboolean tmp = m[i*4+j];
62             m[i*4+j] = m[j*4+i];
63             m[j*4+i] = tmp;
64         }
65     }
66 }
67
68 /* Used for GL_ARB_transpose_matrix */
69 static void TransposeMatrixd(GLdouble m[16])
70 {
71     int i, j;
72     for (i = 0; i < 4; i++) {
73         for (j = 0; j < i; j++) {
74             GLdouble tmp = m[i*4+j];
75             m[i*4+j] = m[j*4+i];
76             m[j*4+i] = tmp;
77         }
78     }
79 }
80
81 /* Used for GL_ARB_transpose_matrix */
82 static void TransposeMatrixi(GLint m[16])
83 {
84     int i, j;
85     for (i = 0; i < 4; i++) {
86         for (j = 0; j < i; j++) {
87             GLint tmp = m[i*4+j];
88             m[i*4+j] = m[j*4+i];
89             m[j*4+i] = tmp;
90         }
91     }
92 }
93
94 GLenum __indirect_glGetError(void)
95 {
96     __GLX_SINGLE_DECLARE_VARIABLES();
97     GLuint retval = GL_NO_ERROR;
98     xGLXGetErrorReply reply;
99
100     if (gc->error) {
101         /* Use internal error first */
102         retval = gc->error;
103         gc->error = GL_NO_ERROR;
104         return retval;
105     }
106
107     __GLX_SINGLE_LOAD_VARIABLES();
108     __GLX_SINGLE_BEGIN(X_GLsop_GetError,0);
109     __GLX_SINGLE_READ_XREPLY();
110     retval = reply.error;
111     __GLX_SINGLE_END();
112
113     return retval;
114 }
115
116 void __indirect_glGetClipPlane(GLenum plane, GLdouble *equation)
117 {
118     __GLX_SINGLE_DECLARE_VARIABLES();
119     xGLXSingleReply reply;
120     __GLX_SINGLE_LOAD_VARIABLES();
121     __GLX_SINGLE_BEGIN(X_GLsop_GetClipPlane,4);
122     __GLX_SINGLE_PUT_LONG(0,plane);
123     __GLX_SINGLE_READ_XREPLY();
124     if (reply.length == 8) {
125         __GLX_SINGLE_GET_DOUBLE_ARRAY(equation,4);
126     }
127     __GLX_SINGLE_END();
128 }
129
130 #define CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type) \
131     case GL_ ## enum_name ## _ARRAY: \
132       *dest = (gl_type) (IS_ARRAY_ENABLED(state, array)); break
133 #define CASE_ARRAY_SIZE(enum_name,array,dest,gl_type) \
134     case GL_ ## enum_name ## _ARRAY_SIZE: \
135       *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].size ; break
136 #define CASE_ARRAY_TYPE(enum_name,array,dest,gl_type) \
137     case GL_ ## enum_name ## _ARRAY_TYPE: \
138       *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].type ; break
139 #define CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type) \
140     case GL_ ## enum_name ## _ARRAY_STRIDE: \
141       *dest = (gl_type) state->vertArray.arrays[array ## _ARRAY].stride ; break
142
143 #define CASE_ARRAY_ALL(enum_name,array,dest,gl_type) \
144         CASE_ARRAY_ENABLE(enum_name,array,dest,gl_type); \
145         CASE_ARRAY_STRIDE(enum_name,array,dest,gl_type); \
146         CASE_ARRAY_TYPE(enum_name,array,dest,gl_type); \
147         CASE_ARRAY_SIZE(enum_name,array,dest,gl_type)
148
149 void __indirect_glGetBooleanv(GLenum val, GLboolean *b)
150 {
151     const GLenum origVal = val;
152     __GLX_SINGLE_DECLARE_VARIABLES();
153     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
154     xGLXSingleReply reply;
155
156     if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) {
157        val = GL_MODELVIEW_MATRIX;
158     }
159     else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) {
160        val = GL_PROJECTION_MATRIX;
161     }
162     else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) {
163        val = GL_TEXTURE_MATRIX;
164     }
165     else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) {
166        val = GL_COLOR_MATRIX;
167     }
168
169     __GLX_SINGLE_LOAD_VARIABLES();
170     __GLX_SINGLE_BEGIN(X_GLsop_GetBooleanv,4);
171     __GLX_SINGLE_PUT_LONG(0,val);
172     __GLX_SINGLE_READ_XREPLY();
173     __GLX_SINGLE_GET_SIZE(compsize);
174
175     if (compsize == 0) {
176         /*
177         ** Error occured; don't modify user's buffer.
178         */
179     } else {
180         /*
181         ** For all the queries listed here, we use the locally stored
182         ** values rather than the one returned by the server.  Note that
183         ** we still needed to send the request to the server in order to
184         ** find out whether it was legal to make a query (it's illegal,
185         ** for example, to call a query between glBegin() and glEnd()).
186         */
187         switch (val) {
188           case GL_PACK_ROW_LENGTH:
189             *b = (GLboolean)state->storePack.rowLength;
190             break;
191           case GL_PACK_IMAGE_HEIGHT:
192             *b = (GLboolean)state->storePack.imageHeight;
193             break;
194           case GL_PACK_SKIP_ROWS:
195             *b = (GLboolean)state->storePack.skipRows;
196             break;
197           case GL_PACK_SKIP_PIXELS:
198             *b = (GLboolean)state->storePack.skipPixels;
199             break;
200           case GL_PACK_SKIP_IMAGES:
201             *b = (GLboolean)state->storePack.skipImages;
202             break;
203           case GL_PACK_ALIGNMENT:
204             *b = (GLboolean)state->storePack.alignment;
205             break;
206           case GL_PACK_SWAP_BYTES:
207             *b = (GLboolean)state->storePack.swapEndian;
208             break;
209           case GL_PACK_LSB_FIRST:
210             *b = (GLboolean)state->storePack.lsbFirst;
211             break;
212           case GL_UNPACK_ROW_LENGTH:
213             *b = (GLboolean)state->storeUnpack.rowLength;
214             break;
215           case GL_UNPACK_IMAGE_HEIGHT:
216             *b = (GLboolean)state->storeUnpack.imageHeight;
217             break;
218           case GL_UNPACK_SKIP_ROWS:
219             *b = (GLboolean)state->storeUnpack.skipRows;
220             break;
221           case GL_UNPACK_SKIP_PIXELS:
222             *b = (GLboolean)state->storeUnpack.skipPixels;
223             break;
224           case GL_UNPACK_SKIP_IMAGES:
225             *b = (GLboolean)state->storeUnpack.skipImages;
226             break;
227           case GL_UNPACK_ALIGNMENT:
228             *b = (GLboolean)state->storeUnpack.alignment;
229             break;
230           case GL_UNPACK_SWAP_BYTES:
231             *b = (GLboolean)state->storeUnpack.swapEndian;
232             break;
233           case GL_UNPACK_LSB_FIRST:
234             *b = (GLboolean)state->storeUnpack.lsbFirst;
235             break;
236
237           CASE_ARRAY_ALL(VERTEX, vertex, b, GLboolean);
238
239           CASE_ARRAY_ENABLE(NORMAL, normal, b, GLboolean);
240           CASE_ARRAY_TYPE(NORMAL, normal, b, GLboolean);
241           CASE_ARRAY_STRIDE(NORMAL, normal, b, GLboolean);
242
243           CASE_ARRAY_ALL(COLOR, color, b, GLboolean);
244
245           CASE_ARRAY_ENABLE(INDEX, index, b, GLboolean);
246           CASE_ARRAY_TYPE(INDEX, index, b, GLboolean);
247           CASE_ARRAY_STRIDE(INDEX, index, b, GLboolean);
248
249           case GL_TEXTURE_COORD_ARRAY:
250             *b = (GLboolean)IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
251             break;
252           case GL_TEXTURE_COORD_ARRAY_SIZE:
253             *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].size;
254             break;
255           case GL_TEXTURE_COORD_ARRAY_TYPE:
256             *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].type;
257             break;
258           case GL_TEXTURE_COORD_ARRAY_STRIDE:
259             *b = (GLboolean)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
260             break;
261
262           CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, b, GLboolean);
263           CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, b, GLboolean);
264
265           CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, b, GLboolean);
266
267           CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, b, GLboolean);
268           CASE_ARRAY_TYPE(FOG_COORD, fogCoord, b, GLboolean);
269           CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, b, GLboolean);
270
271           case GL_MAX_ELEMENTS_VERTICES:
272             *b = (GLboolean)state->vertArray.maxElementsVertices;
273             break;
274           case GL_MAX_ELEMENTS_INDICES:
275             *b = (GLboolean)state->vertArray.maxElementsIndices;
276             break;
277           case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
278             *b = (GLboolean)__GL_CLIENT_ATTRIB_STACK_DEPTH;
279             break;
280           case GL_CLIENT_ACTIVE_TEXTURE_ARB:
281             *b = (GLboolean)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
282             break;
283           default:
284             /*
285             ** Not a local value, so use what we got from the server.
286             */
287             if (compsize == 1) {
288                 __GLX_SINGLE_GET_CHAR(b);
289             } else {
290                 __GLX_SINGLE_GET_CHAR_ARRAY(b,compsize);
291                 if (val != origVal) {
292                    /* matrix transpose */
293                    TransposeMatrixb(b);
294                 }
295             }
296         }
297     }
298     __GLX_SINGLE_END();
299 }
300
301 void __indirect_glGetDoublev(GLenum val, GLdouble *d)
302 {
303     const GLenum origVal = val;
304     __GLX_SINGLE_DECLARE_VARIABLES();
305     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
306     xGLXSingleReply reply;
307
308     if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) {
309        val = GL_MODELVIEW_MATRIX;
310     }
311     else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) {
312        val = GL_PROJECTION_MATRIX;
313     }
314     else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) {
315        val = GL_TEXTURE_MATRIX;
316     }
317     else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) {
318        val = GL_COLOR_MATRIX;
319     }
320
321     __GLX_SINGLE_LOAD_VARIABLES();
322     __GLX_SINGLE_BEGIN(X_GLsop_GetDoublev,4);
323     __GLX_SINGLE_PUT_LONG(0,val);
324     __GLX_SINGLE_READ_XREPLY();
325     __GLX_SINGLE_GET_SIZE(compsize);
326
327     if (compsize == 0) {
328         /*
329         ** Error occured; don't modify user's buffer.
330         */
331     } else {
332         /*
333         ** For all the queries listed here, we use the locally stored
334         ** values rather than the one returned by the server.  Note that
335         ** we still needed to send the request to the server in order to
336         ** find out whether it was legal to make a query (it's illegal,
337         ** for example, to call a query between glBegin() and glEnd()).
338         */
339         switch (val) {
340           case GL_PACK_ROW_LENGTH:
341             *d = (GLdouble)state->storePack.rowLength;
342             break;
343           case GL_PACK_IMAGE_HEIGHT:
344             *d = (GLdouble)state->storePack.imageHeight;
345             break;
346           case GL_PACK_SKIP_ROWS:
347             *d = (GLdouble)state->storePack.skipRows;
348             break;
349           case GL_PACK_SKIP_PIXELS:
350             *d = (GLdouble)state->storePack.skipPixels;
351             break;
352           case GL_PACK_SKIP_IMAGES:
353             *d = (GLdouble)state->storePack.skipImages;
354             break;
355           case GL_PACK_ALIGNMENT:
356             *d = (GLdouble)state->storePack.alignment;
357             break;
358           case GL_PACK_SWAP_BYTES:
359             *d = (GLdouble)state->storePack.swapEndian;
360             break;
361           case GL_PACK_LSB_FIRST:
362             *d = (GLdouble)state->storePack.lsbFirst;
363             break;
364           case GL_UNPACK_ROW_LENGTH:
365             *d = (GLdouble)state->storeUnpack.rowLength;
366             break;
367           case GL_UNPACK_IMAGE_HEIGHT:
368             *d = (GLdouble)state->storeUnpack.imageHeight;
369             break;
370           case GL_UNPACK_SKIP_ROWS:
371             *d = (GLdouble)state->storeUnpack.skipRows;
372             break;
373           case GL_UNPACK_SKIP_PIXELS:
374             *d = (GLdouble)state->storeUnpack.skipPixels;
375             break;
376           case GL_UNPACK_SKIP_IMAGES:
377             *d = (GLdouble)state->storeUnpack.skipImages;
378             break;
379           case GL_UNPACK_ALIGNMENT:
380             *d = (GLdouble)state->storeUnpack.alignment;
381             break;
382           case GL_UNPACK_SWAP_BYTES:
383             *d = (GLdouble)state->storeUnpack.swapEndian;
384             break;
385           case GL_UNPACK_LSB_FIRST:
386             *d = (GLdouble)state->storeUnpack.lsbFirst;
387             break;
388
389           CASE_ARRAY_ALL(VERTEX, vertex, d, GLdouble);
390
391           CASE_ARRAY_ENABLE(NORMAL, normal, d, GLdouble);
392           CASE_ARRAY_TYPE(NORMAL, normal, d, GLdouble);
393           CASE_ARRAY_STRIDE(NORMAL, normal, d, GLdouble);
394
395           CASE_ARRAY_ALL(COLOR, color, d, GLdouble);
396
397           CASE_ARRAY_ENABLE(INDEX, index, d, GLdouble);
398           CASE_ARRAY_TYPE(INDEX, index, d, GLdouble);
399           CASE_ARRAY_STRIDE(INDEX, index, d, GLdouble);
400
401           case GL_TEXTURE_COORD_ARRAY:
402             *d = (GLdouble) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
403             break;
404           case GL_TEXTURE_COORD_ARRAY_SIZE:
405             *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].size;
406             break;
407           case GL_TEXTURE_COORD_ARRAY_TYPE:
408             *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].type;
409             break;
410           case GL_TEXTURE_COORD_ARRAY_STRIDE:
411             *d = (GLdouble)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
412             break;
413
414           CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, d, GLdouble);
415           CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, d, GLdouble);
416
417           CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, d, GLdouble);
418
419           CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, d, GLdouble);
420           CASE_ARRAY_TYPE(FOG_COORD, fogCoord, d, GLdouble);
421           CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, d, GLdouble);
422
423           case GL_MAX_ELEMENTS_VERTICES:
424             *d = (GLdouble)state->vertArray.maxElementsVertices;
425             break;
426           case GL_MAX_ELEMENTS_INDICES:
427             *d = (GLdouble)state->vertArray.maxElementsIndices;
428             break;
429           case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
430             *d = (GLdouble)__GL_CLIENT_ATTRIB_STACK_DEPTH;
431             break;
432           case GL_CLIENT_ACTIVE_TEXTURE_ARB:
433             *d = (GLdouble)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
434             break;
435           default:
436             /*
437              ** Not a local value, so use what we got from the server.
438              */
439             if (compsize == 1) {
440                 __GLX_SINGLE_GET_DOUBLE(d);
441             } else {
442                 __GLX_SINGLE_GET_DOUBLE_ARRAY(d,compsize);
443                 if (val != origVal) {
444                    /* matrix transpose */
445                    TransposeMatrixd(d);
446                 }
447             }
448         }
449     }
450     __GLX_SINGLE_END();
451 }
452
453 void __indirect_glGetFloatv(GLenum val, GLfloat *f)
454 {
455     const GLenum origVal = val;
456     __GLX_SINGLE_DECLARE_VARIABLES();
457     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
458     xGLXSingleReply reply;
459
460     if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) {
461        val = GL_MODELVIEW_MATRIX;
462     }
463     else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) {
464        val = GL_PROJECTION_MATRIX;
465     }
466     else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) {
467        val = GL_TEXTURE_MATRIX;
468     }
469     else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) {
470        val = GL_COLOR_MATRIX;
471     }
472
473     __GLX_SINGLE_LOAD_VARIABLES();
474     __GLX_SINGLE_BEGIN(X_GLsop_GetFloatv,4);
475     __GLX_SINGLE_PUT_LONG(0,val);
476     __GLX_SINGLE_READ_XREPLY();
477     __GLX_SINGLE_GET_SIZE(compsize);
478
479     if (compsize == 0) {
480         /*
481         ** Error occured; don't modify user's buffer.
482         */
483     } else {
484         /*
485         ** For all the queries listed here, we use the locally stored
486         ** values rather than the one returned by the server.  Note that
487         ** we still needed to send the request to the server in order to
488         ** find out whether it was legal to make a query (it's illegal,
489         ** for example, to call a query between glBegin() and glEnd()).
490         */
491         switch (val) {
492           case GL_PACK_ROW_LENGTH:
493             *f = (GLfloat)state->storePack.rowLength;
494             break;
495           case GL_PACK_IMAGE_HEIGHT:
496             *f = (GLfloat)state->storePack.imageHeight;
497             break;
498           case GL_PACK_SKIP_ROWS:
499             *f = (GLfloat)state->storePack.skipRows;
500             break;
501           case GL_PACK_SKIP_PIXELS:
502             *f = (GLfloat)state->storePack.skipPixels;
503             break;
504           case GL_PACK_SKIP_IMAGES:
505             *f = (GLfloat)state->storePack.skipImages;
506             break;
507           case GL_PACK_ALIGNMENT:
508             *f = (GLfloat)state->storePack.alignment;
509             break;
510           case GL_PACK_SWAP_BYTES:
511             *f = (GLfloat)state->storePack.swapEndian;
512             break;
513           case GL_PACK_LSB_FIRST:
514             *f = (GLfloat)state->storePack.lsbFirst;
515             break;
516           case GL_UNPACK_ROW_LENGTH:
517             *f = (GLfloat)state->storeUnpack.rowLength;
518             break;
519           case GL_UNPACK_IMAGE_HEIGHT:
520             *f = (GLfloat)state->storeUnpack.imageHeight;
521             break;
522           case GL_UNPACK_SKIP_ROWS:
523             *f = (GLfloat)state->storeUnpack.skipRows;
524             break;
525           case GL_UNPACK_SKIP_PIXELS:
526             *f = (GLfloat)state->storeUnpack.skipPixels;
527             break;
528           case GL_UNPACK_SKIP_IMAGES:
529             *f = (GLfloat)state->storeUnpack.skipImages;
530             break;
531           case GL_UNPACK_ALIGNMENT:
532             *f = (GLfloat)state->storeUnpack.alignment;
533             break;
534           case GL_UNPACK_SWAP_BYTES:
535             *f = (GLfloat)state->storeUnpack.swapEndian;
536             break;
537           case GL_UNPACK_LSB_FIRST:
538             *f = (GLfloat)state->storeUnpack.lsbFirst;
539             break;
540
541           CASE_ARRAY_ALL(VERTEX, vertex, f, GLfloat);
542
543           CASE_ARRAY_ENABLE(NORMAL, normal, f, GLfloat);
544           CASE_ARRAY_TYPE(NORMAL, normal, f, GLfloat);
545           CASE_ARRAY_STRIDE(NORMAL, normal, f, GLfloat);
546
547           CASE_ARRAY_ALL(COLOR, color, f, GLfloat);
548
549           CASE_ARRAY_ENABLE(INDEX, index, f, GLfloat);
550           CASE_ARRAY_TYPE(INDEX, index, f, GLfloat);
551           CASE_ARRAY_STRIDE(INDEX, index, f, GLfloat);
552
553           case GL_TEXTURE_COORD_ARRAY:
554             *f = (GLfloat) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
555             break;
556           case GL_TEXTURE_COORD_ARRAY_SIZE:
557             *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].size;
558             break;
559           case GL_TEXTURE_COORD_ARRAY_TYPE:
560             *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].type;
561             break;
562           case GL_TEXTURE_COORD_ARRAY_STRIDE:
563             *f = (GLfloat)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
564             break;
565
566           CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, f, GLfloat);
567           CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, f, GLfloat);
568
569           CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, f, GLfloat);
570
571           CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, f, GLfloat);
572           CASE_ARRAY_TYPE(FOG_COORD, fogCoord, f, GLfloat);
573           CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, f, GLfloat);
574
575           case GL_MAX_ELEMENTS_VERTICES:
576             *f = (GLfloat)state->vertArray.maxElementsVertices;
577             break;
578           case GL_MAX_ELEMENTS_INDICES:
579             *f = (GLfloat)state->vertArray.maxElementsIndices;
580             break;
581           case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
582             *f = (GLfloat)__GL_CLIENT_ATTRIB_STACK_DEPTH;
583             break;
584           case GL_CLIENT_ACTIVE_TEXTURE_ARB:
585             *f = (GLfloat)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
586             break;
587           default:
588             /*
589             ** Not a local value, so use what we got from the server.
590             */
591             if (compsize == 1) {
592                 __GLX_SINGLE_GET_FLOAT(f);
593             } else {
594                 __GLX_SINGLE_GET_FLOAT_ARRAY(f,compsize);
595                 if (val != origVal) {
596                    /* matrix transpose */
597                    TransposeMatrixf(f);
598                 }
599             }
600         }
601     }
602     __GLX_SINGLE_END();
603 }
604
605 void __indirect_glGetIntegerv(GLenum val, GLint *i)
606 {
607     const GLenum origVal = val;
608     __GLX_SINGLE_DECLARE_VARIABLES();
609     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
610     xGLXSingleReply reply;
611
612     if (val == GL_TRANSPOSE_MODELVIEW_MATRIX_ARB) {
613        val = GL_MODELVIEW_MATRIX;
614     }
615     else if (val == GL_TRANSPOSE_PROJECTION_MATRIX_ARB) {
616        val = GL_PROJECTION_MATRIX;
617     }
618     else if (val == GL_TRANSPOSE_TEXTURE_MATRIX_ARB) {
619        val = GL_TEXTURE_MATRIX;
620     }
621     else if (val == GL_TRANSPOSE_COLOR_MATRIX_ARB) {
622        val = GL_COLOR_MATRIX;
623     }
624
625     __GLX_SINGLE_LOAD_VARIABLES();
626     __GLX_SINGLE_BEGIN(X_GLsop_GetIntegerv,4);
627     __GLX_SINGLE_PUT_LONG(0,val);
628     __GLX_SINGLE_READ_XREPLY();
629     __GLX_SINGLE_GET_SIZE(compsize);
630
631     if (compsize == 0) {
632         /*
633         ** Error occured; don't modify user's buffer.
634         */
635     } else {
636         /*
637         ** For all the queries listed here, we use the locally stored
638         ** values rather than the one returned by the server.  Note that
639         ** we still needed to send the request to the server in order to
640         ** find out whether it was legal to make a query (it's illegal,
641         ** for example, to call a query between glBegin() and glEnd()).
642         */
643         switch (val) {
644           case GL_PACK_ROW_LENGTH:
645             *i = (GLint)state->storePack.rowLength;
646             break;
647           case GL_PACK_IMAGE_HEIGHT:
648             *i = (GLint)state->storePack.imageHeight;
649             break;
650           case GL_PACK_SKIP_ROWS:
651             *i = (GLint)state->storePack.skipRows;
652             break;
653           case GL_PACK_SKIP_PIXELS:
654             *i = (GLint)state->storePack.skipPixels;
655             break;
656           case GL_PACK_SKIP_IMAGES:
657             *i = (GLint)state->storePack.skipImages;
658             break;
659           case GL_PACK_ALIGNMENT:
660             *i = (GLint)state->storePack.alignment;
661             break;
662           case GL_PACK_SWAP_BYTES:
663             *i = (GLint)state->storePack.swapEndian;
664             break;
665           case GL_PACK_LSB_FIRST:
666             *i = (GLint)state->storePack.lsbFirst;
667             break;
668           case GL_UNPACK_ROW_LENGTH:
669             *i = (GLint)state->storeUnpack.rowLength;
670             break;
671           case GL_UNPACK_IMAGE_HEIGHT:
672             *i = (GLint)state->storeUnpack.imageHeight;
673             break;
674           case GL_UNPACK_SKIP_ROWS:
675             *i = (GLint)state->storeUnpack.skipRows;
676             break;
677           case GL_UNPACK_SKIP_PIXELS:
678             *i = (GLint)state->storeUnpack.skipPixels;
679             break;
680           case GL_UNPACK_SKIP_IMAGES:
681             *i = (GLint)state->storeUnpack.skipImages;
682             break;
683           case GL_UNPACK_ALIGNMENT:
684             *i = (GLint)state->storeUnpack.alignment;
685             break;
686           case GL_UNPACK_SWAP_BYTES:
687             *i = (GLint)state->storeUnpack.swapEndian;
688             break;
689           case GL_UNPACK_LSB_FIRST:
690             *i = (GLint)state->storeUnpack.lsbFirst;
691             break;
692
693           CASE_ARRAY_ALL(VERTEX, vertex, i, GLint);
694
695           CASE_ARRAY_ENABLE(NORMAL, normal, i, GLint);
696           CASE_ARRAY_TYPE(NORMAL, normal, i, GLint);
697           CASE_ARRAY_STRIDE(NORMAL, normal, i, GLint);
698
699           CASE_ARRAY_ALL(COLOR, color, i, GLint);
700
701           CASE_ARRAY_ENABLE(INDEX, index, i, GLint);
702           CASE_ARRAY_TYPE(INDEX, index, i, GLint);
703           CASE_ARRAY_STRIDE(INDEX, index, i, GLint);
704
705           case GL_TEXTURE_COORD_ARRAY:
706             *i = (GLint) IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
707             break;
708           case GL_TEXTURE_COORD_ARRAY_SIZE:
709             *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].size;
710             break;
711           case GL_TEXTURE_COORD_ARRAY_TYPE:
712             *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].type;
713             break;
714           case GL_TEXTURE_COORD_ARRAY_STRIDE:
715             *i = (GLint)state->vertArray.texCoord[state->vertArray.activeTexture].stride;
716             break;
717
718           CASE_ARRAY_ENABLE(EDGE_FLAG, edgeFlag, i, GLint);
719           CASE_ARRAY_STRIDE(EDGE_FLAG, edgeFlag, i, GLint);
720
721           CASE_ARRAY_ALL(SECONDARY_COLOR, secondaryColor, i, GLint);
722
723           CASE_ARRAY_ENABLE(FOG_COORD, fogCoord, i, GLint);
724           CASE_ARRAY_TYPE(FOG_COORD, fogCoord, i, GLint);
725           CASE_ARRAY_STRIDE(FOG_COORD, fogCoord, i, GLint);
726
727           case GL_MAX_ELEMENTS_VERTICES:
728             *i = (GLint)state->vertArray.maxElementsVertices;
729             break;
730           case GL_MAX_ELEMENTS_INDICES:
731             *i = (GLint)state->vertArray.maxElementsIndices;
732             break;
733           case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
734             *i = (GLint)__GL_CLIENT_ATTRIB_STACK_DEPTH;
735             break;
736           case GL_CLIENT_ACTIVE_TEXTURE_ARB:
737             *i = (GLint)(state->vertArray.activeTexture + GL_TEXTURE0_ARB);
738             break;
739           default:
740             /*
741             ** Not a local value, so use what we got from the server.
742             */
743             if (compsize == 1) {
744                 __GLX_SINGLE_GET_LONG(i);
745             } else {
746                 __GLX_SINGLE_GET_LONG_ARRAY(i,compsize);
747                 if (val != origVal) {
748                    /* matrix transpose */
749                    TransposeMatrixi(i);
750                 }
751             }
752         }
753     }
754     __GLX_SINGLE_END();
755 }
756
757 /*
758 ** Send all pending commands to server.
759 */
760 void __indirect_glFlush(void)
761 {
762     __GLX_SINGLE_DECLARE_VARIABLES();
763
764     if (!dpy) return;
765
766     __GLX_SINGLE_LOAD_VARIABLES();
767     __GLX_SINGLE_BEGIN(X_GLsop_Flush,0);
768     __GLX_SINGLE_END();
769
770     /* And finally flush the X protocol data */
771     XFlush(dpy);
772 }
773
774 void __indirect_glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
775 {
776     __GLX_SINGLE_DECLARE_VARIABLES();
777
778     if (!dpy) return;
779
780     __GLX_SINGLE_LOAD_VARIABLES();
781     __GLX_SINGLE_BEGIN(X_GLsop_FeedbackBuffer,8);
782     __GLX_SINGLE_PUT_LONG(0,size);
783     __GLX_SINGLE_PUT_LONG(4,type);
784     __GLX_SINGLE_END();
785
786     gc->feedbackBuf = buffer;
787 }
788
789 void __indirect_glSelectBuffer(GLsizei numnames, GLuint *buffer)
790 {
791     __GLX_SINGLE_DECLARE_VARIABLES();
792
793     if (!dpy) return;
794
795     __GLX_SINGLE_LOAD_VARIABLES();
796     __GLX_SINGLE_BEGIN(X_GLsop_SelectBuffer,4);
797     __GLX_SINGLE_PUT_LONG(0,numnames);
798     __GLX_SINGLE_END();
799
800     gc->selectBuf = buffer;
801 }
802
803 GLint __indirect_glRenderMode(GLenum mode)
804 {
805     __GLX_SINGLE_DECLARE_VARIABLES();
806     GLint retval = 0;
807     xGLXRenderModeReply reply;
808
809     if (!dpy) return -1;
810
811     __GLX_SINGLE_LOAD_VARIABLES();
812     __GLX_SINGLE_BEGIN(X_GLsop_RenderMode,4);
813     __GLX_SINGLE_PUT_LONG(0,mode);
814     __GLX_SINGLE_READ_XREPLY();
815     __GLX_SINGLE_GET_RETVAL(retval,GLint);
816
817     if (reply.newMode != mode) {
818         /*
819         ** Switch to new mode did not take effect, therefore an error
820         ** occured.  When an error happens the server won't send us any
821         ** other data.
822         */
823     } else {
824         /* Read the feedback or selection data */
825         if (gc->renderMode == GL_FEEDBACK) {
826             __GLX_SINGLE_GET_SIZE(compsize);
827             __GLX_SINGLE_GET_FLOAT_ARRAY(gc->feedbackBuf, compsize);
828         } else
829         if (gc->renderMode == GL_SELECT) {
830             __GLX_SINGLE_GET_SIZE(compsize);
831             __GLX_SINGLE_GET_LONG_ARRAY(gc->selectBuf, compsize);
832         }
833         gc->renderMode = mode;
834     }
835     __GLX_SINGLE_END();
836
837     return retval;
838 }
839
840 void __indirect_glFinish(void)
841 {
842     __GLX_SINGLE_DECLARE_VARIABLES();
843     xGLXSingleReply reply;
844
845     __GLX_SINGLE_LOAD_VARIABLES();
846     __GLX_SINGLE_BEGIN(X_GLsop_Finish,0);
847     __GLX_SINGLE_READ_XREPLY();
848     __GLX_SINGLE_END();
849 }
850
851
852 /**
853  * Extract the major and minor version numbers from a version string.
854  */
855 static void
856 version_from_string( const char * ver, 
857                      int * major_version, int * minor_version )
858 {
859     const char * end;
860     long major;
861     long minor;
862
863     major = strtol( ver, (char **) & end, 10 );
864     minor = strtol( end + 1, NULL, 10 );
865     *major_version = major;
866     *minor_version = minor;
867 }
868
869
870 const GLubyte *__indirect_glGetString(GLenum name)
871 {
872     __GLXcontext *gc = __glXGetCurrentContext();
873     Display *dpy = gc->currentDpy;
874     GLubyte *s = NULL;
875
876     if (!dpy) return 0;
877
878     /*
879     ** Return the cached copy if the string has already been fetched
880     */
881     switch(name) {
882       case GL_VENDOR:
883         if (gc->vendor) return gc->vendor;
884         break;
885       case GL_RENDERER:
886         if (gc->renderer) return gc->renderer;
887         break;
888       case GL_VERSION:
889         if (gc->version) return gc->version;
890         break;
891       case GL_EXTENSIONS:
892         if (gc->extensions) return gc->extensions;
893         break;
894       default:
895         __glXSetError(gc, GL_INVALID_ENUM);
896         return 0;
897     }
898
899     /*
900     ** Get requested string from server
901     */
902
903     (void) __glXFlushRenderBuffer( gc, gc->pc );
904     s = (GLubyte *) __glXGetStringFromServer( dpy, gc->majorOpcode,
905                                   X_GLsop_GetString, gc->currentContextTag,
906                                   name );
907     if (!s) {
908         /* Throw data on the floor */
909         __glXSetError(gc, GL_OUT_OF_MEMORY);
910     } else {
911         /*
912         ** Update local cache
913         */
914         switch(name) {
915         case GL_VENDOR:
916             gc->vendor = s;
917             break;
918
919         case GL_RENDERER:
920             gc->renderer = s;
921             break;
922
923         case GL_VERSION: {
924             int client_major;
925             int client_minor;
926
927             version_from_string( (char *) s, 
928                                  & gc->server_major, & gc->server_minor );
929             __glXGetGLVersion( & client_major, & client_minor );
930
931             if ( (gc->server_major < client_major)
932                  || ((gc->server_major == client_major) 
933                      && (gc->server_minor <= client_minor)) ) {
934                 gc->version = s;
935             }
936             else {
937                 /* Allow 7 bytes for the client-side GL version.  This allows
938                  * for upto version 999.999.  I'm not holding my breath for
939                  * that one!  The extra 4 is for the ' ()\0' that will be
940                  * added.
941                  */
942                 const size_t size = 7 + strlen( (char *) s ) + 4;
943
944                 gc->version = Xmalloc( size );
945                 if ( gc->version == NULL ) {
946                     /* If we couldn't allocate memory for the new string,
947                      * make a best-effort and just copy the client-side version
948                      * to the string and use that.  It probably doesn't
949                      * matter what is done here.  If there not memory available
950                      * for a short string, the system is probably going to die
951                      * soon anyway.
952                      */
953                     snprintf( (char *) s, strlen( (char *) s ) + 1, "%u.%u",
954                               client_major, client_minor );
955                     gc->version = s;
956                 }
957                 else {
958                     snprintf( (char *)gc->version, size, "%u.%u (%s)",
959                               client_major, client_minor, s );
960                     Xfree( s );
961                     s = gc->version;
962                 }
963             }
964             break;
965         }
966
967         case GL_EXTENSIONS: {
968             int major = 1;
969             int minor = 0;
970
971             /* This code is currently disabled.  I was reminded that some
972              * vendors intentionally exclude some extensions from their
973              * extension string that are part of the core version they
974              * advertise.  In particular, on Nvidia drivers this means that
975              * the functionality is supported by the driver, but is not
976              * hardware accelerated.  For example, a TNT will show core
977              * version 1.5, but most of the post-1.2 functionality is a
978              * software fallback.
979              * 
980              * I don't want to break applications that rely on this odd
981              * behavior.  At the same time, the code is written and tested,
982              * so I didn't want to throw it away.  Therefore, the code is here
983              * but disabled.  In the future, we may wish to and an environment
984              * variable to enable it.
985              */
986             
987 #if 0
988             /* Call glGetString just to make sure that gc->server_major and
989              * gc->server_minor are set.  This version may be higher than we
990              * can completely support, but it may imply support for some
991              * extensions that we can support.
992              * 
993              * For example, at the time of this writing, the client-side
994              * library only supports upto core GL version 1.2.  However, cubic
995              * textures, multitexture, multisampling, and some other 1.3
996              * features are supported.  If the server reports back version
997              * 1.3, but does not report all of those extensions, we will
998              * enable them.
999              */
1000             (void *) glGetString( GL_VERSION );
1001             major = gc->server_major,
1002             minor = gc->server_minor;
1003 #endif
1004
1005             __glXCalculateUsableGLExtensions( gc, (char *) s, major, minor );
1006             XFree( s );
1007             s = gc->extensions;
1008             break;
1009         }
1010         }
1011     }
1012     return s;
1013 }
1014
1015 GLboolean __indirect_glIsEnabled(GLenum cap)
1016 {
1017     __GLX_SINGLE_DECLARE_VARIABLES();
1018     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1019     xGLXSingleReply reply;
1020     GLboolean retval = 0;
1021
1022     if (!dpy) return 0;
1023
1024     switch(cap) {
1025       case GL_VERTEX_ARRAY:
1026           return IS_ARRAY_ENABLED(state, vertex);
1027       case GL_NORMAL_ARRAY:
1028           return IS_ARRAY_ENABLED(state, normal);
1029       case GL_COLOR_ARRAY:
1030           return IS_ARRAY_ENABLED(state, color);
1031       case GL_INDEX_ARRAY:
1032           return IS_ARRAY_ENABLED(state, index);
1033       case GL_TEXTURE_COORD_ARRAY:
1034           return IS_TEXARRAY_ENABLED(state, state->vertArray.activeTexture);
1035       case GL_EDGE_FLAG_ARRAY:
1036           return IS_ARRAY_ENABLED(state, edgeFlag);
1037       case GL_SECONDARY_COLOR_ARRAY:
1038           return IS_ARRAY_ENABLED(state, secondaryColor);
1039       case GL_FOG_COORD_ARRAY:
1040           return IS_ARRAY_ENABLED(state, fogCoord);
1041     }
1042
1043     __GLX_SINGLE_LOAD_VARIABLES();
1044     __GLX_SINGLE_BEGIN(X_GLsop_IsEnabled,4);
1045     __GLX_SINGLE_PUT_LONG(0,cap);
1046     __GLX_SINGLE_READ_XREPLY();
1047     __GLX_SINGLE_GET_RETVAL(retval, GLboolean);
1048     __GLX_SINGLE_END();
1049     return retval;
1050 }
1051
1052 void __indirect_glGetPointerv(GLenum pname, void **params)
1053 {
1054     __GLXcontext *gc = __glXGetCurrentContext();
1055     __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1056     Display *dpy = gc->currentDpy;
1057
1058     if (!dpy) return;
1059
1060     switch(pname) {
1061       case GL_VERTEX_ARRAY_POINTER:
1062           *params = (void *)state->vertArray.arrays[ vertex_ARRAY ].ptr;
1063           return;
1064       case GL_NORMAL_ARRAY_POINTER:
1065           *params = (void *)state->vertArray.arrays[ normal_ARRAY ].ptr;
1066           return;
1067       case GL_COLOR_ARRAY_POINTER:
1068           *params = (void *)state->vertArray.arrays[ color_ARRAY ].ptr;
1069           return;
1070       case GL_INDEX_ARRAY_POINTER:
1071           *params = (void *)state->vertArray.arrays[ index_ARRAY ].ptr;
1072           return;
1073       case GL_TEXTURE_COORD_ARRAY_POINTER:
1074           *params = (void *)state->vertArray.texCoord[state->vertArray.activeTexture].ptr;
1075           return;
1076       case GL_EDGE_FLAG_ARRAY_POINTER:
1077           *params = (void *)state->vertArray.arrays[ edgeFlag_ARRAY ].ptr;
1078         return;
1079       case GL_SECONDARY_COLOR_ARRAY_POINTER:
1080           *params = (void *)state->vertArray.arrays[ secondaryColor_ARRAY ].ptr;
1081         return;
1082       case GL_FOG_COORD_ARRAY_POINTER:
1083           *params = (void *)state->vertArray.arrays[ fogCoord_ARRAY ].ptr;
1084         return;
1085       case GL_FEEDBACK_BUFFER_POINTER:
1086         *params = (void *)gc->feedbackBuf;
1087         return;
1088       case GL_SELECTION_BUFFER_POINTER:
1089         *params = (void *)gc->selectBuf;
1090         return;
1091       default:
1092         __glXSetError(gc, GL_INVALID_ENUM);
1093         return;
1094     }
1095 }
1096