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