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