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