1cdc920a0Smrg/*
2cdc920a0Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3cdc920a0Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4cdc920a0Smrg *
5cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6cdc920a0Smrg * copy of this software and associated documentation files (the "Software"),
7cdc920a0Smrg * to deal in the Software without restriction, including without limitation
8cdc920a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9cdc920a0Smrg * and/or sell copies of the Software, and to permit persons to whom the
10cdc920a0Smrg * Software is furnished to do so, subject to the following conditions:
11cdc920a0Smrg *
12cdc920a0Smrg * The above copyright notice including the dates of first publication and
13cdc920a0Smrg * either this permission notice or a reference to
14cdc920a0Smrg * http://oss.sgi.com/projects/FreeB/
15cdc920a0Smrg * shall be included in all copies or substantial portions of the Software.
16cdc920a0Smrg *
17cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20cdc920a0Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21cdc920a0Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22cdc920a0Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23cdc920a0Smrg * SOFTWARE.
24cdc920a0Smrg *
25cdc920a0Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26cdc920a0Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27cdc920a0Smrg * other dealings in this Software without prior written authorization from
28cdc920a0Smrg * Silicon Graphics, Inc.
29cdc920a0Smrg */
30cdc920a0Smrg
31cdc920a0Smrg#include "glxclient.h"
32cdc920a0Smrg#include "indirect.h"
3301e04c3fSmrg#include "util/rounding.h"
34cdc920a0Smrg
35cdc920a0Smrg#if !defined(__GNUC__)
36cdc920a0Smrg#  define __builtin_expect(x, y) x
37cdc920a0Smrg#endif
38cdc920a0Smrg
39cdc920a0Smrg/**
40cdc920a0Smrg * Send glPixelStore command to the server
41cdc920a0Smrg *
42cdc920a0Smrg * \param gc     Current GLX context
43cdc920a0Smrg * \param sop    Either \c X_GLsop_PixelStoref or \c X_GLsop_PixelStorei
44cdc920a0Smrg * \param pname  Selector of which pixel parameter is to be set.
45cdc920a0Smrg * \param param  Value that \c pname is set to.
46cdc920a0Smrg *
47cdc920a0Smrg * \sa __indirect_glPixelStorei,  __indirect_glPixelStoref
48cdc920a0Smrg */
49cdc920a0Smrgstatic void
503464ebd5Sriastradhsend_PixelStore(struct glx_context * gc, unsigned sop, GLenum pname,
51cdc920a0Smrg                const void *param)
52cdc920a0Smrg{
53cdc920a0Smrg   Display *const dpy = gc->currentDpy;
54cdc920a0Smrg   const GLuint cmdlen = 8;
55cdc920a0Smrg   if (__builtin_expect(dpy != NULL, 1)) {
56cdc920a0Smrg      GLubyte const *pc = __glXSetupSingleRequest(gc, sop, cmdlen);
57cdc920a0Smrg      (void) memcpy((void *) (pc + 0), (void *) (&pname), 4);
58cdc920a0Smrg      (void) memcpy((void *) (pc + 4), param, 4);
59cdc920a0Smrg      UnlockDisplay(dpy);
60cdc920a0Smrg      SyncHandle();
61cdc920a0Smrg   }
62cdc920a0Smrg   return;
63cdc920a0Smrg}
64cdc920a0Smrg
65cdc920a0Smrg/*
66cdc920a0Smrg** Specify parameters that control the storage format of pixel arrays.
67cdc920a0Smrg*/
68cdc920a0Smrgvoid
69cdc920a0Smrg__indirect_glPixelStoref(GLenum pname, GLfloat param)
70cdc920a0Smrg{
713464ebd5Sriastradh   struct glx_context *gc = __glXGetCurrentContext();
72cdc920a0Smrg   __GLXattribute *state = gc->client_state_private;
73cdc920a0Smrg   Display *dpy = gc->currentDpy;
74cdc920a0Smrg   GLuint a;
75cdc920a0Smrg
76cdc920a0Smrg   if (!dpy)
77cdc920a0Smrg      return;
78cdc920a0Smrg
79cdc920a0Smrg   switch (pname) {
80cdc920a0Smrg   case GL_PACK_ROW_LENGTH:
8101e04c3fSmrg      a = _mesa_lroundevenf(param);
82cdc920a0Smrg      if (((GLint) a) < 0) {
83cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
84cdc920a0Smrg         return;
85cdc920a0Smrg      }
86cdc920a0Smrg      state->storePack.rowLength = a;
87cdc920a0Smrg      break;
88cdc920a0Smrg   case GL_PACK_IMAGE_HEIGHT:
8901e04c3fSmrg      a = _mesa_lroundevenf(param);
90cdc920a0Smrg      if (((GLint) a) < 0) {
91cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
92cdc920a0Smrg         return;
93cdc920a0Smrg      }
94cdc920a0Smrg      state->storePack.imageHeight = a;
95cdc920a0Smrg      break;
96cdc920a0Smrg   case GL_PACK_SKIP_ROWS:
9701e04c3fSmrg      a = _mesa_lroundevenf(param);
98cdc920a0Smrg      if (((GLint) a) < 0) {
99cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
100cdc920a0Smrg         return;
101cdc920a0Smrg      }
102cdc920a0Smrg      state->storePack.skipRows = a;
103cdc920a0Smrg      break;
104cdc920a0Smrg   case GL_PACK_SKIP_PIXELS:
10501e04c3fSmrg      a = _mesa_lroundevenf(param);
106cdc920a0Smrg      if (((GLint) a) < 0) {
107cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
108cdc920a0Smrg         return;
109cdc920a0Smrg      }
110cdc920a0Smrg      state->storePack.skipPixels = a;
111cdc920a0Smrg      break;
112cdc920a0Smrg   case GL_PACK_SKIP_IMAGES:
11301e04c3fSmrg      a = _mesa_lroundevenf(param);
114cdc920a0Smrg      if (((GLint) a) < 0) {
115cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
116cdc920a0Smrg         return;
117cdc920a0Smrg      }
118cdc920a0Smrg      state->storePack.skipImages = a;
119cdc920a0Smrg      break;
120cdc920a0Smrg   case GL_PACK_ALIGNMENT:
12101e04c3fSmrg      a = _mesa_lroundevenf(param);
122cdc920a0Smrg      switch (a) {
123cdc920a0Smrg      case 1:
124cdc920a0Smrg      case 2:
125cdc920a0Smrg      case 4:
126cdc920a0Smrg      case 8:
127cdc920a0Smrg         state->storePack.alignment = a;
128cdc920a0Smrg         break;
129cdc920a0Smrg      default:
130cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
131cdc920a0Smrg         return;
132cdc920a0Smrg      }
133cdc920a0Smrg      break;
134cdc920a0Smrg   case GL_PACK_SWAP_BYTES:
135cdc920a0Smrg      state->storePack.swapEndian = (param != 0);
136cdc920a0Smrg      break;
137cdc920a0Smrg   case GL_PACK_LSB_FIRST:
138cdc920a0Smrg      state->storePack.lsbFirst = (param != 0);
139cdc920a0Smrg      break;
140cdc920a0Smrg
141cdc920a0Smrg   case GL_UNPACK_ROW_LENGTH:
14201e04c3fSmrg      a = _mesa_lroundevenf(param);
143cdc920a0Smrg      if (((GLint) a) < 0) {
144cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
145cdc920a0Smrg         return;
146cdc920a0Smrg      }
147cdc920a0Smrg      state->storeUnpack.rowLength = a;
148cdc920a0Smrg      break;
149cdc920a0Smrg   case GL_UNPACK_IMAGE_HEIGHT:
15001e04c3fSmrg      a = _mesa_lroundevenf(param);
151cdc920a0Smrg      if (((GLint) a) < 0) {
152cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
153cdc920a0Smrg         return;
154cdc920a0Smrg      }
155cdc920a0Smrg      state->storeUnpack.imageHeight = a;
156cdc920a0Smrg      break;
157cdc920a0Smrg   case GL_UNPACK_SKIP_ROWS:
15801e04c3fSmrg      a = _mesa_lroundevenf(param);
159cdc920a0Smrg      if (((GLint) a) < 0) {
160cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
161cdc920a0Smrg         return;
162cdc920a0Smrg      }
163cdc920a0Smrg      state->storeUnpack.skipRows = a;
164cdc920a0Smrg      break;
165cdc920a0Smrg   case GL_UNPACK_SKIP_PIXELS:
16601e04c3fSmrg      a = _mesa_lroundevenf(param);
167cdc920a0Smrg      if (((GLint) a) < 0) {
168cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
169cdc920a0Smrg         return;
170cdc920a0Smrg      }
171cdc920a0Smrg      state->storeUnpack.skipPixels = a;
172cdc920a0Smrg      break;
173cdc920a0Smrg   case GL_UNPACK_SKIP_IMAGES:
17401e04c3fSmrg      a = _mesa_lroundevenf(param);
175cdc920a0Smrg      if (((GLint) a) < 0) {
176cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
177cdc920a0Smrg         return;
178cdc920a0Smrg      }
179cdc920a0Smrg      state->storeUnpack.skipImages = a;
180cdc920a0Smrg      break;
181cdc920a0Smrg   case GL_UNPACK_ALIGNMENT:
18201e04c3fSmrg      a = _mesa_lroundevenf(param);
183cdc920a0Smrg      switch (a) {
184cdc920a0Smrg      case 1:
185cdc920a0Smrg      case 2:
186cdc920a0Smrg      case 4:
187cdc920a0Smrg      case 8:
188cdc920a0Smrg         state->storeUnpack.alignment = a;
189cdc920a0Smrg         break;
190cdc920a0Smrg      default:
191cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
192cdc920a0Smrg         return;
193cdc920a0Smrg      }
194cdc920a0Smrg      break;
195cdc920a0Smrg   case GL_UNPACK_SWAP_BYTES:
196cdc920a0Smrg      state->storeUnpack.swapEndian = (param != 0);
197cdc920a0Smrg      break;
198cdc920a0Smrg   case GL_UNPACK_LSB_FIRST:
199cdc920a0Smrg      state->storeUnpack.lsbFirst = (param != 0);
200cdc920a0Smrg      break;
201cdc920a0Smrg
202cdc920a0Smrg      /* Group all of the pixel store modes that need to be sent to the
203cdc920a0Smrg       * server here.  Care must be used to only send modes to the server that
204cdc920a0Smrg       * won't affect the size of the data sent to or received from the
205cdc920a0Smrg       * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
206cdc920a0Smrg       * future modes may not be.
207cdc920a0Smrg       */
208cdc920a0Smrg   case GL_PACK_INVERT_MESA:
209cdc920a0Smrg      send_PixelStore(gc, X_GLsop_PixelStoref, pname, &param);
210cdc920a0Smrg      break;
211cdc920a0Smrg
212cdc920a0Smrg   default:
213cdc920a0Smrg      __glXSetError(gc, GL_INVALID_ENUM);
214cdc920a0Smrg      break;
215cdc920a0Smrg   }
216cdc920a0Smrg}
217cdc920a0Smrg
218cdc920a0Smrgvoid
219cdc920a0Smrg__indirect_glPixelStorei(GLenum pname, GLint param)
220cdc920a0Smrg{
2213464ebd5Sriastradh   struct glx_context *gc = __glXGetCurrentContext();
222cdc920a0Smrg   __GLXattribute *state = gc->client_state_private;
223cdc920a0Smrg   Display *dpy = gc->currentDpy;
224cdc920a0Smrg
225cdc920a0Smrg   if (!dpy)
226cdc920a0Smrg      return;
227cdc920a0Smrg
228cdc920a0Smrg   switch (pname) {
229cdc920a0Smrg   case GL_PACK_ROW_LENGTH:
230cdc920a0Smrg      if (param < 0) {
231cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
232cdc920a0Smrg         return;
233cdc920a0Smrg      }
234cdc920a0Smrg      state->storePack.rowLength = param;
235cdc920a0Smrg      break;
236cdc920a0Smrg   case GL_PACK_IMAGE_HEIGHT:
237cdc920a0Smrg      if (param < 0) {
238cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
239cdc920a0Smrg         return;
240cdc920a0Smrg      }
241cdc920a0Smrg      state->storePack.imageHeight = param;
242cdc920a0Smrg      break;
243cdc920a0Smrg   case GL_PACK_SKIP_ROWS:
244cdc920a0Smrg      if (param < 0) {
245cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
246cdc920a0Smrg         return;
247cdc920a0Smrg      }
248cdc920a0Smrg      state->storePack.skipRows = param;
249cdc920a0Smrg      break;
250cdc920a0Smrg   case GL_PACK_SKIP_PIXELS:
251cdc920a0Smrg      if (param < 0) {
252cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
253cdc920a0Smrg         return;
254cdc920a0Smrg      }
255cdc920a0Smrg      state->storePack.skipPixels = param;
256cdc920a0Smrg      break;
257cdc920a0Smrg   case GL_PACK_SKIP_IMAGES:
258cdc920a0Smrg      if (param < 0) {
259cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
260cdc920a0Smrg         return;
261cdc920a0Smrg      }
262cdc920a0Smrg      state->storePack.skipImages = param;
263cdc920a0Smrg      break;
264cdc920a0Smrg   case GL_PACK_ALIGNMENT:
265cdc920a0Smrg      switch (param) {
266cdc920a0Smrg      case 1:
267cdc920a0Smrg      case 2:
268cdc920a0Smrg      case 4:
269cdc920a0Smrg      case 8:
270cdc920a0Smrg         state->storePack.alignment = param;
271cdc920a0Smrg         break;
272cdc920a0Smrg      default:
273cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
274cdc920a0Smrg         return;
275cdc920a0Smrg      }
276cdc920a0Smrg      break;
277cdc920a0Smrg   case GL_PACK_SWAP_BYTES:
278cdc920a0Smrg      state->storePack.swapEndian = (param != 0);
279cdc920a0Smrg      break;
280cdc920a0Smrg   case GL_PACK_LSB_FIRST:
281cdc920a0Smrg      state->storePack.lsbFirst = (param != 0);
282cdc920a0Smrg      break;
283cdc920a0Smrg
284cdc920a0Smrg   case GL_UNPACK_ROW_LENGTH:
285cdc920a0Smrg      if (param < 0) {
286cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
287cdc920a0Smrg         return;
288cdc920a0Smrg      }
289cdc920a0Smrg      state->storeUnpack.rowLength = param;
290cdc920a0Smrg      break;
291cdc920a0Smrg   case GL_UNPACK_IMAGE_HEIGHT:
292cdc920a0Smrg      if (param < 0) {
293cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
294cdc920a0Smrg         return;
295cdc920a0Smrg      }
296cdc920a0Smrg      state->storeUnpack.imageHeight = param;
297cdc920a0Smrg      break;
298cdc920a0Smrg   case GL_UNPACK_SKIP_ROWS:
299cdc920a0Smrg      if (param < 0) {
300cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
301cdc920a0Smrg         return;
302cdc920a0Smrg      }
303cdc920a0Smrg      state->storeUnpack.skipRows = param;
304cdc920a0Smrg      break;
305cdc920a0Smrg   case GL_UNPACK_SKIP_PIXELS:
306cdc920a0Smrg      if (param < 0) {
307cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
308cdc920a0Smrg         return;
309cdc920a0Smrg      }
310cdc920a0Smrg      state->storeUnpack.skipPixels = param;
311cdc920a0Smrg      break;
312cdc920a0Smrg   case GL_UNPACK_SKIP_IMAGES:
313cdc920a0Smrg      if (param < 0) {
314cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
315cdc920a0Smrg         return;
316cdc920a0Smrg      }
317cdc920a0Smrg      state->storeUnpack.skipImages = param;
318cdc920a0Smrg      break;
319cdc920a0Smrg   case GL_UNPACK_ALIGNMENT:
320cdc920a0Smrg      switch (param) {
321cdc920a0Smrg      case 1:
322cdc920a0Smrg      case 2:
323cdc920a0Smrg      case 4:
324cdc920a0Smrg      case 8:
325cdc920a0Smrg         state->storeUnpack.alignment = param;
326cdc920a0Smrg         break;
327cdc920a0Smrg      default:
328cdc920a0Smrg         __glXSetError(gc, GL_INVALID_VALUE);
329cdc920a0Smrg         return;
330cdc920a0Smrg      }
331cdc920a0Smrg      break;
332cdc920a0Smrg   case GL_UNPACK_SWAP_BYTES:
333cdc920a0Smrg      state->storeUnpack.swapEndian = (param != 0);
334cdc920a0Smrg      break;
335cdc920a0Smrg   case GL_UNPACK_LSB_FIRST:
336cdc920a0Smrg      state->storeUnpack.lsbFirst = (param != 0);
337cdc920a0Smrg      break;
338cdc920a0Smrg
339cdc920a0Smrg      /* Group all of the pixel store modes that need to be sent to the
340cdc920a0Smrg       * server here.  Care must be used to only send modes to the server that
341cdc920a0Smrg       * won't affect the size of the data sent to or received from the
342cdc920a0Smrg       * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
343cdc920a0Smrg       * future modes may not be.
344cdc920a0Smrg       */
345cdc920a0Smrg   case GL_PACK_INVERT_MESA:
346cdc920a0Smrg      send_PixelStore(gc, X_GLsop_PixelStorei, pname, &param);
347cdc920a0Smrg      break;
348cdc920a0Smrg
349cdc920a0Smrg   default:
350cdc920a0Smrg      __glXSetError(gc, GL_INVALID_ENUM);
351cdc920a0Smrg      break;
352cdc920a0Smrg   }
353cdc920a0Smrg}
354