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