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