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