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 */ 49 static void 50 send_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 */ 68 void 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, ¶m); 210 break; 211 212 default: 213 __glXSetError(gc, GL_INVALID_ENUM); 214 break; 215 } 216 } 217 218 void 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, ¶m); 347 break; 348 349 default: 350 __glXSetError(gc, GL_INVALID_ENUM); 351 break; 352 } 353 } 354