single2.c revision 848b8605
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 occured; 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 occured; 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 occured; 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 occured; 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 ** occured. 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 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 792GLboolean 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 833void 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 880GLboolean 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 911GLboolean 912glAreTexturesResidentEXT(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