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