1/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */ 2/* 3 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 4 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice including the dates of first publication and 14 * either this permission notice or a reference to 15 * http://oss.sgi.com/projects/FreeB/ 16 * shall be included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 * SOFTWARE. 25 * 26 * Except as contained in this notice, the name of Silicon Graphics, Inc. 27 * shall not be used in advertising or otherwise to promote the sale, use or 28 * other dealings in this Software without prior written authorization from 29 * Silicon Graphics, Inc. 30 */ 31 32#ifdef HAVE_DMX_CONFIG_H 33#include <dmx-config.h> 34#endif 35 36#include "dmx.h" 37#include "dmxwindow.h" 38#include "dmxpixmap.h" 39#include "dmxfont.h" 40#include "dmxcb.h" 41 42#include "glxserver.h" 43#include "glxext.h" 44#include "g_disptab.h" 45/* #include "g_disptab_EXT.h" */ 46#include "unpack.h" 47#include "glxutil.h" 48 49#include "GL/glxproto.h" 50 51#ifdef PANORAMIX 52#include "panoramiXsrv.h" 53#endif 54 55/* 56 * GetReqSingle - this is the equivalent of GetReq macro 57 * from Xlibint.h but it does not set the reqType field (the opcode). 58 * this is because the GL single opcodes has different naming convension 59 * the other X opcodes (ie. X_GLsop_GetFloatv). 60 */ 61#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) 62#define GetReqSingle(name, req) \ 63 WORD64ALIGN\ 64 if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ 65 _XFlush(dpy);\ 66 req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ 67 req->length = (SIZEOF(x##name##Req))>>2;\ 68 dpy->bufptr += SIZEOF(x##name##Req);\ 69 dpy->request++ 70 71#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ 72#define GetReqSingle(name, req) \ 73 WORD64ALIGN\ 74 if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ 75 _XFlush(dpy);\ 76 req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ 77 req->length = (SIZEOF(x/**/name/**/Req))>>2;\ 78 dpy->bufptr += SIZEOF(x/**/name/**/Req);\ 79 dpy->request++ 80#endif 81 82#define X_GLXSingle 0 /* needed by GetReqExtra */ 83 84extern Display *GetBackEndDisplay( __GLXclientState *cl, int s ); 85extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s); 86 87static int swap_vec_element_size = 0; 88 89static void SendSwappedReply( ClientPtr client, 90 xGLXSingleReply *reply, 91 char *buf, 92 int buf_size ) 93{ 94 __GLX_DECLARE_SWAP_VARIABLES; 95 __GLX_SWAP_SHORT(&reply->sequenceNumber); 96 __GLX_SWAP_INT(&reply->length); 97 __GLX_SWAP_INT(&reply->retval); 98 __GLX_SWAP_INT(&reply->size); 99 100 if ( (buf_size == 0) && (swap_vec_element_size > 0) ) { 101 /* 102 * the reply has single component - need to swap pad3 103 */ 104 if (swap_vec_element_size == 2) { 105 __GLX_SWAP_SHORT(&reply->pad3); 106 } 107 else if (swap_vec_element_size == 4) { 108 __GLX_SWAP_INT(&reply->pad3); 109 __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4 110 * i.e GetConvolutionFilter 111 */ 112 } 113 else if (swap_vec_element_size == 8) { 114 __GLX_SWAP_DOUBLE(&reply->pad3); 115 } 116 } 117 else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) { 118 /* 119 * the reply has vector of elements which needs to be swapped 120 */ 121 int vsize = buf_size / swap_vec_element_size; 122 char *p = buf; 123 int i; 124 125 for (i=0; i<vsize; i++) { 126 if (swap_vec_element_size == 2) { 127 __GLX_SWAP_SHORT(p); 128 } 129 else if (swap_vec_element_size == 4) { 130 __GLX_SWAP_INT(p); 131 } 132 else if (swap_vec_element_size == 8) { 133 __GLX_SWAP_DOUBLE(p); 134 } 135 136 p += swap_vec_element_size; 137 } 138 139 /* 140 * swap pad words as well - for case that some single reply uses 141 * them as well 142 */ 143 __GLX_SWAP_INT(&reply->pad3); 144 __GLX_SWAP_INT(&reply->pad4); 145 __GLX_SWAP_INT(&reply->pad5); 146 __GLX_SWAP_INT(&reply->pad6); 147 148 } 149 150 WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply); 151 if (buf_size > 0) 152 WriteToClient(client, buf_size, (char *)buf); 153 154} 155 156int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc ) 157{ 158 xGLXSingleReq *req = (xGLXSingleReq *)pc; 159 xGLXSingleReq *be_req; 160 __GLXcontext *glxc; 161 int from_screen = 0; 162 int to_screen = 0; 163 int buf_size; 164 int s; 165 166 glxc = __glXLookupContextByTag(cl, req->contextTag); 167 if (!glxc) { 168 return 0; 169 } 170 from_screen = to_screen = glxc->pScreen->myNum; 171 172#ifdef PANORAMIX 173 if (!noPanoramiXExtension) { 174 from_screen = 0; 175 to_screen = screenInfo.numScreens - 1; 176 } 177#endif 178 179 pc += sz_xGLXSingleReq; 180 buf_size = (req->length << 2) - sz_xGLXSingleReq; 181 182 /* 183 * just forward the request to back-end server(s) 184 */ 185 for (s=from_screen; s<=to_screen; s++) { 186 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 187 Display *dpy = GetBackEndDisplay(cl,s); 188 189 LockDisplay(dpy); 190 GetReqSingle(GLXSingle,be_req); 191 be_req->reqType = dmxScreen->glxMajorOpcode; 192 be_req->glxCode = req->glxCode; 193 be_req->length = req->length; 194 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); 195 if (buf_size > 0) 196 _XSend(dpy, (const char *)pc, buf_size); 197 UnlockDisplay(dpy); 198 SyncHandle(); 199 200 if (req->glxCode == X_GLsop_Flush) { 201 XFlush(dpy); 202 } 203 204 } 205 206 return Success; 207} 208 209int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc ) 210{ 211 ClientPtr client = cl->client; 212 xGLXSingleReq *req = (xGLXSingleReq *)pc; 213 xGLXSingleReq *be_req; 214 xGLXSingleReply reply; 215 xGLXSingleReply be_reply; 216 __GLXcontext *glxc; 217 int buf_size; 218 char *be_buf = NULL; 219 int be_buf_size; 220 DMXScreenInfo *dmxScreen; 221 Display *dpy; 222 223 glxc = __glXLookupContextByTag(cl, req->contextTag); 224 if (!glxc) { 225 return __glXBadContext; 226 } 227 228 pc += sz_xGLXSingleReq; 229 buf_size = (req->length << 2) - sz_xGLXSingleReq; 230 231 dmxScreen = &dmxScreens[glxc->pScreen->myNum]; 232 dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum); 233 234 /* 235 * send the request to the first back-end server 236 */ 237 LockDisplay(dpy); 238 GetReqSingle(GLXSingle,be_req); 239 be_req->reqType = dmxScreen->glxMajorOpcode; 240 be_req->glxCode = req->glxCode; 241 be_req->length = req->length; 242 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum); 243 if (buf_size > 0) 244 _XSend(dpy, (const char *)pc, buf_size); 245 246 /* 247 * get the reply from the back-end server 248 */ 249 _XReply(dpy, (xReply*) &be_reply, 0, False); 250 be_buf_size = be_reply.length << 2; 251 if (be_buf_size > 0) { 252 be_buf = (char *)malloc( be_buf_size ); 253 if (be_buf) { 254 _XRead(dpy, be_buf, be_buf_size); 255 } 256 else { 257 /* Throw data on the floor */ 258 _XEatData(dpy, be_buf_size); 259 return BadAlloc; 260 } 261 } 262 263 UnlockDisplay(dpy); 264 SyncHandle(); 265 266 /* 267 * send the reply to the client 268 */ 269 reply.type = X_Reply; 270 reply.sequenceNumber = client->sequence; 271 reply.length = be_reply.length; 272 reply.retval = be_reply.retval; 273 reply.size = be_reply.size; 274 reply.pad3 = be_reply.pad3; 275 reply.pad4 = be_reply.pad4; 276 277 if (client->swapped) { 278 SendSwappedReply( client, &reply, be_buf, be_buf_size ); 279 } 280 else { 281 WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); 282 if (be_buf_size > 0) 283 WriteToClient(client, be_buf_size, (char *)be_buf); 284 } 285 286 if (be_buf_size > 0) free(be_buf); 287 288 return Success; 289} 290 291int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc ) 292{ 293 ClientPtr client = cl->client; 294 xGLXSingleReq *req = (xGLXSingleReq *)pc; 295 xGLXSingleReq *be_req; 296 xGLXSingleReply reply; 297 xGLXSingleReply be_reply; 298 __GLXcontext *glxc; 299 int buf_size; 300 char *be_buf = NULL; 301 int be_buf_size = 0; 302 int from_screen = 0; 303 int to_screen = 0; 304 int s; 305 306 DMXScreenInfo *dmxScreen; 307 Display *dpy; 308 309 glxc = __glXLookupContextByTag(cl, req->contextTag); 310 if (!glxc) { 311 return 0; 312 } 313 from_screen = to_screen = glxc->pScreen->myNum; 314 315#ifdef PANORAMIX 316 if (!noPanoramiXExtension) { 317 from_screen = 0; 318 to_screen = screenInfo.numScreens - 1; 319 } 320#endif 321 322 pc += sz_xGLXSingleReq; 323 buf_size = (req->length << 2) - sz_xGLXSingleReq; 324 325 /* 326 * send the request to the first back-end server(s) 327 */ 328 for (s=to_screen; s>=from_screen; s--) { 329 dmxScreen = &dmxScreens[s]; 330 dpy = GetBackEndDisplay(cl,s); 331 332 LockDisplay(dpy); 333 GetReqSingle(GLXSingle,be_req); 334 be_req->reqType = dmxScreen->glxMajorOpcode; 335 be_req->glxCode = req->glxCode; 336 be_req->length = req->length; 337 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); 338 if (buf_size > 0) 339 _XSend(dpy, (const char *)pc, buf_size); 340 341 /* 342 * get the reply from the back-end server 343 */ 344 _XReply(dpy, (xReply*) &be_reply, 0, False); 345 be_buf_size = be_reply.length << 2; 346 if (be_buf_size > 0) { 347 be_buf = (char *)malloc( be_buf_size ); 348 if (be_buf) { 349 _XRead(dpy, be_buf, be_buf_size); 350 } 351 else { 352 /* Throw data on the floor */ 353 _XEatData(dpy, be_buf_size); 354 return BadAlloc; 355 } 356 } 357 358 UnlockDisplay(dpy); 359 SyncHandle(); 360 361 if (s > from_screen && be_buf_size > 0) { 362 free(be_buf); 363 } 364 } 365 366 /* 367 * send the reply to the client 368 */ 369 reply.type = X_Reply; 370 reply.sequenceNumber = client->sequence; 371 reply.length = be_reply.length; 372 reply.retval = be_reply.retval; 373 reply.size = be_reply.size; 374 reply.pad3 = be_reply.pad3; 375 reply.pad4 = be_reply.pad4; 376 377 if (client->swapped) { 378 SendSwappedReply( client, &reply, be_buf, be_buf_size ); 379 } 380 else { 381 WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply); 382 if (be_buf_size > 0) 383 WriteToClient(client, be_buf_size, (char *)be_buf); 384 } 385 386 if (be_buf_size > 0) free(be_buf); 387 388 return Success; 389} 390 391int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc ) 392{ 393 xGLXSingleReq *req = (xGLXSingleReq *)pc; 394 __GLX_DECLARE_SWAP_VARIABLES; 395 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 396 397 __GLX_SWAP_SHORT(&req->length); 398 __GLX_SWAP_INT(&req->contextTag); 399 400 swap_vec_element_size = 0; 401 402 /* 403 * swap extra data in request - assuming all data 404 * (if available) are arrays of 4 bytes components ! 405 */ 406 if (req->length > sz_xGLXSingleReq/4) { 407 int *data = (int *)(req+1); 408 int count = req->length - sz_xGLXSingleReq/4; 409 __GLX_SWAP_INT_ARRAY(data, count ); 410 } 411 412 return( __glXForwardSingleReq( cl, pc ) ); 413} 414 415int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc ) 416{ 417 xGLXSingleReq *req = (xGLXSingleReq *)pc; 418 __GLX_DECLARE_SWAP_VARIABLES; 419 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 420 421 __GLX_SWAP_SHORT(&req->length); 422 __GLX_SWAP_INT(&req->contextTag); 423 424 swap_vec_element_size = 0; 425 426 /* 427 * swap extra data in request - assuming all data 428 * (if available) are arrays of 4 bytes components ! 429 */ 430 if (req->length > sz_xGLXSingleReq/4) { 431 int *data = (int *)(req+1); 432 int count = req->length - sz_xGLXSingleReq/4; 433 __GLX_SWAP_INT_ARRAY(data, count ); 434 } 435 436 return( __glXForwardPipe0WithReply( cl, pc ) ); 437} 438 439int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) 440{ 441 xGLXSingleReq *req = (xGLXSingleReq *)pc; 442 __GLX_DECLARE_SWAP_VARIABLES; 443 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 444 445 __GLX_SWAP_SHORT(&req->length); 446 __GLX_SWAP_INT(&req->contextTag); 447 448 swap_vec_element_size = 2; 449 450 /* 451 * swap extra data in request - assuming all data 452 * (if available) are arrays of 4 bytes components ! 453 */ 454 if (req->length > sz_xGLXSingleReq/4) { 455 int *data = (int *)(req+1); 456 int count = req->length - sz_xGLXSingleReq/4; 457 __GLX_SWAP_INT_ARRAY(data, count ); 458 } 459 460 461 return( __glXForwardPipe0WithReply( cl, pc ) ); 462} 463 464int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) 465{ 466 xGLXSingleReq *req = (xGLXSingleReq *)pc; 467 __GLX_DECLARE_SWAP_VARIABLES; 468 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 469 470 __GLX_SWAP_SHORT(&req->length); 471 __GLX_SWAP_INT(&req->contextTag); 472 473 swap_vec_element_size = 4; 474 475 /* 476 * swap extra data in request - assuming all data 477 * (if available) are arrays of 4 bytes components ! 478 */ 479 if (req->length > sz_xGLXSingleReq/4) { 480 int *data = (int *)(req+1); 481 int count = req->length - sz_xGLXSingleReq/4; 482 __GLX_SWAP_INT_ARRAY(data, count ); 483 } 484 485 486 return( __glXForwardPipe0WithReply( cl, pc ) ); 487} 488 489int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) 490{ 491 xGLXSingleReq *req = (xGLXSingleReq *)pc; 492 __GLX_DECLARE_SWAP_VARIABLES; 493 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 494 495 __GLX_SWAP_SHORT(&req->length); 496 __GLX_SWAP_INT(&req->contextTag); 497 498 swap_vec_element_size = 8; 499 500 /* 501 * swap extra data in request - assuming all data 502 * (if available) are arrays of 4 bytes components ! 503 */ 504 if (req->length > sz_xGLXSingleReq/4) { 505 int *data = (int *)(req+1); 506 int count = req->length - sz_xGLXSingleReq/4; 507 __GLX_SWAP_INT_ARRAY(data, count ); 508 } 509 510 511 return( __glXForwardPipe0WithReply( cl, pc ) ); 512} 513 514int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc ) 515{ 516 xGLXSingleReq *req = (xGLXSingleReq *)pc; 517 __GLX_DECLARE_SWAP_VARIABLES; 518 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 519 520 __GLX_SWAP_SHORT(&req->length); 521 __GLX_SWAP_INT(&req->contextTag); 522 523 swap_vec_element_size = 0; 524 525 /* 526 * swap extra data in request - assuming all data 527 * (if available) are arrays of 4 bytes components ! 528 */ 529 if (req->length > sz_xGLXSingleReq/4) { 530 int *data = (int *)(req+1); 531 int count = req->length - sz_xGLXSingleReq/4; 532 __GLX_SWAP_INT_ARRAY(data, count ); 533 } 534 535 536 return( __glXForwardAllWithReply( cl, pc ) ); 537} 538 539int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc ) 540{ 541 xGLXSingleReq *req = (xGLXSingleReq *)pc; 542 __GLX_DECLARE_SWAP_VARIABLES; 543 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 544 545 __GLX_SWAP_SHORT(&req->length); 546 __GLX_SWAP_INT(&req->contextTag); 547 548 swap_vec_element_size = 2; 549 550 /* 551 * swap extra data in request - assuming all data 552 * (if available) are arrays of 4 bytes components ! 553 */ 554 if (req->length > sz_xGLXSingleReq/4) { 555 int *data = (int *)(req+1); 556 int count = req->length - sz_xGLXSingleReq/4; 557 __GLX_SWAP_INT_ARRAY(data, count ); 558 } 559 560 561 return( __glXForwardAllWithReply( cl, pc ) ); 562} 563 564int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc ) 565{ 566 xGLXSingleReq *req = (xGLXSingleReq *)pc; 567 __GLX_DECLARE_SWAP_VARIABLES; 568 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 569 570 __GLX_SWAP_SHORT(&req->length); 571 __GLX_SWAP_INT(&req->contextTag); 572 573 swap_vec_element_size = 4; 574 575 /* 576 * swap extra data in request - assuming all data 577 * (if available) are arrays of 4 bytes components ! 578 */ 579 if (req->length > sz_xGLXSingleReq/4) { 580 int *data = (int *)(req+1); 581 int count = req->length - sz_xGLXSingleReq/4; 582 __GLX_SWAP_INT_ARRAY(data, count ); 583 } 584 585 586 return( __glXForwardAllWithReply( cl, pc ) ); 587} 588 589int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc ) 590{ 591 xGLXSingleReq *req = (xGLXSingleReq *)pc; 592 __GLX_DECLARE_SWAP_VARIABLES; 593 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 594 595 __GLX_SWAP_SHORT(&req->length); 596 __GLX_SWAP_INT(&req->contextTag); 597 598 swap_vec_element_size = 8; 599 600 /* 601 * swap extra data in request - assuming all data 602 * (if available) are arrays of 4 bytes components ! 603 */ 604 if (req->length > sz_xGLXSingleReq/4) { 605 int *data = (int *)(req+1); 606 int count = req->length - sz_xGLXSingleReq/4; 607 __GLX_SWAP_INT_ARRAY(data, count ); 608 } 609 610 611 return( __glXForwardAllWithReply( cl, pc ) ); 612} 613 614static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h, 615 int *elementbits_return, int *rowbytes_return ) 616{ 617 GLint elements, esize; 618 GLint rowsize, padding; 619 620 if (w < 0 || h < 0) { 621 return -1; 622 } 623 switch (format) { 624 case GL_COLOR_INDEX: 625 case GL_STENCIL_INDEX: 626 case GL_DEPTH_COMPONENT: 627 elements = 1; 628 break; 629 case GL_RED: 630 case GL_GREEN: 631 case GL_BLUE: 632 case GL_ALPHA: 633 case GL_LUMINANCE: 634 elements = 1; 635 break; 636 case GL_LUMINANCE_ALPHA: 637 elements = 2; 638 break; 639 case GL_RGB: 640 case GL_BGR: 641 elements = 3; 642 break; 643 case GL_RGBA: 644 case GL_BGRA: 645 case GL_ABGR_EXT: 646 elements = 4; 647 break; 648 default: 649 return -1; 650 } 651 /* 652 ** According to the GLX protocol, each row must be padded to a multiple of 653 ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel 654 ** store modes of the GL. 655 */ 656 switch (type) { 657 case GL_BITMAP: 658 if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { 659 rowsize = ((w * elements)+7)/8; 660 padding = rowsize % 4; 661 if (padding) { 662 rowsize += 4 - padding; 663 } 664 if (elementbits_return) *elementbits_return = elements; 665 if (rowbytes_return) *rowbytes_return = rowsize; 666 return rowsize * h; 667 } else { 668 return -1; 669 } 670 case GL_BYTE: 671 case GL_UNSIGNED_BYTE: 672 esize = 1; 673 break; 674 case GL_UNSIGNED_BYTE_3_3_2: 675 case GL_UNSIGNED_BYTE_2_3_3_REV: 676 esize = 1; 677 elements = 1; 678 break; 679 case GL_SHORT: 680 case GL_UNSIGNED_SHORT: 681 esize = 2; 682 break; 683 case GL_UNSIGNED_SHORT_5_6_5: 684 case GL_UNSIGNED_SHORT_5_6_5_REV: 685 case GL_UNSIGNED_SHORT_4_4_4_4: 686 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 687 case GL_UNSIGNED_SHORT_5_5_5_1: 688 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 689 esize = 2; 690 elements = 1; 691 break; 692 case GL_INT: 693 case GL_UNSIGNED_INT: 694 case GL_FLOAT: 695 esize = 4; 696 break; 697 case GL_UNSIGNED_INT_8_8_8_8: 698 case GL_UNSIGNED_INT_8_8_8_8_REV: 699 case GL_UNSIGNED_INT_10_10_10_2: 700 case GL_UNSIGNED_INT_2_10_10_10_REV: 701 esize = 4; 702 elements = 1; 703 break; 704 default: 705 return -1; 706 } 707 rowsize = w * elements * esize; 708 padding = rowsize % 4; 709 if (padding) { 710 rowsize += 4 - padding; 711 } 712 713 if (elementbits_return) *elementbits_return = esize*elements*8; 714 if (rowbytes_return) *rowbytes_return = rowsize; 715 716 return rowsize * h; 717} 718 719static int intersectRect( int x1, int x2, int y1, int y2, 720 int X1, int X2, int Y1, int Y2, 721 int *ix1, int *ix2, int *iy1, int *iy2 ) 722{ 723 int right = (x2 < X2 ? x2 : X2); 724 int bottom = (y2 < Y2 ? y2 : Y2); 725 int left = (x1 > X1 ? x1 : X1); 726 int top = (y1 > Y1 ? y1 : Y1); 727 int width = right - left + 1; 728 int height = bottom - top + 1; 729 730 if ( (width <= 0) || (height <= 0) ) { 731 *ix1 = *ix2 = *iy1 = *iy2 = 0; 732 return 0; 733 } 734 else { 735 *ix1 = left; 736 *ix2 = right; 737 *iy1 = top; 738 *iy2 = bottom; 739 return width * height; 740 } 741 742} 743 744int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc) 745{ 746 xGLXSingleReq *req = (xGLXSingleReq *)pc; 747 xGLXSingleReq *be_req; 748 xGLXReadPixelsReply reply; 749 xGLXReadPixelsReply be_reply; 750 GLbyte *be_pc; 751 GLint x,y; 752 GLsizei width, height; 753 GLenum format, type; 754 GLboolean swapBytes, lsbFirst; 755 ClientPtr client = cl->client; 756 DrawablePtr pDraw; 757 __GLXcontext *glxc; 758 int from_screen = 0; 759 int to_screen = 0; 760 char *buf; 761 int buf_size; 762 int s; 763 int win_x1, win_x2; 764 int win_y1, win_y2; 765 int ebits, rowsize; 766 __GLX_DECLARE_SWAP_VARIABLES; 767 768 if (client->swapped) { 769 __GLX_SWAP_INT(&req->contextTag); 770 } 771 772 glxc = __glXLookupContextByTag(cl, req->contextTag); 773 if (!glxc) { 774 return 0; 775 } 776 from_screen = to_screen = glxc->pScreen->myNum; 777 778#ifdef PANORAMIX 779 if (!noPanoramiXExtension) { 780 from_screen = 0; 781 to_screen = screenInfo.numScreens - 1; 782 } 783#endif 784 785 pc += sz_xGLXSingleReq; 786 x = *(GLint *)(pc + 0); 787 y = *(GLint *)(pc + 4); 788 width = *(GLsizei *)(pc + 8); 789 height = *(GLsizei *)(pc + 12); 790 format = *(GLenum *)(pc + 16); 791 type = *(GLenum *)(pc + 20); 792 swapBytes = *(GLboolean *)(pc + 24); 793 lsbFirst = *(GLboolean *)(pc + 25); 794 795 if (client->swapped) { 796 __GLX_SWAP_INT(&x); 797 __GLX_SWAP_INT(&y); 798 __GLX_SWAP_INT(&width); 799 __GLX_SWAP_INT(&height); 800 __GLX_SWAP_INT(&format); 801 __GLX_SWAP_INT(&type); 802 swapBytes = !swapBytes; 803 } 804 805 buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize); 806 if (buf_size > 0) { 807 buf = (char *) malloc( buf_size ); 808 if ( !buf ) { 809 return BadAlloc; 810 } 811 } 812 else { 813 buf_size = 0; 814 buf = NULL; 815 } 816 817 if (buf_size > 0) { 818 /* 819 * Get the current drawable this context is bound to 820 */ 821 pDraw = __glXLookupDrawableByTag( cl, req->contextTag ); 822 win_x1 = pDraw->x + x; 823 win_x2 = win_x1 + width - 1; 824 win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y; 825 win_y2 = win_y1 + height - 1; 826 if (pDraw->type != DRAWABLE_WINDOW) { 827 from_screen = to_screen = 0; 828 } 829 830 for (s=from_screen; s<=to_screen; s++) { 831 DMXScreenInfo *dmxScreen = &dmxScreens[s]; 832 Display *dpy = GetBackEndDisplay(cl,s); 833 int scr_x1 = dmxScreen->rootXOrigin; 834 int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1; 835 int scr_y1 = dmxScreen->rootYOrigin; 836 int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1; 837 int wx1, wx2, wy1, wy2; 838 int sx, sy, sw, sh; 839 int npixels; 840 841 /* 842 * find the window portion that is on the current screen 843 */ 844 if (pDraw->type == DRAWABLE_WINDOW) { 845 npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2, 846 win_x1, win_x2, win_y1, win_y2, 847 &wx1, &wx2, &wy1, &wy2 ); 848 } 849 else { 850 wx1 = win_x1; 851 wx2 = win_x2; 852 wy1 = win_y1; 853 wy2 = win_y2; 854 npixels = (wx2-wx1+1) * (wy2-wy1+1); 855 } 856 857 if (npixels > 0) { 858 859 /* send the request to the back-end server */ 860 LockDisplay(dpy); 861 GetReqExtra(GLXSingle,__GLX_PAD(26),be_req); 862 be_req->reqType = dmxScreen->glxMajorOpcode; 863 be_req->glxCode = X_GLsop_ReadPixels; 864 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s); 865 be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq); 866 867 sx = wx1 - pDraw->x; 868 sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height); 869 sw = (wx2-wx1+1); 870 sh = (wy2-wy1+1); 871 872 *(GLint *)(be_pc + 0) = sx; /* x */ 873 *(GLint *)(be_pc + 4) = sy; /* y */ 874 *(GLsizei *)(be_pc + 8) = sw; /* width */ 875 *(GLsizei *)(be_pc + 12) = sh; /* height */ 876 *(GLenum *)(be_pc + 16) = format; 877 *(GLenum *)(be_pc + 20) = type; 878 *(GLboolean *)(be_pc + 24) = swapBytes; 879 *(GLboolean *)(be_pc + 25) = lsbFirst; 880 881 _XReply(dpy, (xReply*) &be_reply, 0, False); 882 883 if (be_reply.length > 0) { 884 char *be_buf; 885 int be_buf_size = be_reply.length << 2; 886 887 be_buf = (char *) malloc( be_buf_size ); 888 if (be_buf) { 889 _XRead(dpy, be_buf, be_buf_size); 890 891 /* copy pixels data to the right location of the */ 892 /* reply buffer */ 893 if ( type != GL_BITMAP ) { 894 int pbytes = ebits / 8; 895 char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes; 896 char *src = be_buf; 897 int pad = (pbytes * sw) % 4; 898 int r; 899 900 for (r=0; r<sh; r++) { 901 memcpy( dst, src, pbytes*sw ); 902 dst += rowsize; 903 src += (pbytes*sw + (pad ? 4-pad : 0) ); 904 } 905 } 906 else { 907 /* this is a GL_BITMAP pixel type, should copy bits */ 908 int r; 909 int src_rowsize = bits_to_bytes(sw * ebits); 910 int src_pad = src_rowsize % 4; 911 if ( src_pad ) { 912 src_rowsize += (4 - src_pad); 913 } 914 915 for (r=0; r<sh; r++) { 916 unsigned char dst_mask = 0x80 >> (sx % 8); 917 unsigned char src_mask = 0x80; 918 char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8; 919 char *src = be_buf + r*src_rowsize; 920 int b; 921 922 for (b=0; b<sw*ebits; b++) { 923 if ( *src & src_mask ) { 924 *dst |= dst_mask; 925 } 926 else { 927 *dst &= ~dst_mask; 928 } 929 930 if (dst_mask > 1) dst_mask >>= 1; 931 else { 932 dst_mask = 0x80; 933 dst++; 934 } 935 936 if (src_mask > 1) src_mask >>= 1; 937 else { 938 src_mask = 0x80; 939 src++; 940 } 941 } 942 } 943 944 } 945 946 free( be_buf ); 947 } 948 else { 949 /* Throw data on the floor */ 950 _XEatData(dpy, be_buf_size); 951 free( buf ); 952 return BadAlloc; 953 } 954 } 955 956 UnlockDisplay(dpy); 957 SyncHandle(); 958 959 } /* of npixels > 0 */ 960 961 } /* of for loop */ 962 963 } /* of if buf_size > 0 */ 964 965 reply.type = X_Reply; 966 reply.sequenceNumber = client->sequence; 967 reply.length = buf_size >> 2; 968 969 if (client->swapped) { 970 __GLX_SWAP_SHORT(&reply.sequenceNumber); 971 __GLX_SWAP_INT(&reply.length); 972 } 973 974 WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply); 975 if (buf_size > 0) { 976 WriteToClient(client, buf_size, (char *)buf); 977 free( buf ); 978 } 979 980 return Success; 981} 982 983int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc) 984{ 985 __GLX_DECLARE_SWAP_VARIABLES; 986 GLbyte *lpc = pc; 987 988 lpc += sz_xGLXSingleReq; 989 __GLX_SWAP_INT(lpc+0); 990 __GLX_SWAP_INT(lpc+4); 991 __GLX_SWAP_INT(lpc+8); 992 __GLX_SWAP_INT(lpc+12); 993 994 /* reverse swapBytes */ 995 *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16); 996 997 return( __glXForwardPipe0WithReplySwap( cl, pc ) ); 998} 999 1000int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc) 1001{ 1002 __GLX_DECLARE_SWAP_VARIABLES; 1003 GLbyte *lpc = pc; 1004 1005 lpc += sz_xGLXSingleReq; 1006 __GLX_SWAP_INT(lpc+0); 1007 __GLX_SWAP_INT(lpc+4); 1008 __GLX_SWAP_INT(lpc+8); 1009 1010 /* reverse swapBytes */ 1011 *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12); 1012 1013 return( __glXForwardPipe0WithReplySwap( cl, pc ) ); 1014} 1015 1016 1017