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, ¶m);
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, ¶m);
346 break;
347
348 default:
349 __glXSetError(gc, GL_INVALID_ENUM);
350 break;
351 }
352 }
353