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