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 #include "glxclient.h"
32 #include "indirect.h"
33 
34 #if !defined(__GNUC__)
35 #  define __builtin_expect(x, y) x
36 #endif
37 
38 /**
39  * Send glPixelStore command to the server
40  *
41  * \param gc     Current GLX context
42  * \param sop    Either \c X_GLsop_PixelStoref or \c X_GLsop_PixelStorei
43  * \param pname  Selector of which pixel parameter is to be set.
44  * \param param  Value that \c pname is set to.
45  *
46  * \sa __indirect_glPixelStorei,  __indirect_glPixelStoref
47  */
48 static void
send_PixelStore(struct glx_context * gc,unsigned sop,GLenum pname,const void * param)49 send_PixelStore(struct glx_context * gc, unsigned sop, GLenum pname,
50                 const void *param)
51 {
52    Display *const dpy = gc->currentDpy;
53    const GLuint cmdlen = 8;
54    if (__builtin_expect(dpy != NULL, 1)) {
55       GLubyte const *pc = __glXSetupSingleRequest(gc, sop, cmdlen);
56       (void) memcpy((void *) (pc + 0), (void *) (&pname), 4);
57       (void) memcpy((void *) (pc + 4), param, 4);
58       UnlockDisplay(dpy);
59       SyncHandle();
60    }
61    return;
62 }
63 
64 /*
65 ** Specify parameters that control the storage format of pixel arrays.
66 */
67 void
__indirect_glPixelStoref(GLenum pname,GLfloat param)68 __indirect_glPixelStoref(GLenum pname, GLfloat param)
69 {
70    struct glx_context *gc = __glXGetCurrentContext();
71    __GLXattribute *state = gc->client_state_private;
72    Display *dpy = gc->currentDpy;
73    GLuint a;
74 
75    if (!dpy)
76       return;
77 
78    switch (pname) {
79    case GL_PACK_ROW_LENGTH:
80       a = (GLuint) (param + 0.5);
81       if (((GLint) a) < 0) {
82          __glXSetError(gc, GL_INVALID_VALUE);
83          return;
84       }
85       state->storePack.rowLength = a;
86       break;
87    case GL_PACK_IMAGE_HEIGHT:
88       a = (GLuint) (param + 0.5);
89       if (((GLint) a) < 0) {
90          __glXSetError(gc, GL_INVALID_VALUE);
91          return;
92       }
93       state->storePack.imageHeight = a;
94       break;
95    case GL_PACK_SKIP_ROWS:
96       a = (GLuint) (param + 0.5);
97       if (((GLint) a) < 0) {
98          __glXSetError(gc, GL_INVALID_VALUE);
99          return;
100       }
101       state->storePack.skipRows = a;
102       break;
103    case GL_PACK_SKIP_PIXELS:
104       a = (GLuint) (param + 0.5);
105       if (((GLint) a) < 0) {
106          __glXSetError(gc, GL_INVALID_VALUE);
107          return;
108       }
109       state->storePack.skipPixels = a;
110       break;
111    case GL_PACK_SKIP_IMAGES:
112       a = (GLuint) (param + 0.5);
113       if (((GLint) a) < 0) {
114          __glXSetError(gc, GL_INVALID_VALUE);
115          return;
116       }
117       state->storePack.skipImages = a;
118       break;
119    case GL_PACK_ALIGNMENT:
120       a = (GLint) (param + 0.5);
121       switch (a) {
122       case 1:
123       case 2:
124       case 4:
125       case 8:
126          state->storePack.alignment = a;
127          break;
128       default:
129          __glXSetError(gc, GL_INVALID_VALUE);
130          return;
131       }
132       break;
133    case GL_PACK_SWAP_BYTES:
134       state->storePack.swapEndian = (param != 0);
135       break;
136    case GL_PACK_LSB_FIRST:
137       state->storePack.lsbFirst = (param != 0);
138       break;
139 
140    case GL_UNPACK_ROW_LENGTH:
141       a = (GLuint) (param + 0.5);
142       if (((GLint) a) < 0) {
143          __glXSetError(gc, GL_INVALID_VALUE);
144          return;
145       }
146       state->storeUnpack.rowLength = a;
147       break;
148    case GL_UNPACK_IMAGE_HEIGHT:
149       a = (GLuint) (param + 0.5);
150       if (((GLint) a) < 0) {
151          __glXSetError(gc, GL_INVALID_VALUE);
152          return;
153       }
154       state->storeUnpack.imageHeight = a;
155       break;
156    case GL_UNPACK_SKIP_ROWS:
157       a = (GLuint) (param + 0.5);
158       if (((GLint) a) < 0) {
159          __glXSetError(gc, GL_INVALID_VALUE);
160          return;
161       }
162       state->storeUnpack.skipRows = a;
163       break;
164    case GL_UNPACK_SKIP_PIXELS:
165       a = (GLuint) (param + 0.5);
166       if (((GLint) a) < 0) {
167          __glXSetError(gc, GL_INVALID_VALUE);
168          return;
169       }
170       state->storeUnpack.skipPixels = a;
171       break;
172    case GL_UNPACK_SKIP_IMAGES:
173       a = (GLuint) (param + 0.5);
174       if (((GLint) a) < 0) {
175          __glXSetError(gc, GL_INVALID_VALUE);
176          return;
177       }
178       state->storeUnpack.skipImages = a;
179       break;
180    case GL_UNPACK_ALIGNMENT:
181       a = (GLint) (param + 0.5);
182       switch (a) {
183       case 1:
184       case 2:
185       case 4:
186       case 8:
187          state->storeUnpack.alignment = a;
188          break;
189       default:
190          __glXSetError(gc, GL_INVALID_VALUE);
191          return;
192       }
193       break;
194    case GL_UNPACK_SWAP_BYTES:
195       state->storeUnpack.swapEndian = (param != 0);
196       break;
197    case GL_UNPACK_LSB_FIRST:
198       state->storeUnpack.lsbFirst = (param != 0);
199       break;
200 
201       /* Group all of the pixel store modes that need to be sent to the
202        * server here.  Care must be used to only send modes to the server that
203        * won't affect the size of the data sent to or received from the
204        * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
205        * future modes may not be.
206        */
207    case GL_PACK_INVERT_MESA:
208       send_PixelStore(gc, X_GLsop_PixelStoref, pname, &param);
209       break;
210 
211    default:
212       __glXSetError(gc, GL_INVALID_ENUM);
213       break;
214    }
215 }
216 
217 void
__indirect_glPixelStorei(GLenum pname,GLint param)218 __indirect_glPixelStorei(GLenum pname, GLint param)
219 {
220    struct glx_context *gc = __glXGetCurrentContext();
221    __GLXattribute *state = gc->client_state_private;
222    Display *dpy = gc->currentDpy;
223 
224    if (!dpy)
225       return;
226 
227    switch (pname) {
228    case GL_PACK_ROW_LENGTH:
229       if (param < 0) {
230          __glXSetError(gc, GL_INVALID_VALUE);
231          return;
232       }
233       state->storePack.rowLength = param;
234       break;
235    case GL_PACK_IMAGE_HEIGHT:
236       if (param < 0) {
237          __glXSetError(gc, GL_INVALID_VALUE);
238          return;
239       }
240       state->storePack.imageHeight = param;
241       break;
242    case GL_PACK_SKIP_ROWS:
243       if (param < 0) {
244          __glXSetError(gc, GL_INVALID_VALUE);
245          return;
246       }
247       state->storePack.skipRows = param;
248       break;
249    case GL_PACK_SKIP_PIXELS:
250       if (param < 0) {
251          __glXSetError(gc, GL_INVALID_VALUE);
252          return;
253       }
254       state->storePack.skipPixels = param;
255       break;
256    case GL_PACK_SKIP_IMAGES:
257       if (param < 0) {
258          __glXSetError(gc, GL_INVALID_VALUE);
259          return;
260       }
261       state->storePack.skipImages = param;
262       break;
263    case GL_PACK_ALIGNMENT:
264       switch (param) {
265       case 1:
266       case 2:
267       case 4:
268       case 8:
269          state->storePack.alignment = param;
270          break;
271       default:
272          __glXSetError(gc, GL_INVALID_VALUE);
273          return;
274       }
275       break;
276    case GL_PACK_SWAP_BYTES:
277       state->storePack.swapEndian = (param != 0);
278       break;
279    case GL_PACK_LSB_FIRST:
280       state->storePack.lsbFirst = (param != 0);
281       break;
282 
283    case GL_UNPACK_ROW_LENGTH:
284       if (param < 0) {
285          __glXSetError(gc, GL_INVALID_VALUE);
286          return;
287       }
288       state->storeUnpack.rowLength = param;
289       break;
290    case GL_UNPACK_IMAGE_HEIGHT:
291       if (param < 0) {
292          __glXSetError(gc, GL_INVALID_VALUE);
293          return;
294       }
295       state->storeUnpack.imageHeight = param;
296       break;
297    case GL_UNPACK_SKIP_ROWS:
298       if (param < 0) {
299          __glXSetError(gc, GL_INVALID_VALUE);
300          return;
301       }
302       state->storeUnpack.skipRows = param;
303       break;
304    case GL_UNPACK_SKIP_PIXELS:
305       if (param < 0) {
306          __glXSetError(gc, GL_INVALID_VALUE);
307          return;
308       }
309       state->storeUnpack.skipPixels = param;
310       break;
311    case GL_UNPACK_SKIP_IMAGES:
312       if (param < 0) {
313          __glXSetError(gc, GL_INVALID_VALUE);
314          return;
315       }
316       state->storeUnpack.skipImages = param;
317       break;
318    case GL_UNPACK_ALIGNMENT:
319       switch (param) {
320       case 1:
321       case 2:
322       case 4:
323       case 8:
324          state->storeUnpack.alignment = param;
325          break;
326       default:
327          __glXSetError(gc, GL_INVALID_VALUE);
328          return;
329       }
330       break;
331    case GL_UNPACK_SWAP_BYTES:
332       state->storeUnpack.swapEndian = (param != 0);
333       break;
334    case GL_UNPACK_LSB_FIRST:
335       state->storeUnpack.lsbFirst = (param != 0);
336       break;
337 
338       /* Group all of the pixel store modes that need to be sent to the
339        * server here.  Care must be used to only send modes to the server that
340        * won't affect the size of the data sent to or received from the
341        * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
342        * future modes may not be.
343        */
344    case GL_PACK_INVERT_MESA:
345       send_PixelStore(gc, X_GLsop_PixelStorei, pname, &param);
346       break;
347 
348    default:
349       __glXSetError(gc, GL_INVALID_ENUM);
350       break;
351    }
352 }
353