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