Home | History | Annotate | Download | only in glx
      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, &param);
    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, &param);
    347       break;
    348 
    349    default:
    350       __glXSetError(gc, GL_INVALID_ENUM);
    351       break;
    352    }
    353 }
    354