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