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