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