Imported Upstream version 1.15.1
[deb_xorg-server.git] / glx / singlepixswap.c
CommitLineData
a09e091a
JB
1/*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
29 */
30
31#ifdef HAVE_DIX_CONFIG_H
32#include <dix-config.h>
33#endif
34
35#include "glxserver.h"
36#include "glxext.h"
37#include "singlesize.h"
38#include "unpack.h"
39#include "indirect_dispatch.h"
40#include "indirect_size_get.h"
41
42int
43__glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc)
44{
45 GLsizei width, height;
46 GLenum format, type;
47 GLboolean swapBytes, lsbFirst;
48 GLint compsize;
49
50 __GLX_DECLARE_SWAP_VARIABLES;
51 __GLXcontext *cx;
52 ClientPtr client = cl->client;
53 int error;
54 char *answer, answerBuffer[200];
55
56 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
57 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
58 if (!cx) {
59 return error;
60 }
61
62 pc += __GLX_SINGLE_HDR_SIZE;
63 __GLX_SWAP_INT(pc + 0);
64 __GLX_SWAP_INT(pc + 4);
65 __GLX_SWAP_INT(pc + 8);
66 __GLX_SWAP_INT(pc + 12);
67 __GLX_SWAP_INT(pc + 16);
68 __GLX_SWAP_INT(pc + 20);
69
70 width = *(GLsizei *) (pc + 8);
71 height = *(GLsizei *) (pc + 12);
72 format = *(GLenum *) (pc + 16);
73 type = *(GLenum *) (pc + 20);
74 swapBytes = *(GLboolean *) (pc + 24);
75 lsbFirst = *(GLboolean *) (pc + 25);
76 compsize = __glReadPixels_size(format, type, width, height);
77 if (compsize < 0)
78 compsize = 0;
79
80 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
81 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
82 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
83 __glXClearErrorOccured();
84 glReadPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4),
85 *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12),
86 *(GLenum *) (pc + 16), *(GLenum *) (pc + 20), answer);
87
88 if (__glXErrorOccured()) {
89 __GLX_BEGIN_REPLY(0);
90 __GLX_SWAP_REPLY_HEADER();
91 __GLX_SEND_HEADER();
92 }
93 else {
94 __GLX_BEGIN_REPLY(compsize);
95 __GLX_SWAP_REPLY_HEADER();
96 __GLX_SEND_HEADER();
97 __GLX_SEND_VOID_ARRAY(compsize);
98 }
99 cx->hasUnflushedCommands = GL_FALSE;
100 return Success;
101}
102
103int
104__glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc)
105{
106 GLint level, compsize;
107 GLenum format, type, target;
108 GLboolean swapBytes;
109
110 __GLX_DECLARE_SWAP_VARIABLES;
111 __GLXcontext *cx;
112 ClientPtr client = cl->client;
113 int error;
114 char *answer, answerBuffer[200];
115 GLint width = 0, height = 0, depth = 1;
116
117 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
118 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
119 if (!cx) {
120 return error;
121 }
122
123 pc += __GLX_SINGLE_HDR_SIZE;
124 __GLX_SWAP_INT(pc + 0);
125 __GLX_SWAP_INT(pc + 4);
126 __GLX_SWAP_INT(pc + 8);
127 __GLX_SWAP_INT(pc + 12);
128
129 level = *(GLint *) (pc + 4);
130 format = *(GLenum *) (pc + 8);
131 type = *(GLenum *) (pc + 12);
132 target = *(GLenum *) (pc + 0);
133 swapBytes = *(GLboolean *) (pc + 16);
134
135 glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
136 glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
137 if (target == GL_TEXTURE_3D) {
138 glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
139 }
140 /*
141 * The three queries above might fail if we're in a state where queries
142 * are illegal, but then width, height, and depth would still be zero anyway.
143 */
144 compsize =
145 __glGetTexImage_size(target, level, format, type, width, height, depth);
146 if (compsize < 0)
147 compsize = 0;
148
149 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
150 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
151 __glXClearErrorOccured();
152 glGetTexImage(*(GLenum *) (pc + 0), *(GLint *) (pc + 4),
153 *(GLenum *) (pc + 8), *(GLenum *) (pc + 12), answer);
154
155 if (__glXErrorOccured()) {
156 __GLX_BEGIN_REPLY(0);
157 __GLX_SWAP_REPLY_HEADER();
158 __GLX_SEND_HEADER();
159 }
160 else {
161 __GLX_BEGIN_REPLY(compsize);
162 __GLX_SWAP_REPLY_HEADER();
163 __GLX_SWAP_INT(&width);
164 __GLX_SWAP_INT(&height);
165 __GLX_SWAP_INT(&depth);
166 ((xGLXGetTexImageReply *) &__glXReply)->width = width;
167 ((xGLXGetTexImageReply *) &__glXReply)->height = height;
168 ((xGLXGetTexImageReply *) &__glXReply)->depth = depth;
169 __GLX_SEND_HEADER();
170 __GLX_SEND_VOID_ARRAY(compsize);
171 }
172 return Success;
173}
174
175int
176__glXDispSwap_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
177{
178 GLboolean lsbFirst;
179 __GLXcontext *cx;
180 ClientPtr client = cl->client;
181 int error;
182 GLubyte answerBuffer[200];
183 char *answer;
184
185 __GLX_DECLARE_SWAP_VARIABLES;
186
187 __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag);
188 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
189 if (!cx) {
190 return error;
191 }
192 pc += __GLX_SINGLE_HDR_SIZE;
193 lsbFirst = *(GLboolean *) (pc + 0);
194
195 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
196 __GLX_GET_ANSWER_BUFFER(answer, cl, 128, 1);
197
198 __glXClearErrorOccured();
199 glGetPolygonStipple((GLubyte *) answer);
200 if (__glXErrorOccured()) {
201 __GLX_BEGIN_REPLY(0);
202 __GLX_SWAP_REPLY_HEADER();
203 __GLX_SEND_HEADER();
204 }
205 else {
206 __GLX_BEGIN_REPLY(128);
207 __GLX_SWAP_REPLY_HEADER();
208 __GLX_SEND_HEADER();
209 __GLX_SEND_BYTE_ARRAY(128);
210 }
211 return Success;
212}
213
214static int
215GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
216{
217 GLint compsize, compsize2;
218 GLenum format, type, target;
219 GLboolean swapBytes;
220 __GLXcontext *cx;
221 ClientPtr client = cl->client;
222 int error;
223
224 __GLX_DECLARE_SWAP_VARIABLES;
225 char *answer, answerBuffer[200];
226 GLint width = 0, height = 0;
227
228 cx = __glXForceCurrent(cl, tag, &error);
229 if (!cx) {
230 return error;
231 }
232
233 __GLX_SWAP_INT(pc + 0);
234 __GLX_SWAP_INT(pc + 4);
235 __GLX_SWAP_INT(pc + 8);
236
237 format = *(GLenum *) (pc + 4);
238 type = *(GLenum *) (pc + 8);
239 target = *(GLenum *) (pc + 0);
240 swapBytes = *(GLboolean *) (pc + 12);
241
242 /* target must be SEPARABLE_2D, however I guess we can let the GL
243 barf on this one.... */
244
245 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
246 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
247 /*
248 * The two queries above might fail if we're in a state where queries
249 * are illegal, but then width and height would still be zero anyway.
250 */
251 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
252 compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
253
254 if (compsize < 0)
255 compsize = 0;
256 if (compsize2 < 0)
257 compsize2 = 0;
258 compsize = __GLX_PAD(compsize);
259 compsize2 = __GLX_PAD(compsize2);
260
261 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
262 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1);
263 __glXClearErrorOccured();
264 glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
265 *(GLenum *) (pc + 8), answer, answer + compsize, NULL);
266
267 if (__glXErrorOccured()) {
268 __GLX_BEGIN_REPLY(0);
269 __GLX_SWAP_REPLY_HEADER();
270 }
271 else {
272 __GLX_BEGIN_REPLY(compsize + compsize2);
273 __GLX_SWAP_REPLY_HEADER();
274 __GLX_SWAP_INT(&width);
275 __GLX_SWAP_INT(&height);
276 ((xGLXGetSeparableFilterReply *) &__glXReply)->width = width;
277 ((xGLXGetSeparableFilterReply *) &__glXReply)->height = height;
278 __GLX_SEND_VOID_ARRAY(compsize + compsize2);
279 }
280
281 return Success;
282}
283
284int
285__glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
286{
287 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
288
289 return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
290}
291
292int
293__glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
294{
295 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
296
297 return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
298}
299
300static int
301GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
302{
303 GLint compsize;
304 GLenum format, type, target;
305 GLboolean swapBytes;
306 __GLXcontext *cx;
307 ClientPtr client = cl->client;
308 int error;
309
310 __GLX_DECLARE_SWAP_VARIABLES;
311 char *answer, answerBuffer[200];
312 GLint width = 0, height = 0;
313
314 cx = __glXForceCurrent(cl, tag, &error);
315 if (!cx) {
316 return error;
317 }
318
319 __GLX_SWAP_INT(pc + 0);
320 __GLX_SWAP_INT(pc + 4);
321 __GLX_SWAP_INT(pc + 8);
322
323 format = *(GLenum *) (pc + 4);
324 type = *(GLenum *) (pc + 8);
325 target = *(GLenum *) (pc + 0);
326 swapBytes = *(GLboolean *) (pc + 12);
327
328 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
329 if (target == GL_CONVOLUTION_2D) {
330 height = 1;
331 }
332 else {
333 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
334 }
335 /*
336 * The two queries above might fail if we're in a state where queries
337 * are illegal, but then width and height would still be zero anyway.
338 */
339 compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
340 if (compsize < 0)
341 compsize = 0;
342
343 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
344 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
345 __glXClearErrorOccured();
346 glGetConvolutionFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
347 *(GLenum *) (pc + 8), answer);
348
349 if (__glXErrorOccured()) {
350 __GLX_BEGIN_REPLY(0);
351 __GLX_SWAP_REPLY_HEADER();
352 }
353 else {
354 __GLX_BEGIN_REPLY(compsize);
355 __GLX_SWAP_REPLY_HEADER();
356 __GLX_SWAP_INT(&width);
357 __GLX_SWAP_INT(&height);
358 ((xGLXGetConvolutionFilterReply *) &__glXReply)->width = width;
359 ((xGLXGetConvolutionFilterReply *) &__glXReply)->height = height;
360 __GLX_SEND_VOID_ARRAY(compsize);
361 }
362
363 return Success;
364}
365
366int
367__glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
368{
369 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
370
371 return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
372}
373
374int
375__glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
376{
377 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
378
379 return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
380}
381
382static int
383GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
384{
385 GLint compsize;
386 GLenum format, type, target;
387 GLboolean swapBytes, reset;
388 __GLXcontext *cx;
389 ClientPtr client = cl->client;
390 int error;
391
392 __GLX_DECLARE_SWAP_VARIABLES;
393 char *answer, answerBuffer[200];
394 GLint width = 0;
395
396 cx = __glXForceCurrent(cl, tag, &error);
397 if (!cx) {
398 return error;
399 }
400
401 __GLX_SWAP_INT(pc + 0);
402 __GLX_SWAP_INT(pc + 4);
403 __GLX_SWAP_INT(pc + 8);
404
405 format = *(GLenum *) (pc + 4);
406 type = *(GLenum *) (pc + 8);
407 target = *(GLenum *) (pc + 0);
408 swapBytes = *(GLboolean *) (pc + 12);
409 reset = *(GLboolean *) (pc + 13);
410
411 glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width);
412 /*
413 * The one query above might fail if we're in a state where queries
414 * are illegal, but then width would still be zero anyway.
415 */
416 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
417 if (compsize < 0)
418 compsize = 0;
419
420 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
421 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
422 __glXClearErrorOccured();
423 glGetHistogram(target, reset, format, type, answer);
424
425 if (__glXErrorOccured()) {
426 __GLX_BEGIN_REPLY(0);
427 __GLX_SWAP_REPLY_HEADER();
428 }
429 else {
430 __GLX_BEGIN_REPLY(compsize);
431 __GLX_SWAP_REPLY_HEADER();
432 __GLX_SWAP_INT(&width);
433 ((xGLXGetHistogramReply *) &__glXReply)->width = width;
434 __GLX_SEND_VOID_ARRAY(compsize);
435 }
436
437 return Success;
438}
439
440int
441__glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc)
442{
443 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
444
445 return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
446}
447
448int
449__glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
450{
451 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
452
453 return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
454}
455
456static int
457GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
458{
459 GLint compsize;
460 GLenum format, type, target;
461 GLboolean swapBytes, reset;
462 __GLXcontext *cx;
463 ClientPtr client = cl->client;
464 int error;
465
466 __GLX_DECLARE_SWAP_VARIABLES;
467 char *answer, answerBuffer[200];
468
469 cx = __glXForceCurrent(cl, tag, &error);
470 if (!cx) {
471 return error;
472 }
473
474 __GLX_SWAP_INT(pc + 0);
475 __GLX_SWAP_INT(pc + 4);
476 __GLX_SWAP_INT(pc + 8);
477
478 format = *(GLenum *) (pc + 4);
479 type = *(GLenum *) (pc + 8);
480 target = *(GLenum *) (pc + 0);
481 swapBytes = *(GLboolean *) (pc + 12);
482 reset = *(GLboolean *) (pc + 13);
483
484 compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
485 if (compsize < 0)
486 compsize = 0;
487
488 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
489 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
490 __glXClearErrorOccured();
491 glGetMinmax(target, reset, format, type, answer);
492
493 if (__glXErrorOccured()) {
494 __GLX_BEGIN_REPLY(0);
495 __GLX_SWAP_REPLY_HEADER();
496 }
497 else {
498 __GLX_BEGIN_REPLY(compsize);
499 __GLX_SWAP_REPLY_HEADER();
500 __GLX_SEND_VOID_ARRAY(compsize);
501 }
502
503 return Success;
504}
505
506int
507__glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc)
508{
509 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
510
511 return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
512}
513
514int
515__glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
516{
517 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
518
519 return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
520}
521
522static int
523GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
524{
525 GLint compsize;
526 GLenum format, type, target;
527 GLboolean swapBytes;
528 __GLXcontext *cx;
529 ClientPtr client = cl->client;
530 int error;
531
532 __GLX_DECLARE_SWAP_VARIABLES;
533 char *answer, answerBuffer[200];
534 GLint width = 0;
535
536 cx = __glXForceCurrent(cl, tag, &error);
537 if (!cx) {
538 return error;
539 }
540
541 __GLX_SWAP_INT(pc + 0);
542 __GLX_SWAP_INT(pc + 4);
543 __GLX_SWAP_INT(pc + 8);
544
545 format = *(GLenum *) (pc + 4);
546 type = *(GLenum *) (pc + 8);
547 target = *(GLenum *) (pc + 0);
548 swapBytes = *(GLboolean *) (pc + 12);
549
550 glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width);
551 /*
552 * The one query above might fail if we're in a state where queries
553 * are illegal, but then width would still be zero anyway.
554 */
555 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
556 if (compsize < 0)
557 compsize = 0;
558
559 glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
560 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
561 __glXClearErrorOccured();
562 glGetColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
563 *(GLenum *) (pc + 8), answer);
564
565 if (__glXErrorOccured()) {
566 __GLX_BEGIN_REPLY(0);
567 __GLX_SWAP_REPLY_HEADER();
568 }
569 else {
570 __GLX_BEGIN_REPLY(compsize);
571 __GLX_SWAP_REPLY_HEADER();
572 __GLX_SWAP_INT(&width);
573 ((xGLXGetColorTableReply *) &__glXReply)->width = width;
574 __GLX_SEND_VOID_ARRAY(compsize);
575 }
576
577 return Success;
578}
579
580int
581__glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc)
582{
583 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
584
585 return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
586}
587
588int
589__glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
590{
591 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
592
593 return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
594}