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 */ 48static void 49TransposeMatrixf(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 */ 62static void 63TransposeMatrixb(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 */ 76static void 77TransposeMatrixd(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 */ 90static void 91TransposeMatrixi(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 */ 108static GLenum 109RemapTransposeEnum(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 124GLenum 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 */ 154static GLboolean 155get_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 316void 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 367void 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 418void 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 469void 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*/ 523void 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 539void 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 556void 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 572GLint 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 612void 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 */ 628static void 629version_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 642const GLubyte * 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 NULL; 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 NULL; 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 754GLboolean 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 795void 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 842GLboolean 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 873GLboolean 874glAreTexturesResidentEXT(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