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 */
48static void
49send_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*/
67void
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
217void
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