• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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->majorOpcode, gc->currentContextTag,
683                                   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 = malloc(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                   free(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             free(s);
784             s = gc->extensions;
785             break;
786          }
787       }
788    }
789    return s;
790 }
791 
792 GLboolean
__indirect_glIsEnabled(GLenum cap)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
__indirect_glGetPointerv(GLenum pname,void ** params)834 __indirect_glGetPointerv(GLenum pname, void **params)
835 {
836    struct glx_context *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
__indirect_glAreTexturesResident(GLsizei n,const GLuint * textures,GLboolean * residences)881 __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
882                                  GLboolean * residences)
883 {
884    struct glx_context *const gc = __glXGetCurrentContext();
885    Display *const dpy = gc->currentDpy;
886    GLboolean retval = (GLboolean) 0;
887    if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
888       xcb_connection_t *c = XGetXCBConnection(dpy);
889       xcb_glx_are_textures_resident_reply_t *reply;
890       (void) __glXFlushRenderBuffer(gc, gc->pc);
891       reply =
892          xcb_glx_are_textures_resident_reply(c,
893                                              xcb_glx_are_textures_resident
894                                              (c, gc->currentContextTag, n,
895                                               textures), NULL);
896       (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
897                     xcb_glx_are_textures_resident_data_length(reply) *
898                     sizeof(GLboolean));
899       retval = reply->ret_val;
900       free(reply);
901    }
902    return retval;
903 }
904 
905 
906 /**
907  * This was previously auto-generated, but we need to special-case
908  * how we handle writing into the 'residences' buffer when n%4!=0.
909  */
910 #define X_GLvop_AreTexturesResidentEXT 11
911 GLboolean
glAreTexturesResidentEXT(GLsizei n,const GLuint * textures,GLboolean * residences)912 glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
913                          GLboolean * residences)
914 {
915    struct glx_context *const gc = __glXGetCurrentContext();
916 
917    if (gc->isDirect) {
918       const _glapi_proc *const table = (_glapi_proc *) GET_DISPATCH();
919       PFNGLARETEXTURESRESIDENTEXTPROC p =
920          (PFNGLARETEXTURESRESIDENTEXTPROC) table[332];
921 
922       return p(n, textures, residences);
923    }
924    else {
925       struct glx_context *const gc = __glXGetCurrentContext();
926       Display *const dpy = gc->currentDpy;
927       GLboolean retval = (GLboolean) 0;
928       const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
929       if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
930          GLubyte const *pc =
931             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
932                                     X_GLvop_AreTexturesResidentEXT,
933                                     cmdlen);
934          (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
935          (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
936          if (n & 3) {
937             /* see comments in __indirect_glAreTexturesResident() */
938             GLboolean *res4 = malloc((n + 3) & ~3);
939             retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
940             memcpy(residences, res4, n);
941             free(res4);
942          }
943          else {
944             retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
945          }
946          UnlockDisplay(dpy);
947          SyncHandle();
948       }
949       return retval;
950    }
951 }
952