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