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