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