First import
[xorg_rtime.git] / xorg-server-1.4 / hw / dmx / glxProxy / glxsingle.c
blob27a27c3356863cb256f34daa5f9805ba8e911f8a
1 /* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
2 /*
3 ** License Applicability. Except to the extent portions of this file are
4 ** made subject to an alternative license as permitted in the SGI Free
5 ** Software License B, Version 1.1 (the "License"), the contents of this
6 ** file are subject only to the provisions of the License. You may not use
7 ** this file except in compliance with the License. You may obtain a copy
8 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 **
11 ** http://oss.sgi.com/projects/FreeB
12 **
13 ** Note that, as provided in the License, the Software is distributed on an
14 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 **
19 ** Original Code. The Original Code is: OpenGL Sample Implementation,
20 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22 ** Copyright in any portions created by third parties is as indicated
23 ** elsewhere herein. All Rights Reserved.
24 **
25 ** Additional Notice Provisions: This software was created using the
26 ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
27 ** not been independently verified as being compliant with the OpenGL(R)
28 ** version 1.2.1 Specification.
31 #ifdef HAVE_DMX_CONFIG_H
32 #include <dmx-config.h>
33 #endif
35 #include "dmx.h"
36 #include "dmxwindow.h"
37 #include "dmxpixmap.h"
38 #include "dmxfont.h"
39 #include "dmxcb.h"
41 #undef Xmalloc
42 #undef Xcalloc
43 #undef Xrealloc
44 #undef Xfree
46 #define NEED_REPLIES
47 #include "glxserver.h"
48 #include "glxext.h"
49 #include "g_disptab.h"
50 /* #include "g_disptab_EXT.h" */
51 #include "unpack.h"
52 #include "glxutil.h"
54 #include "GL/glxproto.h"
56 #ifdef PANORAMIX
57 #include "panoramiXsrv.h"
58 #endif
61 * GetReqSingle - this is the equivalent of GetReq macro
62 * from Xlibint.h but it does not set the reqType field (the opcode).
63 * this is because the GL single opcodes has different naming convension
64 * the other X opcodes (ie. X_GLsop_GetFloatv).
66 #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
67 #define GetReqSingle(name, req) \
68 WORD64ALIGN\
69 if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
70 _XFlush(dpy);\
71 req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
72 req->length = (SIZEOF(x##name##Req))>>2;\
73 dpy->bufptr += SIZEOF(x##name##Req);\
74 dpy->request++
76 #else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
77 #define GetReqSingle(name, req) \
78 WORD64ALIGN\
79 if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
80 _XFlush(dpy);\
81 req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
82 req->length = (SIZEOF(x/**/name/**/Req))>>2;\
83 dpy->bufptr += SIZEOF(x/**/name/**/Req);\
84 dpy->request++
85 #endif
87 #define X_GLXSingle 0 /* needed by GetReqExtra */
89 extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
90 extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
92 static int swap_vec_element_size = 0;
94 static void SendSwappedReply( ClientPtr client,
95 xGLXSingleReply *reply,
96 char *buf,
97 int buf_size )
99 __GLX_DECLARE_SWAP_VARIABLES;
100 __GLX_SWAP_SHORT(&reply->sequenceNumber);
101 __GLX_SWAP_INT(&reply->length);
102 __GLX_SWAP_INT(&reply->retval);
103 __GLX_SWAP_INT(&reply->size);
105 if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
107 * the reply has single component - need to swap pad3
109 if (swap_vec_element_size == 2) {
110 __GLX_SWAP_SHORT(&reply->pad3);
112 else if (swap_vec_element_size == 4) {
113 __GLX_SWAP_INT(&reply->pad3);
114 __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4
115 * i.e GetConvolutionFilter
118 else if (swap_vec_element_size == 8) {
119 __GLX_SWAP_DOUBLE(&reply->pad3);
122 else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
124 * the reply has vector of elements which needs to be swapped
126 int vsize = buf_size / swap_vec_element_size;
127 char *p = buf;
128 int i;
130 for (i=0; i<vsize; i++) {
131 if (swap_vec_element_size == 2) {
132 __GLX_SWAP_SHORT(p);
134 else if (swap_vec_element_size == 4) {
135 __GLX_SWAP_INT(p);
137 else if (swap_vec_element_size == 8) {
138 __GLX_SWAP_DOUBLE(p);
141 p += swap_vec_element_size;
145 * swap pad words as well - for case that some single reply uses
146 * them as well
148 __GLX_SWAP_INT(&reply->pad3);
149 __GLX_SWAP_INT(&reply->pad4);
150 __GLX_SWAP_INT(&reply->pad5);
151 __GLX_SWAP_INT(&reply->pad6);
155 WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply);
156 if (buf_size > 0)
157 WriteToClient(client, buf_size, (char *)buf);
161 int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
163 xGLXSingleReq *req = (xGLXSingleReq *)pc;
164 xGLXSingleReq *be_req;
165 __GLXcontext *glxc;
166 int from_screen = 0;
167 int to_screen = 0;
168 int buf_size;
169 int s;
171 glxc = __glXLookupContextByTag(cl, req->contextTag);
172 if (!glxc) {
173 return 0;
175 from_screen = to_screen = glxc->pScreen->myNum;
177 #ifdef PANORAMIX
178 if (!noPanoramiXExtension) {
179 from_screen = 0;
180 to_screen = screenInfo.numScreens - 1;
182 #endif
184 pc += sz_xGLXSingleReq;
185 buf_size = (req->length << 2) - sz_xGLXSingleReq;
188 * just forward the request to back-end server(s)
190 for (s=from_screen; s<=to_screen; s++) {
191 DMXScreenInfo *dmxScreen = &dmxScreens[s];
192 Display *dpy = GetBackEndDisplay(cl,s);
194 LockDisplay(dpy);
195 GetReqSingle(GLXSingle,be_req);
196 be_req->reqType = dmxScreen->glxMajorOpcode;
197 be_req->glxCode = req->glxCode;
198 be_req->length = req->length;
199 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
200 if (buf_size > 0)
201 _XSend(dpy, (const char *)pc, buf_size);
202 UnlockDisplay(dpy);
203 SyncHandle();
205 if (req->glxCode == X_GLsop_Flush) {
206 XFlush(dpy);
211 return Success;
214 int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
216 ClientPtr client = cl->client;
217 xGLXSingleReq *req = (xGLXSingleReq *)pc;
218 xGLXSingleReq *be_req;
219 xGLXSingleReply reply;
220 xGLXSingleReply be_reply;
221 __GLXcontext *glxc;
222 int buf_size;
223 char *be_buf;
224 int be_buf_size;
225 DMXScreenInfo *dmxScreen;
226 Display *dpy;
228 glxc = __glXLookupContextByTag(cl, req->contextTag);
229 if (!glxc) {
230 return __glXBadContext;
233 pc += sz_xGLXSingleReq;
234 buf_size = (req->length << 2) - sz_xGLXSingleReq;
236 dmxScreen = &dmxScreens[glxc->pScreen->myNum];
237 dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
240 * send the request to the first back-end server
242 LockDisplay(dpy);
243 GetReqSingle(GLXSingle,be_req);
244 be_req->reqType = dmxScreen->glxMajorOpcode;
245 be_req->glxCode = req->glxCode;
246 be_req->length = req->length;
247 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum);
248 if (buf_size > 0)
249 _XSend(dpy, (const char *)pc, buf_size);
252 * get the reply from the back-end server
254 _XReply(dpy, (xReply*) &be_reply, 0, False);
255 be_buf_size = be_reply.length << 2;
256 if (be_buf_size > 0) {
257 be_buf = (char *)Xalloc( be_buf_size );
258 if (be_buf) {
259 _XRead(dpy, be_buf, be_buf_size);
261 else {
262 /* Throw data on the floor */
263 _XEatData(dpy, be_buf_size);
264 return BadAlloc;
268 UnlockDisplay(dpy);
269 SyncHandle();
272 * send the reply to the client
274 reply.type = X_Reply;
275 reply.sequenceNumber = client->sequence;
276 reply.length = be_reply.length;
277 reply.retval = be_reply.retval;
278 reply.size = be_reply.size;
279 reply.pad3 = be_reply.pad3;
280 reply.pad4 = be_reply.pad4;
282 if (client->swapped) {
283 SendSwappedReply( client, &reply, be_buf, be_buf_size );
285 else {
286 WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
287 if (be_buf_size > 0)
288 WriteToClient(client, be_buf_size, (char *)be_buf);
291 if (be_buf_size > 0) Xfree(be_buf);
293 return Success;
296 int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
298 ClientPtr client = cl->client;
299 xGLXSingleReq *req = (xGLXSingleReq *)pc;
300 xGLXSingleReq *be_req;
301 xGLXSingleReply reply;
302 xGLXSingleReply be_reply;
303 __GLXcontext *glxc;
304 int buf_size;
305 char *be_buf;
306 int be_buf_size;
307 int from_screen = 0;
308 int to_screen = 0;
309 int s;
311 DMXScreenInfo *dmxScreen;
312 Display *dpy;
314 glxc = __glXLookupContextByTag(cl, req->contextTag);
315 if (!glxc) {
316 return 0;
318 from_screen = to_screen = glxc->pScreen->myNum;
320 #ifdef PANORAMIX
321 if (!noPanoramiXExtension) {
322 from_screen = 0;
323 to_screen = screenInfo.numScreens - 1;
325 #endif
327 pc += sz_xGLXSingleReq;
328 buf_size = (req->length << 2) - sz_xGLXSingleReq;
331 * send the request to the first back-end server(s)
333 for (s=to_screen; s>=from_screen; s--) {
334 dmxScreen = &dmxScreens[s];
335 dpy = GetBackEndDisplay(cl,s);
337 LockDisplay(dpy);
338 GetReqSingle(GLXSingle,be_req);
339 be_req->reqType = dmxScreen->glxMajorOpcode;
340 be_req->glxCode = req->glxCode;
341 be_req->length = req->length;
342 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
343 if (buf_size > 0)
344 _XSend(dpy, (const char *)pc, buf_size);
347 * get the reply from the back-end server
349 _XReply(dpy, (xReply*) &be_reply, 0, False);
350 be_buf_size = be_reply.length << 2;
351 if (be_buf_size > 0) {
352 be_buf = (char *)Xalloc( be_buf_size );
353 if (be_buf) {
354 _XRead(dpy, be_buf, be_buf_size);
356 else {
357 /* Throw data on the floor */
358 _XEatData(dpy, be_buf_size);
359 return BadAlloc;
363 UnlockDisplay(dpy);
364 SyncHandle();
366 if (s > from_screen && be_buf_size > 0) {
367 Xfree(be_buf);
372 * send the reply to the client
374 reply.type = X_Reply;
375 reply.sequenceNumber = client->sequence;
376 reply.length = be_reply.length;
377 reply.retval = be_reply.retval;
378 reply.size = be_reply.size;
379 reply.pad3 = be_reply.pad3;
380 reply.pad4 = be_reply.pad4;
382 if (client->swapped) {
383 SendSwappedReply( client, &reply, be_buf, be_buf_size );
385 else {
386 WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
387 if (be_buf_size > 0)
388 WriteToClient(client, be_buf_size, (char *)be_buf);
391 if (be_buf_size > 0) Xfree(be_buf);
393 return Success;
396 int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
398 xGLXSingleReq *req = (xGLXSingleReq *)pc;
399 __GLX_DECLARE_SWAP_VARIABLES;
401 __GLX_SWAP_SHORT(&req->length);
402 __GLX_SWAP_INT(&req->contextTag);
404 swap_vec_element_size = 0;
407 * swap extra data in request - assuming all data
408 * (if available) are arrays of 4 bytes components !
410 if (req->length > sz_xGLXSingleReq/4) {
411 int *data = (int *)(req+1);
412 int count = req->length - sz_xGLXSingleReq/4;
413 __GLX_SWAP_INT_ARRAY(data, count );
416 return( __glXForwardSingleReq( cl, pc ) );
419 int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
421 xGLXSingleReq *req = (xGLXSingleReq *)pc;
422 __GLX_DECLARE_SWAP_VARIABLES;
424 __GLX_SWAP_SHORT(&req->length);
425 __GLX_SWAP_INT(&req->contextTag);
427 swap_vec_element_size = 0;
430 * swap extra data in request - assuming all data
431 * (if available) are arrays of 4 bytes components !
433 if (req->length > sz_xGLXSingleReq/4) {
434 int *data = (int *)(req+1);
435 int count = req->length - sz_xGLXSingleReq/4;
436 __GLX_SWAP_INT_ARRAY(data, count );
439 return( __glXForwardPipe0WithReply( cl, pc ) );
442 int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
444 xGLXSingleReq *req = (xGLXSingleReq *)pc;
445 __GLX_DECLARE_SWAP_VARIABLES;
447 __GLX_SWAP_SHORT(&req->length);
448 __GLX_SWAP_INT(&req->contextTag);
450 swap_vec_element_size = 2;
453 * swap extra data in request - assuming all data
454 * (if available) are arrays of 4 bytes components !
456 if (req->length > sz_xGLXSingleReq/4) {
457 int *data = (int *)(req+1);
458 int count = req->length - sz_xGLXSingleReq/4;
459 __GLX_SWAP_INT_ARRAY(data, count );
463 return( __glXForwardPipe0WithReply( cl, pc ) );
466 int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
468 xGLXSingleReq *req = (xGLXSingleReq *)pc;
469 __GLX_DECLARE_SWAP_VARIABLES;
471 __GLX_SWAP_SHORT(&req->length);
472 __GLX_SWAP_INT(&req->contextTag);
474 swap_vec_element_size = 4;
477 * swap extra data in request - assuming all data
478 * (if available) are arrays of 4 bytes components !
480 if (req->length > sz_xGLXSingleReq/4) {
481 int *data = (int *)(req+1);
482 int count = req->length - sz_xGLXSingleReq/4;
483 __GLX_SWAP_INT_ARRAY(data, count );
487 return( __glXForwardPipe0WithReply( cl, pc ) );
490 int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
492 xGLXSingleReq *req = (xGLXSingleReq *)pc;
493 __GLX_DECLARE_SWAP_VARIABLES;
495 __GLX_SWAP_SHORT(&req->length);
496 __GLX_SWAP_INT(&req->contextTag);
498 swap_vec_element_size = 8;
501 * swap extra data in request - assuming all data
502 * (if available) are arrays of 4 bytes components !
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 );
511 return( __glXForwardPipe0WithReply( cl, pc ) );
514 int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
516 xGLXSingleReq *req = (xGLXSingleReq *)pc;
517 __GLX_DECLARE_SWAP_VARIABLES;
519 __GLX_SWAP_SHORT(&req->length);
520 __GLX_SWAP_INT(&req->contextTag);
522 swap_vec_element_size = 0;
525 * swap extra data in request - assuming all data
526 * (if available) are arrays of 4 bytes components !
528 if (req->length > sz_xGLXSingleReq/4) {
529 int *data = (int *)(req+1);
530 int count = req->length - sz_xGLXSingleReq/4;
531 __GLX_SWAP_INT_ARRAY(data, count );
535 return( __glXForwardAllWithReply( cl, pc ) );
538 int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
540 xGLXSingleReq *req = (xGLXSingleReq *)pc;
541 __GLX_DECLARE_SWAP_VARIABLES;
543 __GLX_SWAP_SHORT(&req->length);
544 __GLX_SWAP_INT(&req->contextTag);
546 swap_vec_element_size = 2;
549 * swap extra data in request - assuming all data
550 * (if available) are arrays of 4 bytes components !
552 if (req->length > sz_xGLXSingleReq/4) {
553 int *data = (int *)(req+1);
554 int count = req->length - sz_xGLXSingleReq/4;
555 __GLX_SWAP_INT_ARRAY(data, count );
559 return( __glXForwardAllWithReply( cl, pc ) );
562 int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
564 xGLXSingleReq *req = (xGLXSingleReq *)pc;
565 __GLX_DECLARE_SWAP_VARIABLES;
567 __GLX_SWAP_SHORT(&req->length);
568 __GLX_SWAP_INT(&req->contextTag);
570 swap_vec_element_size = 4;
573 * swap extra data in request - assuming all data
574 * (if available) are arrays of 4 bytes components !
576 if (req->length > sz_xGLXSingleReq/4) {
577 int *data = (int *)(req+1);
578 int count = req->length - sz_xGLXSingleReq/4;
579 __GLX_SWAP_INT_ARRAY(data, count );
583 return( __glXForwardAllWithReply( cl, pc ) );
586 int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
588 xGLXSingleReq *req = (xGLXSingleReq *)pc;
589 __GLX_DECLARE_SWAP_VARIABLES;
591 __GLX_SWAP_SHORT(&req->length);
592 __GLX_SWAP_INT(&req->contextTag);
594 swap_vec_element_size = 8;
597 * swap extra data in request - assuming all data
598 * (if available) are arrays of 4 bytes components !
600 if (req->length > sz_xGLXSingleReq/4) {
601 int *data = (int *)(req+1);
602 int count = req->length - sz_xGLXSingleReq/4;
603 __GLX_SWAP_INT_ARRAY(data, count );
607 return( __glXForwardAllWithReply( cl, pc ) );
610 static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h,
611 int *elementbits_return, int *rowbytes_return )
613 GLint elements, esize;
614 GLint rowsize, padding;
616 if (w < 0 || h < 0) {
617 return -1;
619 switch (format) {
620 case GL_COLOR_INDEX:
621 case GL_STENCIL_INDEX:
622 case GL_DEPTH_COMPONENT:
623 elements = 1;
624 break;
625 case GL_RED:
626 case GL_GREEN:
627 case GL_BLUE:
628 case GL_ALPHA:
629 case GL_LUMINANCE:
630 elements = 1;
631 break;
632 case GL_LUMINANCE_ALPHA:
633 elements = 2;
634 break;
635 case GL_RGB:
636 case GL_BGR:
637 elements = 3;
638 break;
639 case GL_RGBA:
640 case GL_BGRA:
641 case GL_ABGR_EXT:
642 elements = 4;
643 break;
644 default:
645 return -1;
648 ** According to the GLX protocol, each row must be padded to a multiple of
649 ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel
650 ** store modes of the GL.
652 switch (type) {
653 case GL_BITMAP:
654 if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
655 rowsize = ((w * elements)+7)/8;
656 padding = rowsize % 4;
657 if (padding) {
658 rowsize += 4 - padding;
660 if (elementbits_return) *elementbits_return = elements;
661 if (rowbytes_return) *rowbytes_return = rowsize;
662 return (rowsize * h);
663 } else {
664 return -1;
666 case GL_BYTE:
667 case GL_UNSIGNED_BYTE:
668 esize = 1;
669 break;
670 case GL_UNSIGNED_BYTE_3_3_2:
671 case GL_UNSIGNED_BYTE_2_3_3_REV:
672 esize = 1;
673 elements = 1;
674 break;
675 case GL_SHORT:
676 case GL_UNSIGNED_SHORT:
677 esize = 2;
678 break;
679 case GL_UNSIGNED_SHORT_5_6_5:
680 case GL_UNSIGNED_SHORT_5_6_5_REV:
681 case GL_UNSIGNED_SHORT_4_4_4_4:
682 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
683 case GL_UNSIGNED_SHORT_5_5_5_1:
684 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
685 esize = 2;
686 elements = 1;
687 break;
688 case GL_INT:
689 case GL_UNSIGNED_INT:
690 case GL_FLOAT:
691 esize = 4;
692 break;
693 case GL_UNSIGNED_INT_8_8_8_8:
694 case GL_UNSIGNED_INT_8_8_8_8_REV:
695 case GL_UNSIGNED_INT_10_10_10_2:
696 case GL_UNSIGNED_INT_2_10_10_10_REV:
697 esize = 4;
698 elements = 1;
699 break;
700 default:
701 return -1;
703 rowsize = w * elements * esize;
704 padding = rowsize % 4;
705 if (padding) {
706 rowsize += 4 - padding;
709 if (elementbits_return) *elementbits_return = esize*elements*8;
710 if (rowbytes_return) *rowbytes_return = rowsize;
712 return (rowsize * h);
715 static int intersectRect( int x1, int x2, int y1, int y2,
716 int X1, int X2, int Y1, int Y2,
717 int *ix1, int *ix2, int *iy1, int *iy2 )
719 int right = (x2 < X2 ? x2 : X2);
720 int bottom = (y2 < Y2 ? y2 : Y2);
721 int left = (x1 > X1 ? x1 : X1);
722 int top = (y1 > Y1 ? y1 : Y1);
723 int width = right - left + 1;
724 int height = bottom - top + 1;
726 if ( (width <= 0) || (height <= 0) ) {
727 *ix1 = *ix2 = *iy1 = *iy2 = 0;
728 return(0);
730 else {
731 *ix1 = left;
732 *ix2 = right;
733 *iy1 = top;
734 *iy2 = bottom;
735 return( width * height );
740 int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc)
742 xGLXSingleReq *req = (xGLXSingleReq *)pc;
743 xGLXSingleReq *be_req;
744 xGLXReadPixelsReply reply;
745 xGLXReadPixelsReply be_reply;
746 GLbyte *be_pc;
747 GLint x,y;
748 GLsizei width, height;
749 GLenum format, type;
750 GLboolean swapBytes, lsbFirst;
751 ClientPtr client = cl->client;
752 DrawablePtr pDraw;
753 int error;
754 __GLXcontext *glxc;
755 int from_screen = 0;
756 int to_screen = 0;
757 char *buf;
758 int buf_size;
759 int s;
760 int win_x1, win_x2;
761 int win_y1, win_y2;
762 int ebits, rowsize;
763 __GLX_DECLARE_SWAP_VARIABLES;
765 if (client->swapped) {
766 __GLX_SWAP_INT(&req->contextTag);
769 glxc = __glXLookupContextByTag(cl, req->contextTag);
770 if (!glxc) {
771 return 0;
773 from_screen = to_screen = glxc->pScreen->myNum;
775 #ifdef PANORAMIX
776 if (!noPanoramiXExtension) {
777 from_screen = 0;
778 to_screen = screenInfo.numScreens - 1;
780 #endif
782 pc += sz_xGLXSingleReq;
783 x = *(GLint *)(pc + 0);
784 y = *(GLint *)(pc + 4);
785 width = *(GLsizei *)(pc + 8);
786 height = *(GLsizei *)(pc + 12);
787 format = *(GLenum *)(pc + 16);
788 type = *(GLenum *)(pc + 20);
789 swapBytes = *(GLboolean *)(pc + 24);
790 lsbFirst = *(GLboolean *)(pc + 25);
792 if (client->swapped) {
793 __GLX_SWAP_INT(&x);
794 __GLX_SWAP_INT(&y);
795 __GLX_SWAP_INT(&width);
796 __GLX_SWAP_INT(&height);
797 __GLX_SWAP_INT(&format);
798 __GLX_SWAP_INT(&type);
799 swapBytes = !swapBytes;
802 buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize);
803 if (buf_size > 0) {
804 buf = (char *) Xalloc( buf_size );
805 if ( !buf ) {
806 return( BadAlloc );
809 else {
810 buf_size = 0;
813 if (buf_size > 0) {
815 * Get the current drawable this context is bound to
817 pDraw = __glXLookupDrawableByTag( cl, req->contextTag );
818 win_x1 = pDraw->x + x;
819 win_x2 = win_x1 + width - 1;
820 win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y;
821 win_y2 = win_y1 + height - 1;
822 if (pDraw->type != DRAWABLE_WINDOW) {
823 from_screen = to_screen = 0;
826 for (s=from_screen; s<=to_screen; s++) {
827 DMXScreenInfo *dmxScreen = &dmxScreens[s];
828 Display *dpy = GetBackEndDisplay(cl,s);
829 int scr_x1 = dmxScreen->rootXOrigin;
830 int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1;
831 int scr_y1 = dmxScreen->rootYOrigin;
832 int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1;
833 int wx1, wx2, wy1, wy2;
834 int sx, sy, sw, sh;
835 int npixels;
838 * find the window portion that is on the current screen
840 if (pDraw->type == DRAWABLE_WINDOW) {
841 npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2,
842 win_x1, win_x2, win_y1, win_y2,
843 &wx1, &wx2, &wy1, &wy2 );
845 else {
846 wx1 = win_x1;
847 wx2 = win_x2;
848 wy1 = win_y1;
849 wy2 = win_y2;
850 npixels = (wx2-wx1+1) * (wy2-wy1+1);
853 if (npixels > 0) {
855 /* send the request to the back-end server */
856 LockDisplay(dpy);
857 GetReqExtra(GLXSingle,__GLX_PAD(26),be_req);
858 be_req->reqType = dmxScreen->glxMajorOpcode;
859 be_req->glxCode = X_GLsop_ReadPixels;
860 be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
861 be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq);
863 sx = wx1 - pDraw->x;
864 sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height);
865 sw = (wx2-wx1+1);
866 sh = (wy2-wy1+1);
868 *(GLint *)(be_pc + 0) = sx; /* x */
869 *(GLint *)(be_pc + 4) = sy; /* y */
870 *(GLsizei *)(be_pc + 8) = sw; /* width */
871 *(GLsizei *)(be_pc + 12) = sh; /* height */
872 *(GLenum *)(be_pc + 16) = format;
873 *(GLenum *)(be_pc + 20) = type;
874 *(GLboolean *)(be_pc + 24) = swapBytes;
875 *(GLboolean *)(be_pc + 25) = lsbFirst;
877 _XReply(dpy, (xReply*) &be_reply, 0, False);
879 if (be_reply.length > 0) {
880 char *be_buf;
881 int be_buf_size = be_reply.length << 2;
883 be_buf = (char *) Xalloc( be_buf_size );
884 if (be_buf) {
885 _XRead(dpy, be_buf, be_buf_size);
887 /* copy pixels data to the right location of the */
888 /* reply buffer */
889 if ( type != GL_BITMAP ) {
890 int pbytes = ebits / 8;
891 char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes;
892 char *src = be_buf;
893 int pad = (pbytes * sw) % 4;
894 int r;
896 for (r=0; r<sh; r++) {
897 memcpy( dst, src, pbytes*sw );
898 dst += rowsize;
899 src += (pbytes*sw + (pad ? 4-pad : 0) );
902 else {
903 /* this is a GL_BITMAP pixel type, should copy bits */
904 int r;
905 int src_rowsize = ((sw * ebits) + 7) / 8;
906 int src_pad = src_rowsize % 4;
907 if ( src_pad ) {
908 src_rowsize += (4 - src_pad);
911 for (r=0; r<sh; r++) {
912 unsigned char dst_mask = 0x80 >> (sx % 8);
913 unsigned char src_mask = 0x80;
914 char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8;
915 char *src = be_buf + r*src_rowsize;
916 int b;
918 for (b=0; b<sw*ebits; b++) {
919 if ( *src & src_mask ) {
920 *dst |= dst_mask;
922 else {
923 *dst &= ~dst_mask;
926 if (dst_mask > 1) dst_mask >>= 1;
927 else {
928 dst_mask = 0x80;
929 dst++;
932 if (src_mask > 1) src_mask >>= 1;
933 else {
934 src_mask = 0x80;
935 src++;
942 Xfree( be_buf );
944 else {
945 /* Throw data on the floor */
946 _XEatData(dpy, be_buf_size);
947 Xfree( buf );
948 return BadAlloc;
952 UnlockDisplay(dpy);
953 SyncHandle();
955 } /* of npixels > 0 */
957 } /* of for loop */
959 } /* of if buf_size > 0 */
961 reply.type = X_Reply;
962 reply.sequenceNumber = client->sequence;
963 reply.length = buf_size >> 2;
965 if (client->swapped) {
966 __GLX_SWAP_SHORT(&reply.sequenceNumber);
967 __GLX_SWAP_INT(&reply.length);
970 WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply);
971 if (buf_size > 0) {
972 WriteToClient(client, buf_size, (char *)buf);
973 Xfree( buf );
976 return Success;
979 int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc)
981 __GLX_DECLARE_SWAP_VARIABLES;
982 GLbyte *lpc = pc;
984 lpc += sz_xGLXSingleReq;
985 __GLX_SWAP_INT(lpc+0);
986 __GLX_SWAP_INT(lpc+4);
987 __GLX_SWAP_INT(lpc+8);
988 __GLX_SWAP_INT(lpc+12);
990 /* reverse swapBytes */
991 *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16);
993 return( __glXForwardPipe0WithReplySwap( cl, pc ) );
996 int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc)
998 __GLX_DECLARE_SWAP_VARIABLES;
999 GLbyte *lpc = pc;
1001 lpc += sz_xGLXSingleReq;
1002 __GLX_SWAP_INT(lpc+0);
1003 __GLX_SWAP_INT(lpc+4);
1004 __GLX_SWAP_INT(lpc+8);
1006 /* reverse swapBytes */
1007 *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12);
1009 return( __glXForwardPipe0WithReplySwap( cl, pc ) );