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