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