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_size_get.h"
40 #include "indirect_dispatch.h"
41
42 int
__glXDisp_ReadPixels(__GLXclientState * cl,GLbyte * pc)43 __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc)
44 {
45 GLsizei width, height;
46 GLenum format, type;
47 GLboolean swapBytes, lsbFirst;
48 GLint compsize;
49 __GLXcontext *cx;
50 ClientPtr client = cl->client;
51 int error;
52 char *answer, answerBuffer[200];
53 xGLXSingleReply reply = { 0, };
54
55 REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
56
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 width = *(GLsizei *) (pc + 8);
64 height = *(GLsizei *) (pc + 12);
65 format = *(GLenum *) (pc + 16);
66 type = *(GLenum *) (pc + 20);
67 swapBytes = *(GLboolean *) (pc + 24);
68 lsbFirst = *(GLboolean *) (pc + 25);
69 compsize = __glReadPixels_size(format, type, width, height);
70 if (compsize < 0)
71 return BadLength;
72
73 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
74 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
75 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
76 __glXClearErrorOccured();
77 glReadPixels(*(GLint *) (pc + 0), *(GLint *) (pc + 4),
78 *(GLsizei *) (pc + 8), *(GLsizei *) (pc + 12),
79 *(GLenum *) (pc + 16), *(GLenum *) (pc + 20), answer);
80
81 if (__glXErrorOccured()) {
82 __GLX_BEGIN_REPLY(0);
83 __GLX_SEND_HEADER();
84 }
85 else {
86 __GLX_BEGIN_REPLY(compsize);
87 __GLX_SEND_HEADER();
88 __GLX_SEND_VOID_ARRAY(compsize);
89 }
90 return Success;
91 }
92
93 int
__glXDisp_GetTexImage(__GLXclientState * cl,GLbyte * pc)94 __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc)
95 {
96 GLint level, compsize;
97 GLenum format, type, target;
98 GLboolean swapBytes;
99 __GLXcontext *cx;
100 ClientPtr client = cl->client;
101 int error;
102 char *answer, answerBuffer[200];
103 GLint width = 0, height = 0, depth = 1;
104 xGLXSingleReply reply = { 0, };
105
106 REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
107
108 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
109 if (!cx) {
110 return error;
111 }
112
113 pc += __GLX_SINGLE_HDR_SIZE;
114 level = *(GLint *) (pc + 4);
115 format = *(GLenum *) (pc + 8);
116 type = *(GLenum *) (pc + 12);
117 target = *(GLenum *) (pc + 0);
118 swapBytes = *(GLboolean *) (pc + 16);
119
120 glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
121 glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
122 if (target == GL_TEXTURE_3D) {
123 glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
124 }
125 /*
126 * The three queries above might fail if we're in a state where queries
127 * are illegal, but then width, height, and depth would still be zero anyway.
128 */
129 compsize =
130 __glGetTexImage_size(target, level, format, type, width, height, depth);
131 if (compsize < 0)
132 return BadLength;
133
134 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
135 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
136 __glXClearErrorOccured();
137 glGetTexImage(*(GLenum *) (pc + 0), *(GLint *) (pc + 4),
138 *(GLenum *) (pc + 8), *(GLenum *) (pc + 12), answer);
139
140 if (__glXErrorOccured()) {
141 __GLX_BEGIN_REPLY(0);
142 __GLX_SEND_HEADER();
143 }
144 else {
145 __GLX_BEGIN_REPLY(compsize);
146 ((xGLXGetTexImageReply *) &reply)->width = width;
147 ((xGLXGetTexImageReply *) &reply)->height = height;
148 ((xGLXGetTexImageReply *) &reply)->depth = depth;
149 __GLX_SEND_HEADER();
150 __GLX_SEND_VOID_ARRAY(compsize);
151 }
152 return Success;
153 }
154
155 int
__glXDisp_GetPolygonStipple(__GLXclientState * cl,GLbyte * pc)156 __glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc)
157 {
158 GLboolean lsbFirst;
159 __GLXcontext *cx;
160 ClientPtr client = cl->client;
161 int error;
162 GLubyte answerBuffer[200];
163 char *answer;
164 xGLXSingleReply reply = { 0, };
165
166 REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
167
168 cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
169 if (!cx) {
170 return error;
171 }
172
173 pc += __GLX_SINGLE_HDR_SIZE;
174 lsbFirst = *(GLboolean *) (pc + 0);
175
176 glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
177 __GLX_GET_ANSWER_BUFFER(answer, cl, 128, 1);
178
179 __glXClearErrorOccured();
180 glGetPolygonStipple((GLubyte *) answer);
181
182 if (__glXErrorOccured()) {
183 __GLX_BEGIN_REPLY(0);
184 __GLX_SEND_HEADER();
185 }
186 else {
187 __GLX_BEGIN_REPLY(128);
188 __GLX_SEND_HEADER();
189 __GLX_SEND_BYTE_ARRAY(128);
190 }
191 return Success;
192 }
193
194 static int
GetSeparableFilter(__GLXclientState * cl,GLbyte * pc,GLXContextTag tag)195 GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
196 {
197 GLint compsize, compsize2;
198 GLenum format, type, target;
199 GLboolean swapBytes;
200 __GLXcontext *cx;
201 ClientPtr client = cl->client;
202 int error;
203 char *answer, answerBuffer[200];
204 GLint width = 0, height = 0;
205 xGLXSingleReply reply = { 0, };
206
207 cx = __glXForceCurrent(cl, tag, &error);
208 if (!cx) {
209 return error;
210 }
211
212 format = *(GLenum *) (pc + 4);
213 type = *(GLenum *) (pc + 8);
214 target = *(GLenum *) (pc + 0);
215 swapBytes = *(GLboolean *) (pc + 12);
216
217 /* target must be SEPARABLE_2D, however I guess we can let the GL
218 barf on this one.... */
219
220 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
221 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
222 /*
223 * The two queries above might fail if we're in a state where queries
224 * are illegal, but then width and height would still be zero anyway.
225 */
226 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
227 compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1);
228
229 if ((compsize = safe_pad(compsize)) < 0)
230 return BadLength;
231 if ((compsize2 = safe_pad(compsize2)) < 0)
232 return BadLength;
233
234 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
235 __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1);
236 __glXClearErrorOccured();
237 glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
238 *(GLenum *) (pc + 8), answer, answer + compsize, NULL);
239
240 if (__glXErrorOccured()) {
241 __GLX_BEGIN_REPLY(0);
242 __GLX_SEND_HEADER();
243 }
244 else {
245 __GLX_BEGIN_REPLY(compsize + compsize2);
246 ((xGLXGetSeparableFilterReply *) &reply)->width = width;
247 ((xGLXGetSeparableFilterReply *) &reply)->height = height;
248 __GLX_SEND_HEADER();
249 __GLX_SEND_VOID_ARRAY(compsize + compsize2);
250 }
251
252 return Success;
253 }
254
255 int
__glXDisp_GetSeparableFilter(__GLXclientState * cl,GLbyte * pc)256 __glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc)
257 {
258 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
259 ClientPtr client = cl->client;
260 REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
261 return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
262 }
263
264 int
__glXDisp_GetSeparableFilterEXT(__GLXclientState * cl,GLbyte * pc)265 __glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc)
266 {
267 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
268 ClientPtr client = cl->client;
269 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
270 return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
271 }
272
273 static int
GetConvolutionFilter(__GLXclientState * cl,GLbyte * pc,GLXContextTag tag)274 GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
275 {
276 GLint compsize;
277 GLenum format, type, target;
278 GLboolean swapBytes;
279 __GLXcontext *cx;
280 ClientPtr client = cl->client;
281 int error;
282 char *answer, answerBuffer[200];
283 GLint width = 0, height = 0;
284 xGLXSingleReply reply = { 0, };
285
286 cx = __glXForceCurrent(cl, tag, &error);
287 if (!cx) {
288 return error;
289 }
290
291 format = *(GLenum *) (pc + 4);
292 type = *(GLenum *) (pc + 8);
293 target = *(GLenum *) (pc + 0);
294 swapBytes = *(GLboolean *) (pc + 12);
295
296 glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
297 if (target == GL_CONVOLUTION_1D) {
298 height = 1;
299 }
300 else {
301 glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
302 }
303 /*
304 * The two queries above might fail if we're in a state where queries
305 * are illegal, but then width and height would still be zero anyway.
306 */
307 compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1);
308 if (compsize < 0)
309 return BadLength;
310
311 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
312 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
313 __glXClearErrorOccured();
314 glGetConvolutionFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
315 *(GLenum *) (pc + 8), answer);
316
317 if (__glXErrorOccured()) {
318 __GLX_BEGIN_REPLY(0);
319 __GLX_SEND_HEADER();
320 }
321 else {
322 __GLX_BEGIN_REPLY(compsize);
323 ((xGLXGetConvolutionFilterReply *) &reply)->width = width;
324 ((xGLXGetConvolutionFilterReply *) &reply)->height = height;
325 __GLX_SEND_HEADER();
326 __GLX_SEND_VOID_ARRAY(compsize);
327 }
328
329 return Success;
330 }
331
332 int
__glXDisp_GetConvolutionFilter(__GLXclientState * cl,GLbyte * pc)333 __glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc)
334 {
335 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
336 ClientPtr client = cl->client;
337 REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
338 return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
339 }
340
341 int
__glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl,GLbyte * pc)342 __glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc)
343 {
344 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
345 ClientPtr client = cl->client;
346 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
347 return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
348 }
349
350 static int
GetHistogram(__GLXclientState * cl,GLbyte * pc,GLXContextTag tag)351 GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
352 {
353 GLint compsize;
354 GLenum format, type, target;
355 GLboolean swapBytes, reset;
356 __GLXcontext *cx;
357 ClientPtr client = cl->client;
358 int error;
359 char *answer, answerBuffer[200];
360 GLint width = 0;
361 xGLXSingleReply reply = { 0, };
362
363 cx = __glXForceCurrent(cl, tag, &error);
364 if (!cx) {
365 return error;
366 }
367
368 format = *(GLenum *) (pc + 4);
369 type = *(GLenum *) (pc + 8);
370 target = *(GLenum *) (pc + 0);
371 swapBytes = *(GLboolean *) (pc + 12);
372 reset = *(GLboolean *) (pc + 13);
373
374 glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width);
375 /*
376 * The one query above might fail if we're in a state where queries
377 * are illegal, but then width would still be zero anyway.
378 */
379 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
380 if (compsize < 0)
381 return BadLength;
382
383 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
384 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
385 __glXClearErrorOccured();
386 glGetHistogram(target, reset, format, type, answer);
387
388 if (__glXErrorOccured()) {
389 __GLX_BEGIN_REPLY(0);
390 __GLX_SEND_HEADER();
391 }
392 else {
393 __GLX_BEGIN_REPLY(compsize);
394 ((xGLXGetHistogramReply *) &reply)->width = width;
395 __GLX_SEND_HEADER();
396 __GLX_SEND_VOID_ARRAY(compsize);
397 }
398
399 return Success;
400 }
401
402 int
__glXDisp_GetHistogram(__GLXclientState * cl,GLbyte * pc)403 __glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc)
404 {
405 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
406 ClientPtr client = cl->client;
407 REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
408 return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
409 }
410
411 int
__glXDisp_GetHistogramEXT(__GLXclientState * cl,GLbyte * pc)412 __glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc)
413 {
414 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
415 ClientPtr client = cl->client;
416 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
417 return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
418 }
419
420 static int
GetMinmax(__GLXclientState * cl,GLbyte * pc,GLXContextTag tag)421 GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
422 {
423 GLint compsize;
424 GLenum format, type, target;
425 GLboolean swapBytes, reset;
426 __GLXcontext *cx;
427 ClientPtr client = cl->client;
428 int error;
429 char *answer, answerBuffer[200];
430 xGLXSingleReply reply = { 0, };
431
432 cx = __glXForceCurrent(cl, tag, &error);
433 if (!cx) {
434 return error;
435 }
436
437 format = *(GLenum *) (pc + 4);
438 type = *(GLenum *) (pc + 8);
439 target = *(GLenum *) (pc + 0);
440 swapBytes = *(GLboolean *) (pc + 12);
441 reset = *(GLboolean *) (pc + 13);
442
443 compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1);
444 if (compsize < 0)
445 return BadLength;
446
447 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
448 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
449 __glXClearErrorOccured();
450 glGetMinmax(target, reset, format, type, answer);
451
452 if (__glXErrorOccured()) {
453 __GLX_BEGIN_REPLY(0);
454 __GLX_SEND_HEADER();
455 }
456 else {
457 __GLX_BEGIN_REPLY(compsize);
458 __GLX_SEND_HEADER();
459 __GLX_SEND_VOID_ARRAY(compsize);
460 }
461
462 return Success;
463 }
464
465 int
__glXDisp_GetMinmax(__GLXclientState * cl,GLbyte * pc)466 __glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc)
467 {
468 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
469 ClientPtr client = cl->client;
470 REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
471 return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
472 }
473
474 int
__glXDisp_GetMinmaxEXT(__GLXclientState * cl,GLbyte * pc)475 __glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc)
476 {
477 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
478 ClientPtr client = cl->client;
479 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
480 return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
481 }
482
483 static int
GetColorTable(__GLXclientState * cl,GLbyte * pc,GLXContextTag tag)484 GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag)
485 {
486 GLint compsize;
487 GLenum format, type, target;
488 GLboolean swapBytes;
489 __GLXcontext *cx;
490 ClientPtr client = cl->client;
491 int error;
492 char *answer, answerBuffer[200];
493 GLint width = 0;
494 xGLXSingleReply reply = { 0, };
495
496 cx = __glXForceCurrent(cl, tag, &error);
497 if (!cx) {
498 return error;
499 }
500
501 target = *(GLenum *) (pc + 0);
502 format = *(GLenum *) (pc + 4);
503 type = *(GLenum *) (pc + 8);
504 swapBytes = *(GLboolean *) (pc + 12);
505
506 glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width);
507 /*
508 * The one query above might fail if we're in a state where queries
509 * are illegal, but then width would still be zero anyway.
510 */
511 compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1);
512 if (compsize < 0)
513 return BadLength;
514
515 glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
516 __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1);
517 __glXClearErrorOccured();
518 glGetColorTable(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4),
519 *(GLenum *) (pc + 8), answer);
520
521 if (__glXErrorOccured()) {
522 __GLX_BEGIN_REPLY(0);
523 __GLX_SEND_HEADER();
524 }
525 else {
526 __GLX_BEGIN_REPLY(compsize);
527 ((xGLXGetColorTableReply *) &reply)->width = width;
528 __GLX_SEND_HEADER();
529 __GLX_SEND_VOID_ARRAY(compsize);
530 }
531
532 return Success;
533 }
534
535 int
__glXDisp_GetColorTable(__GLXclientState * cl,GLbyte * pc)536 __glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc)
537 {
538 const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc);
539 ClientPtr client = cl->client;
540 REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
541 return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag);
542 }
543
544 int
__glXDisp_GetColorTableSGI(__GLXclientState * cl,GLbyte * pc)545 __glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc)
546 {
547 const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc);
548 ClientPtr client = cl->client;
549 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16);
550 return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag);
551 }
552