1848b8605Smrg/*
2848b8605Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3848b8605Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4848b8605Smrg *
5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6848b8605Smrg * copy of this software and associated documentation files (the "Software"),
7848b8605Smrg * to deal in the Software without restriction, including without limitation
8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
10848b8605Smrg * Software is furnished to do so, subject to the following conditions:
11848b8605Smrg *
12848b8605Smrg * The above copyright notice including the dates of first publication and
13848b8605Smrg * either this permission notice or a reference to
14848b8605Smrg * http://oss.sgi.com/projects/FreeB/
15848b8605Smrg * shall be included in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20848b8605Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21848b8605Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22848b8605Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23848b8605Smrg * SOFTWARE.
24848b8605Smrg *
25848b8605Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26848b8605Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27848b8605Smrg * other dealings in this Software without prior written authorization from
28848b8605Smrg * Silicon Graphics, Inc.
29848b8605Smrg */
30848b8605Smrg
31848b8605Smrg#include "glxclient.h"
32848b8605Smrg#include "indirect.h"
33b8e80941Smrg#include "util/rounding.h"
34848b8605Smrg
35848b8605Smrg#if !defined(__GNUC__)
36848b8605Smrg#  define __builtin_expect(x, y) x
37848b8605Smrg#endif
38848b8605Smrg
39848b8605Smrg/**
40848b8605Smrg * Send glPixelStore command to the server
41848b8605Smrg *
42848b8605Smrg * \param gc     Current GLX context
43848b8605Smrg * \param sop    Either \c X_GLsop_PixelStoref or \c X_GLsop_PixelStorei
44848b8605Smrg * \param pname  Selector of which pixel parameter is to be set.
45848b8605Smrg * \param param  Value that \c pname is set to.
46848b8605Smrg *
47848b8605Smrg * \sa __indirect_glPixelStorei,  __indirect_glPixelStoref
48848b8605Smrg */
49848b8605Smrgstatic void
50848b8605Smrgsend_PixelStore(struct glx_context * gc, unsigned sop, GLenum pname,
51848b8605Smrg                const void *param)
52848b8605Smrg{
53848b8605Smrg   Display *const dpy = gc->currentDpy;
54848b8605Smrg   const GLuint cmdlen = 8;
55848b8605Smrg   if (__builtin_expect(dpy != NULL, 1)) {
56848b8605Smrg      GLubyte const *pc = __glXSetupSingleRequest(gc, sop, cmdlen);
57848b8605Smrg      (void) memcpy((void *) (pc + 0), (void *) (&pname), 4);
58848b8605Smrg      (void) memcpy((void *) (pc + 4), param, 4);
59848b8605Smrg      UnlockDisplay(dpy);
60848b8605Smrg      SyncHandle();
61848b8605Smrg   }
62848b8605Smrg   return;
63848b8605Smrg}
64848b8605Smrg
65848b8605Smrg/*
66848b8605Smrg** Specify parameters that control the storage format of pixel arrays.
67848b8605Smrg*/
68848b8605Smrgvoid
69848b8605Smrg__indirect_glPixelStoref(GLenum pname, GLfloat param)
70848b8605Smrg{
71848b8605Smrg   struct glx_context *gc = __glXGetCurrentContext();
72848b8605Smrg   __GLXattribute *state = gc->client_state_private;
73848b8605Smrg   Display *dpy = gc->currentDpy;
74848b8605Smrg   GLuint a;
75848b8605Smrg
76848b8605Smrg   if (!dpy)
77848b8605Smrg      return;
78848b8605Smrg
79848b8605Smrg   switch (pname) {
80848b8605Smrg   case GL_PACK_ROW_LENGTH:
81b8e80941Smrg      a = _mesa_lroundevenf(param);
82848b8605Smrg      if (((GLint) a) < 0) {
83848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
84848b8605Smrg         return;
85848b8605Smrg      }
86848b8605Smrg      state->storePack.rowLength = a;
87848b8605Smrg      break;
88848b8605Smrg   case GL_PACK_IMAGE_HEIGHT:
89b8e80941Smrg      a = _mesa_lroundevenf(param);
90848b8605Smrg      if (((GLint) a) < 0) {
91848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
92848b8605Smrg         return;
93848b8605Smrg      }
94848b8605Smrg      state->storePack.imageHeight = a;
95848b8605Smrg      break;
96848b8605Smrg   case GL_PACK_SKIP_ROWS:
97b8e80941Smrg      a = _mesa_lroundevenf(param);
98848b8605Smrg      if (((GLint) a) < 0) {
99848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
100848b8605Smrg         return;
101848b8605Smrg      }
102848b8605Smrg      state->storePack.skipRows = a;
103848b8605Smrg      break;
104848b8605Smrg   case GL_PACK_SKIP_PIXELS:
105b8e80941Smrg      a = _mesa_lroundevenf(param);
106848b8605Smrg      if (((GLint) a) < 0) {
107848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
108848b8605Smrg         return;
109848b8605Smrg      }
110848b8605Smrg      state->storePack.skipPixels = a;
111848b8605Smrg      break;
112848b8605Smrg   case GL_PACK_SKIP_IMAGES:
113b8e80941Smrg      a = _mesa_lroundevenf(param);
114848b8605Smrg      if (((GLint) a) < 0) {
115848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
116848b8605Smrg         return;
117848b8605Smrg      }
118848b8605Smrg      state->storePack.skipImages = a;
119848b8605Smrg      break;
120848b8605Smrg   case GL_PACK_ALIGNMENT:
121b8e80941Smrg      a = _mesa_lroundevenf(param);
122848b8605Smrg      switch (a) {
123848b8605Smrg      case 1:
124848b8605Smrg      case 2:
125848b8605Smrg      case 4:
126848b8605Smrg      case 8:
127848b8605Smrg         state->storePack.alignment = a;
128848b8605Smrg         break;
129848b8605Smrg      default:
130848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
131848b8605Smrg         return;
132848b8605Smrg      }
133848b8605Smrg      break;
134848b8605Smrg   case GL_PACK_SWAP_BYTES:
135848b8605Smrg      state->storePack.swapEndian = (param != 0);
136848b8605Smrg      break;
137848b8605Smrg   case GL_PACK_LSB_FIRST:
138848b8605Smrg      state->storePack.lsbFirst = (param != 0);
139848b8605Smrg      break;
140848b8605Smrg
141848b8605Smrg   case GL_UNPACK_ROW_LENGTH:
142b8e80941Smrg      a = _mesa_lroundevenf(param);
143848b8605Smrg      if (((GLint) a) < 0) {
144848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
145848b8605Smrg         return;
146848b8605Smrg      }
147848b8605Smrg      state->storeUnpack.rowLength = a;
148848b8605Smrg      break;
149848b8605Smrg   case GL_UNPACK_IMAGE_HEIGHT:
150b8e80941Smrg      a = _mesa_lroundevenf(param);
151848b8605Smrg      if (((GLint) a) < 0) {
152848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
153848b8605Smrg         return;
154848b8605Smrg      }
155848b8605Smrg      state->storeUnpack.imageHeight = a;
156848b8605Smrg      break;
157848b8605Smrg   case GL_UNPACK_SKIP_ROWS:
158b8e80941Smrg      a = _mesa_lroundevenf(param);
159848b8605Smrg      if (((GLint) a) < 0) {
160848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
161848b8605Smrg         return;
162848b8605Smrg      }
163848b8605Smrg      state->storeUnpack.skipRows = a;
164848b8605Smrg      break;
165848b8605Smrg   case GL_UNPACK_SKIP_PIXELS:
166b8e80941Smrg      a = _mesa_lroundevenf(param);
167848b8605Smrg      if (((GLint) a) < 0) {
168848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
169848b8605Smrg         return;
170848b8605Smrg      }
171848b8605Smrg      state->storeUnpack.skipPixels = a;
172848b8605Smrg      break;
173848b8605Smrg   case GL_UNPACK_SKIP_IMAGES:
174b8e80941Smrg      a = _mesa_lroundevenf(param);
175848b8605Smrg      if (((GLint) a) < 0) {
176848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
177848b8605Smrg         return;
178848b8605Smrg      }
179848b8605Smrg      state->storeUnpack.skipImages = a;
180848b8605Smrg      break;
181848b8605Smrg   case GL_UNPACK_ALIGNMENT:
182b8e80941Smrg      a = _mesa_lroundevenf(param);
183848b8605Smrg      switch (a) {
184848b8605Smrg      case 1:
185848b8605Smrg      case 2:
186848b8605Smrg      case 4:
187848b8605Smrg      case 8:
188848b8605Smrg         state->storeUnpack.alignment = a;
189848b8605Smrg         break;
190848b8605Smrg      default:
191848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
192848b8605Smrg         return;
193848b8605Smrg      }
194848b8605Smrg      break;
195848b8605Smrg   case GL_UNPACK_SWAP_BYTES:
196848b8605Smrg      state->storeUnpack.swapEndian = (param != 0);
197848b8605Smrg      break;
198848b8605Smrg   case GL_UNPACK_LSB_FIRST:
199848b8605Smrg      state->storeUnpack.lsbFirst = (param != 0);
200848b8605Smrg      break;
201848b8605Smrg
202848b8605Smrg      /* Group all of the pixel store modes that need to be sent to the
203848b8605Smrg       * server here.  Care must be used to only send modes to the server that
204848b8605Smrg       * won't affect the size of the data sent to or received from the
205848b8605Smrg       * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
206848b8605Smrg       * future modes may not be.
207848b8605Smrg       */
208848b8605Smrg   case GL_PACK_INVERT_MESA:
209848b8605Smrg      send_PixelStore(gc, X_GLsop_PixelStoref, pname, &param);
210848b8605Smrg      break;
211848b8605Smrg
212848b8605Smrg   default:
213848b8605Smrg      __glXSetError(gc, GL_INVALID_ENUM);
214848b8605Smrg      break;
215848b8605Smrg   }
216848b8605Smrg}
217848b8605Smrg
218848b8605Smrgvoid
219848b8605Smrg__indirect_glPixelStorei(GLenum pname, GLint param)
220848b8605Smrg{
221848b8605Smrg   struct glx_context *gc = __glXGetCurrentContext();
222848b8605Smrg   __GLXattribute *state = gc->client_state_private;
223848b8605Smrg   Display *dpy = gc->currentDpy;
224848b8605Smrg
225848b8605Smrg   if (!dpy)
226848b8605Smrg      return;
227848b8605Smrg
228848b8605Smrg   switch (pname) {
229848b8605Smrg   case GL_PACK_ROW_LENGTH:
230848b8605Smrg      if (param < 0) {
231848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
232848b8605Smrg         return;
233848b8605Smrg      }
234848b8605Smrg      state->storePack.rowLength = param;
235848b8605Smrg      break;
236848b8605Smrg   case GL_PACK_IMAGE_HEIGHT:
237848b8605Smrg      if (param < 0) {
238848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
239848b8605Smrg         return;
240848b8605Smrg      }
241848b8605Smrg      state->storePack.imageHeight = param;
242848b8605Smrg      break;
243848b8605Smrg   case GL_PACK_SKIP_ROWS:
244848b8605Smrg      if (param < 0) {
245848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
246848b8605Smrg         return;
247848b8605Smrg      }
248848b8605Smrg      state->storePack.skipRows = param;
249848b8605Smrg      break;
250848b8605Smrg   case GL_PACK_SKIP_PIXELS:
251848b8605Smrg      if (param < 0) {
252848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
253848b8605Smrg         return;
254848b8605Smrg      }
255848b8605Smrg      state->storePack.skipPixels = param;
256848b8605Smrg      break;
257848b8605Smrg   case GL_PACK_SKIP_IMAGES:
258848b8605Smrg      if (param < 0) {
259848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
260848b8605Smrg         return;
261848b8605Smrg      }
262848b8605Smrg      state->storePack.skipImages = param;
263848b8605Smrg      break;
264848b8605Smrg   case GL_PACK_ALIGNMENT:
265848b8605Smrg      switch (param) {
266848b8605Smrg      case 1:
267848b8605Smrg      case 2:
268848b8605Smrg      case 4:
269848b8605Smrg      case 8:
270848b8605Smrg         state->storePack.alignment = param;
271848b8605Smrg         break;
272848b8605Smrg      default:
273848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
274848b8605Smrg         return;
275848b8605Smrg      }
276848b8605Smrg      break;
277848b8605Smrg   case GL_PACK_SWAP_BYTES:
278848b8605Smrg      state->storePack.swapEndian = (param != 0);
279848b8605Smrg      break;
280848b8605Smrg   case GL_PACK_LSB_FIRST:
281848b8605Smrg      state->storePack.lsbFirst = (param != 0);
282848b8605Smrg      break;
283848b8605Smrg
284848b8605Smrg   case GL_UNPACK_ROW_LENGTH:
285848b8605Smrg      if (param < 0) {
286848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
287848b8605Smrg         return;
288848b8605Smrg      }
289848b8605Smrg      state->storeUnpack.rowLength = param;
290848b8605Smrg      break;
291848b8605Smrg   case GL_UNPACK_IMAGE_HEIGHT:
292848b8605Smrg      if (param < 0) {
293848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
294848b8605Smrg         return;
295848b8605Smrg      }
296848b8605Smrg      state->storeUnpack.imageHeight = param;
297848b8605Smrg      break;
298848b8605Smrg   case GL_UNPACK_SKIP_ROWS:
299848b8605Smrg      if (param < 0) {
300848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
301848b8605Smrg         return;
302848b8605Smrg      }
303848b8605Smrg      state->storeUnpack.skipRows = param;
304848b8605Smrg      break;
305848b8605Smrg   case GL_UNPACK_SKIP_PIXELS:
306848b8605Smrg      if (param < 0) {
307848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
308848b8605Smrg         return;
309848b8605Smrg      }
310848b8605Smrg      state->storeUnpack.skipPixels = param;
311848b8605Smrg      break;
312848b8605Smrg   case GL_UNPACK_SKIP_IMAGES:
313848b8605Smrg      if (param < 0) {
314848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
315848b8605Smrg         return;
316848b8605Smrg      }
317848b8605Smrg      state->storeUnpack.skipImages = param;
318848b8605Smrg      break;
319848b8605Smrg   case GL_UNPACK_ALIGNMENT:
320848b8605Smrg      switch (param) {
321848b8605Smrg      case 1:
322848b8605Smrg      case 2:
323848b8605Smrg      case 4:
324848b8605Smrg      case 8:
325848b8605Smrg         state->storeUnpack.alignment = param;
326848b8605Smrg         break;
327848b8605Smrg      default:
328848b8605Smrg         __glXSetError(gc, GL_INVALID_VALUE);
329848b8605Smrg         return;
330848b8605Smrg      }
331848b8605Smrg      break;
332848b8605Smrg   case GL_UNPACK_SWAP_BYTES:
333848b8605Smrg      state->storeUnpack.swapEndian = (param != 0);
334848b8605Smrg      break;
335848b8605Smrg   case GL_UNPACK_LSB_FIRST:
336848b8605Smrg      state->storeUnpack.lsbFirst = (param != 0);
337848b8605Smrg      break;
338848b8605Smrg
339848b8605Smrg      /* Group all of the pixel store modes that need to be sent to the
340848b8605Smrg       * server here.  Care must be used to only send modes to the server that
341848b8605Smrg       * won't affect the size of the data sent to or received from the
342848b8605Smrg       * server.  GL_PACK_INVERT_MESA is safe in this respect, but other,
343848b8605Smrg       * future modes may not be.
344848b8605Smrg       */
345848b8605Smrg   case GL_PACK_INVERT_MESA:
346848b8605Smrg      send_PixelStore(gc, X_GLsop_PixelStorei, pname, &param);
347848b8605Smrg      break;
348848b8605Smrg
349848b8605Smrg   default:
350848b8605Smrg      __glXSetError(gc, GL_INVALID_ENUM);
351848b8605Smrg      break;
352848b8605Smrg   }
353848b8605Smrg}
354