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