Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 <stdio.h>
  32. #include <assert.h>
  33. #include "glxclient.h"
  34. #include "packsingle.h"
  35. #include "glxextensions.h"
  36. #include "indirect.h"
  37. #include "indirect_vertex_array.h"
  38. #include "glapi.h"
  39. #include <xcb/xcb.h>
  40. #include <xcb/glx.h>
  41. #include <X11/Xlib-xcb.h>
  42.  
  43. #if !defined(__GNUC__)
  44. #  define __builtin_expect(x, y) x
  45. #endif
  46.  
  47. /* Used for GL_ARB_transpose_matrix */
  48. static void
  49. TransposeMatrixf(GLfloat m[16])
  50. {
  51.    int i, j;
  52.    for (i = 0; i < 4; i++) {
  53.       for (j = 0; j < i; j++) {
  54.          GLfloat tmp = m[i * 4 + j];
  55.          m[i * 4 + j] = m[j * 4 + i];
  56.          m[j * 4 + i] = tmp;
  57.       }
  58.    }
  59. }
  60.  
  61. /* Used for GL_ARB_transpose_matrix */
  62. static void
  63. TransposeMatrixb(GLboolean m[16])
  64. {
  65.    int i, j;
  66.    for (i = 0; i < 4; i++) {
  67.       for (j = 0; j < i; j++) {
  68.          GLboolean tmp = m[i * 4 + j];
  69.          m[i * 4 + j] = m[j * 4 + i];
  70.          m[j * 4 + i] = tmp;
  71.       }
  72.    }
  73. }
  74.  
  75. /* Used for GL_ARB_transpose_matrix */
  76. static void
  77. TransposeMatrixd(GLdouble m[16])
  78. {
  79.    int i, j;
  80.    for (i = 0; i < 4; i++) {
  81.       for (j = 0; j < i; j++) {
  82.          GLdouble tmp = m[i * 4 + j];
  83.          m[i * 4 + j] = m[j * 4 + i];
  84.          m[j * 4 + i] = tmp;
  85.       }
  86.    }
  87. }
  88.  
  89. /* Used for GL_ARB_transpose_matrix */
  90. static void
  91. TransposeMatrixi(GLint m[16])
  92. {
  93.    int i, j;
  94.    for (i = 0; i < 4; i++) {
  95.       for (j = 0; j < i; j++) {
  96.          GLint tmp = m[i * 4 + j];
  97.          m[i * 4 + j] = m[j * 4 + i];
  98.          m[j * 4 + i] = tmp;
  99.       }
  100.    }
  101. }
  102.  
  103.  
  104. /**
  105.  * Remap a transpose-matrix enum to a non-transpose-matrix enum.  Enums
  106.  * that are not transpose-matrix enums are unaffected.
  107.  */
  108. static GLenum
  109. RemapTransposeEnum(GLenum e)
  110. {
  111.    switch (e) {
  112.    case GL_TRANSPOSE_MODELVIEW_MATRIX:
  113.    case GL_TRANSPOSE_PROJECTION_MATRIX:
  114.    case GL_TRANSPOSE_TEXTURE_MATRIX:
  115.       return e - (GL_TRANSPOSE_MODELVIEW_MATRIX - GL_MODELVIEW_MATRIX);
  116.    case GL_TRANSPOSE_COLOR_MATRIX:
  117.       return GL_COLOR_MATRIX;
  118.    default:
  119.       return e;
  120.    };
  121. }
  122.  
  123.  
  124. GLenum
  125. __indirect_glGetError(void)
  126. {
  127.    __GLX_SINGLE_DECLARE_VARIABLES();
  128.    GLuint retval = GL_NO_ERROR;
  129.    xGLXGetErrorReply reply;
  130.  
  131.    if (gc->error) {
  132.       /* Use internal error first */
  133.       retval = gc->error;
  134.       gc->error = GL_NO_ERROR;
  135.       return retval;
  136.    }
  137.  
  138.    __GLX_SINGLE_LOAD_VARIABLES();
  139.    __GLX_SINGLE_BEGIN(X_GLsop_GetError, 0);
  140.    __GLX_SINGLE_READ_XREPLY();
  141.    retval = reply.error;
  142.    __GLX_SINGLE_END();
  143.  
  144.    return retval;
  145. }
  146.  
  147.  
  148. /**
  149.  * Get the selected attribute from the client state.
  150.  *
  151.  * \returns
  152.  * On success \c GL_TRUE is returned.  Otherwise, \c GL_FALSE is returned.
  153.  */
  154. static GLboolean
  155. get_client_data(struct glx_context * gc, GLenum cap, GLintptr * data)
  156. {
  157.    GLboolean retval = GL_TRUE;
  158.    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
  159.    const GLint tex_unit = __glXGetActiveTextureUnit(state);
  160.  
  161.  
  162.    switch (cap) {
  163.    case GL_VERTEX_ARRAY:
  164.    case GL_NORMAL_ARRAY:
  165.    case GL_COLOR_ARRAY:
  166.    case GL_INDEX_ARRAY:
  167.    case GL_EDGE_FLAG_ARRAY:
  168.    case GL_SECONDARY_COLOR_ARRAY:
  169.    case GL_FOG_COORD_ARRAY:
  170.       retval = __glXGetArrayEnable(state, cap, 0, data);
  171.       break;
  172.  
  173.    case GL_VERTEX_ARRAY_SIZE:
  174.       retval = __glXGetArraySize(state, GL_VERTEX_ARRAY, 0, data);
  175.       break;
  176.    case GL_COLOR_ARRAY_SIZE:
  177.       retval = __glXGetArraySize(state, GL_COLOR_ARRAY, 0, data);
  178.       break;
  179.    case GL_SECONDARY_COLOR_ARRAY_SIZE:
  180.       retval = __glXGetArraySize(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
  181.       break;
  182.  
  183.    case GL_VERTEX_ARRAY_TYPE:
  184.       retval = __glXGetArrayType(state, GL_VERTEX_ARRAY, 0, data);
  185.       break;
  186.    case GL_NORMAL_ARRAY_TYPE:
  187.       retval = __glXGetArrayType(state, GL_NORMAL_ARRAY, 0, data);
  188.       break;
  189.    case GL_INDEX_ARRAY_TYPE:
  190.       retval = __glXGetArrayType(state, GL_INDEX_ARRAY, 0, data);
  191.       break;
  192.    case GL_COLOR_ARRAY_TYPE:
  193.       retval = __glXGetArrayType(state, GL_COLOR_ARRAY, 0, data);
  194.       break;
  195.    case GL_SECONDARY_COLOR_ARRAY_TYPE:
  196.       retval = __glXGetArrayType(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
  197.       break;
  198.    case GL_FOG_COORD_ARRAY_TYPE:
  199.       retval = __glXGetArrayType(state, GL_FOG_COORD_ARRAY, 0, data);
  200.       break;
  201.  
  202.    case GL_VERTEX_ARRAY_STRIDE:
  203.       retval = __glXGetArrayStride(state, GL_VERTEX_ARRAY, 0, data);
  204.       break;
  205.    case GL_NORMAL_ARRAY_STRIDE:
  206.       retval = __glXGetArrayStride(state, GL_NORMAL_ARRAY, 0, data);
  207.       break;
  208.    case GL_INDEX_ARRAY_STRIDE:
  209.       retval = __glXGetArrayStride(state, GL_INDEX_ARRAY, 0, data);
  210.       break;
  211.    case GL_EDGE_FLAG_ARRAY_STRIDE:
  212.       retval = __glXGetArrayStride(state, GL_EDGE_FLAG_ARRAY, 0, data);
  213.       break;
  214.    case GL_COLOR_ARRAY_STRIDE:
  215.       retval = __glXGetArrayStride(state, GL_COLOR_ARRAY, 0, data);
  216.       break;
  217.    case GL_SECONDARY_COLOR_ARRAY_STRIDE:
  218.       retval = __glXGetArrayStride(state, GL_SECONDARY_COLOR_ARRAY, 0, data);
  219.       break;
  220.    case GL_FOG_COORD_ARRAY_STRIDE:
  221.       retval = __glXGetArrayStride(state, GL_FOG_COORD_ARRAY, 0, data);
  222.       break;
  223.  
  224.    case GL_TEXTURE_COORD_ARRAY:
  225.       retval =
  226.          __glXGetArrayEnable(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
  227.       break;
  228.    case GL_TEXTURE_COORD_ARRAY_SIZE:
  229.       retval =
  230.          __glXGetArraySize(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
  231.       break;
  232.    case GL_TEXTURE_COORD_ARRAY_TYPE:
  233.       retval =
  234.          __glXGetArrayType(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
  235.       break;
  236.    case GL_TEXTURE_COORD_ARRAY_STRIDE:
  237.       retval =
  238.          __glXGetArrayStride(state, GL_TEXTURE_COORD_ARRAY, tex_unit, data);
  239.       break;
  240.  
  241.    case GL_MAX_ELEMENTS_VERTICES:
  242.    case GL_MAX_ELEMENTS_INDICES:
  243.       retval = GL_TRUE;
  244.       *data = ~0UL;
  245.       break;
  246.  
  247.  
  248.    case GL_PACK_ROW_LENGTH:
  249.       *data = (GLintptr) state->storePack.rowLength;
  250.       break;
  251.    case GL_PACK_IMAGE_HEIGHT:
  252.       *data = (GLintptr) state->storePack.imageHeight;
  253.       break;
  254.    case GL_PACK_SKIP_ROWS:
  255.       *data = (GLintptr) state->storePack.skipRows;
  256.       break;
  257.    case GL_PACK_SKIP_PIXELS:
  258.       *data = (GLintptr) state->storePack.skipPixels;
  259.       break;
  260.    case GL_PACK_SKIP_IMAGES:
  261.       *data = (GLintptr) state->storePack.skipImages;
  262.       break;
  263.    case GL_PACK_ALIGNMENT:
  264.       *data = (GLintptr) state->storePack.alignment;
  265.       break;
  266.    case GL_PACK_SWAP_BYTES:
  267.       *data = (GLintptr) state->storePack.swapEndian;
  268.       break;
  269.    case GL_PACK_LSB_FIRST:
  270.       *data = (GLintptr) state->storePack.lsbFirst;
  271.       break;
  272.    case GL_UNPACK_ROW_LENGTH:
  273.       *data = (GLintptr) state->storeUnpack.rowLength;
  274.       break;
  275.    case GL_UNPACK_IMAGE_HEIGHT:
  276.       *data = (GLintptr) state->storeUnpack.imageHeight;
  277.       break;
  278.    case GL_UNPACK_SKIP_ROWS:
  279.       *data = (GLintptr) state->storeUnpack.skipRows;
  280.       break;
  281.    case GL_UNPACK_SKIP_PIXELS:
  282.       *data = (GLintptr) state->storeUnpack.skipPixels;
  283.       break;
  284.    case GL_UNPACK_SKIP_IMAGES:
  285.       *data = (GLintptr) state->storeUnpack.skipImages;
  286.       break;
  287.    case GL_UNPACK_ALIGNMENT:
  288.       *data = (GLintptr) state->storeUnpack.alignment;
  289.       break;
  290.    case GL_UNPACK_SWAP_BYTES:
  291.       *data = (GLintptr) state->storeUnpack.swapEndian;
  292.       break;
  293.    case GL_UNPACK_LSB_FIRST:
  294.       *data = (GLintptr) state->storeUnpack.lsbFirst;
  295.       break;
  296.    case GL_CLIENT_ATTRIB_STACK_DEPTH:
  297.       *data = (GLintptr) (gc->attributes.stackPointer - gc->attributes.stack);
  298.       break;
  299.    case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
  300.       *data = (GLintptr) __GL_CLIENT_ATTRIB_STACK_DEPTH;
  301.       break;
  302.    case GL_CLIENT_ACTIVE_TEXTURE:
  303.       *data = (GLintptr) (tex_unit + GL_TEXTURE0);
  304.       break;
  305.  
  306.    default:
  307.       retval = GL_FALSE;
  308.       break;
  309.    }
  310.  
  311.  
  312.    return retval;
  313. }
  314.  
  315.  
  316. void
  317. __indirect_glGetBooleanv(GLenum val, GLboolean * b)
  318. {
  319.    const GLenum origVal = val;
  320.    __GLX_SINGLE_DECLARE_VARIABLES();
  321.    xGLXSingleReply reply;
  322.  
  323.    val = RemapTransposeEnum(val);
  324.  
  325.    __GLX_SINGLE_LOAD_VARIABLES();
  326.    __GLX_SINGLE_BEGIN(X_GLsop_GetBooleanv, 4);
  327.    __GLX_SINGLE_PUT_LONG(0, val);
  328.    __GLX_SINGLE_READ_XREPLY();
  329.    __GLX_SINGLE_GET_SIZE(compsize);
  330.  
  331.    if (compsize == 0) {
  332.       /*
  333.        ** Error occured; don't modify user's buffer.
  334.        */
  335.    }
  336.    else {
  337.       GLintptr data;
  338.  
  339.       /*
  340.        ** We still needed to send the request to the server in order to
  341.        ** find out whether it was legal to make a query (it's illegal,
  342.        ** for example, to call a query between glBegin() and glEnd()).
  343.        */
  344.  
  345.       if (get_client_data(gc, val, &data)) {
  346.          *b = (GLboolean) data;
  347.       }
  348.       else {
  349.          /*
  350.           ** Not a local value, so use what we got from the server.
  351.           */
  352.          if (compsize == 1) {
  353.             __GLX_SINGLE_GET_CHAR(b);
  354.          }
  355.          else {
  356.             __GLX_SINGLE_GET_CHAR_ARRAY(b, compsize);
  357.             if (val != origVal) {
  358.                /* matrix transpose */
  359.                TransposeMatrixb(b);
  360.             }
  361.          }
  362.       }
  363.    }
  364.    __GLX_SINGLE_END();
  365. }
  366.  
  367. void
  368. __indirect_glGetDoublev(GLenum val, GLdouble * d)
  369. {
  370.    const GLenum origVal = val;
  371.    __GLX_SINGLE_DECLARE_VARIABLES();
  372.    xGLXSingleReply reply;
  373.  
  374.    val = RemapTransposeEnum(val);
  375.  
  376.    __GLX_SINGLE_LOAD_VARIABLES();
  377.    __GLX_SINGLE_BEGIN(X_GLsop_GetDoublev, 4);
  378.    __GLX_SINGLE_PUT_LONG(0, val);
  379.    __GLX_SINGLE_READ_XREPLY();
  380.    __GLX_SINGLE_GET_SIZE(compsize);
  381.  
  382.    if (compsize == 0) {
  383.       /*
  384.        ** Error occured; don't modify user's buffer.
  385.        */
  386.    }
  387.    else {
  388.       GLintptr data;
  389.  
  390.       /*
  391.        ** We still needed to send the request to the server in order to
  392.        ** find out whether it was legal to make a query (it's illegal,
  393.        ** for example, to call a query between glBegin() and glEnd()).
  394.        */
  395.  
  396.       if (get_client_data(gc, val, &data)) {
  397.          *d = (GLdouble) data;
  398.       }
  399.       else {
  400.          /*
  401.           ** Not a local value, so use what we got from the server.
  402.           */
  403.          if (compsize == 1) {
  404.             __GLX_SINGLE_GET_DOUBLE(d);
  405.          }
  406.          else {
  407.             __GLX_SINGLE_GET_DOUBLE_ARRAY(d, compsize);
  408.             if (val != origVal) {
  409.                /* matrix transpose */
  410.                TransposeMatrixd(d);
  411.             }
  412.          }
  413.       }
  414.    }
  415.    __GLX_SINGLE_END();
  416. }
  417.  
  418. void
  419. __indirect_glGetFloatv(GLenum val, GLfloat * f)
  420. {
  421.    const GLenum origVal = val;
  422.    __GLX_SINGLE_DECLARE_VARIABLES();
  423.    xGLXSingleReply reply;
  424.  
  425.    val = RemapTransposeEnum(val);
  426.  
  427.    __GLX_SINGLE_LOAD_VARIABLES();
  428.    __GLX_SINGLE_BEGIN(X_GLsop_GetFloatv, 4);
  429.    __GLX_SINGLE_PUT_LONG(0, val);
  430.    __GLX_SINGLE_READ_XREPLY();
  431.    __GLX_SINGLE_GET_SIZE(compsize);
  432.  
  433.    if (compsize == 0) {
  434.       /*
  435.        ** Error occured; don't modify user's buffer.
  436.        */
  437.    }
  438.    else {
  439.       GLintptr data;
  440.  
  441.       /*
  442.        ** We still needed to send the request to the server in order to
  443.        ** find out whether it was legal to make a query (it's illegal,
  444.        ** for example, to call a query between glBegin() and glEnd()).
  445.        */
  446.  
  447.       if (get_client_data(gc, val, &data)) {
  448.          *f = (GLfloat) data;
  449.       }
  450.       else {
  451.          /*
  452.           ** Not a local value, so use what we got from the server.
  453.           */
  454.          if (compsize == 1) {
  455.             __GLX_SINGLE_GET_FLOAT(f);
  456.          }
  457.          else {
  458.             __GLX_SINGLE_GET_FLOAT_ARRAY(f, compsize);
  459.             if (val != origVal) {
  460.                /* matrix transpose */
  461.                TransposeMatrixf(f);
  462.             }
  463.          }
  464.       }
  465.    }
  466.    __GLX_SINGLE_END();
  467. }
  468.  
  469. void
  470. __indirect_glGetIntegerv(GLenum val, GLint * i)
  471. {
  472.    const GLenum origVal = val;
  473.    __GLX_SINGLE_DECLARE_VARIABLES();
  474.    xGLXSingleReply reply;
  475.  
  476.    val = RemapTransposeEnum(val);
  477.  
  478.    __GLX_SINGLE_LOAD_VARIABLES();
  479.    __GLX_SINGLE_BEGIN(X_GLsop_GetIntegerv, 4);
  480.    __GLX_SINGLE_PUT_LONG(0, val);
  481.    __GLX_SINGLE_READ_XREPLY();
  482.    __GLX_SINGLE_GET_SIZE(compsize);
  483.  
  484.    if (compsize == 0) {
  485.       /*
  486.        ** Error occured; don't modify user's buffer.
  487.        */
  488.    }
  489.    else {
  490.       GLintptr data;
  491.  
  492.       /*
  493.        ** We still needed to send the request to the server in order to
  494.        ** find out whether it was legal to make a query (it's illegal,
  495.        ** for example, to call a query between glBegin() and glEnd()).
  496.        */
  497.  
  498.       if (get_client_data(gc, val, &data)) {
  499.          *i = (GLint) data;
  500.       }
  501.       else {
  502.          /*
  503.           ** Not a local value, so use what we got from the server.
  504.           */
  505.          if (compsize == 1) {
  506.             __GLX_SINGLE_GET_LONG(i);
  507.          }
  508.          else {
  509.             __GLX_SINGLE_GET_LONG_ARRAY(i, compsize);
  510.             if (val != origVal) {
  511.                /* matrix transpose */
  512.                TransposeMatrixi(i);
  513.             }
  514.          }
  515.       }
  516.    }
  517.    __GLX_SINGLE_END();
  518. }
  519.  
  520. /*
  521. ** Send all pending commands to server.
  522. */
  523. void
  524. __indirect_glFlush(void)
  525. {
  526.    __GLX_SINGLE_DECLARE_VARIABLES();
  527.  
  528.    if (!dpy)
  529.       return;
  530.  
  531.    __GLX_SINGLE_LOAD_VARIABLES();
  532.    __GLX_SINGLE_BEGIN(X_GLsop_Flush, 0);
  533.    __GLX_SINGLE_END();
  534.  
  535.    /* And finally flush the X protocol data */
  536.    XFlush(dpy);
  537. }
  538.  
  539. void
  540. __indirect_glFeedbackBuffer(GLsizei size, GLenum type, GLfloat * buffer)
  541. {
  542.    __GLX_SINGLE_DECLARE_VARIABLES();
  543.  
  544.    if (!dpy)
  545.       return;
  546.  
  547.    __GLX_SINGLE_LOAD_VARIABLES();
  548.    __GLX_SINGLE_BEGIN(X_GLsop_FeedbackBuffer, 8);
  549.    __GLX_SINGLE_PUT_LONG(0, size);
  550.    __GLX_SINGLE_PUT_LONG(4, type);
  551.    __GLX_SINGLE_END();
  552.  
  553.    gc->feedbackBuf = buffer;
  554. }
  555.  
  556. void
  557. __indirect_glSelectBuffer(GLsizei numnames, GLuint * buffer)
  558. {
  559.    __GLX_SINGLE_DECLARE_VARIABLES();
  560.  
  561.    if (!dpy)
  562.       return;
  563.  
  564.    __GLX_SINGLE_LOAD_VARIABLES();
  565.    __GLX_SINGLE_BEGIN(X_GLsop_SelectBuffer, 4);
  566.    __GLX_SINGLE_PUT_LONG(0, numnames);
  567.    __GLX_SINGLE_END();
  568.  
  569.    gc->selectBuf = buffer;
  570. }
  571.  
  572. GLint
  573. __indirect_glRenderMode(GLenum mode)
  574. {
  575.    __GLX_SINGLE_DECLARE_VARIABLES();
  576.    GLint retval = 0;
  577.    xGLXRenderModeReply reply;
  578.  
  579.    if (!dpy)
  580.       return -1;
  581.  
  582.    __GLX_SINGLE_LOAD_VARIABLES();
  583.    __GLX_SINGLE_BEGIN(X_GLsop_RenderMode, 4);
  584.    __GLX_SINGLE_PUT_LONG(0, mode);
  585.    __GLX_SINGLE_READ_XREPLY();
  586.    __GLX_SINGLE_GET_RETVAL(retval, GLint);
  587.  
  588.    if (reply.newMode != mode) {
  589.       /*
  590.        ** Switch to new mode did not take effect, therefore an error
  591.        ** occured.  When an error happens the server won't send us any
  592.        ** other data.
  593.        */
  594.    }
  595.    else {
  596.       /* Read the feedback or selection data */
  597.       if (gc->renderMode == GL_FEEDBACK) {
  598.          __GLX_SINGLE_GET_SIZE(compsize);
  599.          __GLX_SINGLE_GET_FLOAT_ARRAY(gc->feedbackBuf, compsize);
  600.       }
  601.       else if (gc->renderMode == GL_SELECT) {
  602.          __GLX_SINGLE_GET_SIZE(compsize);
  603.          __GLX_SINGLE_GET_LONG_ARRAY(gc->selectBuf, compsize);
  604.       }
  605.       gc->renderMode = mode;
  606.    }
  607.    __GLX_SINGLE_END();
  608.  
  609.    return retval;
  610. }
  611.  
  612. void
  613. __indirect_glFinish(void)
  614. {
  615.    __GLX_SINGLE_DECLARE_VARIABLES();
  616.    xGLXSingleReply reply;
  617.  
  618.    __GLX_SINGLE_LOAD_VARIABLES();
  619.    __GLX_SINGLE_BEGIN(X_GLsop_Finish, 0);
  620.    __GLX_SINGLE_READ_XREPLY();
  621.    __GLX_SINGLE_END();
  622. }
  623.  
  624.  
  625. /**
  626.  * Extract the major and minor version numbers from a version string.
  627.  */
  628. static void
  629. version_from_string(const char *ver, int *major_version, int *minor_version)
  630. {
  631.    const char *end;
  632.    long major;
  633.    long minor;
  634.  
  635.    major = strtol(ver, (char **) &end, 10);
  636.    minor = strtol(end + 1, NULL, 10);
  637.    *major_version = major;
  638.    *minor_version = minor;
  639. }
  640.  
  641.  
  642. const GLubyte *
  643. __indirect_glGetString(GLenum name)
  644. {
  645.    struct glx_context *gc = __glXGetCurrentContext();
  646.    Display *dpy = gc->currentDpy;
  647.    GLubyte *s = NULL;
  648.  
  649.    if (!dpy)
  650.       return 0;
  651.  
  652.    /*
  653.     ** Return the cached copy if the string has already been fetched
  654.     */
  655.    switch (name) {
  656.    case GL_VENDOR:
  657.       if (gc->vendor)
  658.          return gc->vendor;
  659.       break;
  660.    case GL_RENDERER:
  661.       if (gc->renderer)
  662.          return gc->renderer;
  663.       break;
  664.    case GL_VERSION:
  665.       if (gc->version)
  666.          return gc->version;
  667.       break;
  668.    case GL_EXTENSIONS:
  669.       if (gc->extensions)
  670.          return gc->extensions;
  671.       break;
  672.    default:
  673.       __glXSetError(gc, GL_INVALID_ENUM);
  674.       return 0;
  675.    }
  676.  
  677.    /*
  678.     ** Get requested string from server
  679.     */
  680.  
  681.    (void) __glXFlushRenderBuffer(gc, gc->pc);
  682.    s = (GLubyte *) __glXGetString(dpy, gc->majorOpcode, gc->currentContextTag,
  683.                                   name);
  684.    if (!s) {
  685.       /* Throw data on the floor */
  686.       __glXSetError(gc, GL_OUT_OF_MEMORY);
  687.    }
  688.    else {
  689.       /*
  690.        ** Update local cache
  691.        */
  692.       switch (name) {
  693.       case GL_VENDOR:
  694.          gc->vendor = s;
  695.          break;
  696.  
  697.       case GL_RENDERER:
  698.          gc->renderer = s;
  699.          break;
  700.  
  701.       case GL_VERSION:{
  702.             int client_major;
  703.             int client_minor;
  704.  
  705.             version_from_string((char *) s,
  706.                                 &gc->server_major, &gc->server_minor);
  707.             __glXGetGLVersion(&client_major, &client_minor);
  708.  
  709.             if ((gc->server_major < client_major)
  710.                 || ((gc->server_major == client_major)
  711.                     && (gc->server_minor <= client_minor))) {
  712.                gc->version = s;
  713.             }
  714.             else {
  715.                /* Allow 7 bytes for the client-side GL version.  This allows
  716.                 * for upto version 999.999.  I'm not holding my breath for
  717.                 * that one!  The extra 4 is for the ' ()\0' that will be
  718.                 * added.
  719.                 */
  720.                const size_t size = 7 + strlen((char *) s) + 4;
  721.  
  722.                gc->version = malloc(size);
  723.                if (gc->version == NULL) {
  724.                   /* If we couldn't allocate memory for the new string,
  725.                    * make a best-effort and just copy the client-side version
  726.                    * to the string and use that.  It probably doesn't
  727.                    * matter what is done here.  If there not memory available
  728.                    * for a short string, the system is probably going to die
  729.                    * soon anyway.
  730.                    */
  731.                   snprintf((char *) s, strlen((char *) s) + 1, "%u.%u",
  732.                            client_major, client_minor);
  733.                   gc->version = s;
  734.                }
  735.                else {
  736.                   snprintf((char *) gc->version, size, "%u.%u (%s)",
  737.                            client_major, client_minor, s);
  738.                   free(s);
  739.                   s = gc->version;
  740.                }
  741.             }
  742.             break;
  743.          }
  744.  
  745.       case GL_EXTENSIONS:{
  746.             int major = 1;
  747.             int minor = 0;
  748.  
  749.             /* This code is currently disabled.  I was reminded that some
  750.              * vendors intentionally exclude some extensions from their
  751.              * extension string that are part of the core version they
  752.              * advertise.  In particular, on Nvidia drivers this means that
  753.              * the functionality is supported by the driver, but is not
  754.              * hardware accelerated.  For example, a TNT will show core
  755.              * version 1.5, but most of the post-1.2 functionality is a
  756.              * software fallback.
  757.              *
  758.              * I don't want to break applications that rely on this odd
  759.              * behavior.  At the same time, the code is written and tested,
  760.              * so I didn't want to throw it away.  Therefore, the code is here
  761.              * but disabled.  In the future, we may wish to and an environment
  762.              * variable to enable it.
  763.              */
  764.  
  765. #if 0
  766.             /* Call glGetString just to make sure that gc->server_major and
  767.              * gc->server_minor are set.  This version may be higher than we
  768.              * can completely support, but it may imply support for some
  769.              * extensions that we can support.
  770.              *
  771.              * For example, at the time of this writing, the client-side
  772.              * library only supports upto core GL version 1.2.  However, cubic
  773.              * textures, multitexture, multisampling, and some other 1.3
  774.              * features are supported.  If the server reports back version
  775.              * 1.3, but does not report all of those extensions, we will
  776.              * enable them.
  777.              */
  778.             (void *) glGetString(GL_VERSION);
  779.             major = gc->server_major, minor = gc->server_minor;
  780. #endif
  781.  
  782.             __glXCalculateUsableGLExtensions(gc, (char *) s, major, minor);
  783.             free(s);
  784.             s = gc->extensions;
  785.             break;
  786.          }
  787.       }
  788.    }
  789.    return s;
  790. }
  791.  
  792. GLboolean
  793. __indirect_glIsEnabled(GLenum cap)
  794. {
  795.    __GLX_SINGLE_DECLARE_VARIABLES();
  796.    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
  797.    xGLXSingleReply reply;
  798.    GLboolean retval = 0;
  799.    GLintptr enable;
  800.  
  801.    if (!dpy)
  802.       return 0;
  803.  
  804.    switch (cap) {
  805.    case GL_VERTEX_ARRAY:
  806.    case GL_NORMAL_ARRAY:
  807.    case GL_COLOR_ARRAY:
  808.    case GL_INDEX_ARRAY:
  809.    case GL_EDGE_FLAG_ARRAY:
  810.    case GL_SECONDARY_COLOR_ARRAY:
  811.    case GL_FOG_COORD_ARRAY:
  812.       retval = __glXGetArrayEnable(state, cap, 0, &enable);
  813.       assert(retval);
  814.       return (GLboolean) enable;
  815.       break;
  816.    case GL_TEXTURE_COORD_ARRAY:
  817.       retval = __glXGetArrayEnable(state, GL_TEXTURE_COORD_ARRAY,
  818.                                    __glXGetActiveTextureUnit(state), &enable);
  819.       assert(retval);
  820.       return (GLboolean) enable;
  821.       break;
  822.    }
  823.  
  824.    __GLX_SINGLE_LOAD_VARIABLES();
  825.    __GLX_SINGLE_BEGIN(X_GLsop_IsEnabled, 4);
  826.    __GLX_SINGLE_PUT_LONG(0, cap);
  827.    __GLX_SINGLE_READ_XREPLY();
  828.    __GLX_SINGLE_GET_RETVAL(retval, GLboolean);
  829.    __GLX_SINGLE_END();
  830.    return retval;
  831. }
  832.  
  833. void
  834. __indirect_glGetPointerv(GLenum pname, void **params)
  835. {
  836.    struct glx_context *gc = __glXGetCurrentContext();
  837.    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
  838.    Display *dpy = gc->currentDpy;
  839.  
  840.    if (!dpy)
  841.       return;
  842.  
  843.    switch (pname) {
  844.    case GL_VERTEX_ARRAY_POINTER:
  845.    case GL_NORMAL_ARRAY_POINTER:
  846.    case GL_COLOR_ARRAY_POINTER:
  847.    case GL_INDEX_ARRAY_POINTER:
  848.    case GL_EDGE_FLAG_ARRAY_POINTER:
  849.       __glXGetArrayPointer(state, pname - GL_VERTEX_ARRAY_POINTER
  850.                            + GL_VERTEX_ARRAY, 0, params);
  851.       return;
  852.    case GL_TEXTURE_COORD_ARRAY_POINTER:
  853.       __glXGetArrayPointer(state, GL_TEXTURE_COORD_ARRAY,
  854.                            __glXGetActiveTextureUnit(state), params);
  855.       return;
  856.    case GL_SECONDARY_COLOR_ARRAY_POINTER:
  857.    case GL_FOG_COORD_ARRAY_POINTER:
  858.       __glXGetArrayPointer(state, pname - GL_FOG_COORD_ARRAY_POINTER
  859.                            + GL_FOG_COORD_ARRAY, 0, params);
  860.       return;
  861.    case GL_FEEDBACK_BUFFER_POINTER:
  862.       *params = (void *) gc->feedbackBuf;
  863.       return;
  864.    case GL_SELECTION_BUFFER_POINTER:
  865.       *params = (void *) gc->selectBuf;
  866.       return;
  867.    default:
  868.       __glXSetError(gc, GL_INVALID_ENUM);
  869.       return;
  870.    }
  871. }
  872.  
  873.  
  874.  
  875. /**
  876.  * This was previously auto-generated, but we need to special-case
  877.  * how we handle writing into the 'residences' buffer when n%4!=0.
  878.  */
  879. #define X_GLsop_AreTexturesResident 143
  880. GLboolean
  881. __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
  882.                                  GLboolean * residences)
  883. {
  884.    struct glx_context *const gc = __glXGetCurrentContext();
  885.    Display *const dpy = gc->currentDpy;
  886.    GLboolean retval = (GLboolean) 0;
  887.    if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
  888.       xcb_connection_t *c = XGetXCBConnection(dpy);
  889.       xcb_glx_are_textures_resident_reply_t *reply;
  890.       (void) __glXFlushRenderBuffer(gc, gc->pc);
  891.       reply =
  892.          xcb_glx_are_textures_resident_reply(c,
  893.                                              xcb_glx_are_textures_resident
  894.                                              (c, gc->currentContextTag, n,
  895.                                               textures), NULL);
  896.       (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
  897.                     xcb_glx_are_textures_resident_data_length(reply) *
  898.                     sizeof(GLboolean));
  899.       retval = reply->ret_val;
  900.       free(reply);
  901.    }
  902.    return retval;
  903. }
  904.  
  905.  
  906. /**
  907.  * This was previously auto-generated, but we need to special-case
  908.  * how we handle writing into the 'residences' buffer when n%4!=0.
  909.  */
  910. #define X_GLvop_AreTexturesResidentEXT 11
  911. GLboolean
  912. glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
  913.                          GLboolean * residences)
  914. {
  915.    struct glx_context *const gc = __glXGetCurrentContext();
  916.  
  917.    if (gc->isDirect) {
  918.       const _glapi_proc *const table = (_glapi_proc *) GET_DISPATCH();
  919.       PFNGLARETEXTURESRESIDENTEXTPROC p =
  920.          (PFNGLARETEXTURESRESIDENTEXTPROC) table[332];
  921.  
  922.       return p(n, textures, residences);
  923.    }
  924.    else {
  925.       struct glx_context *const gc = __glXGetCurrentContext();
  926.       Display *const dpy = gc->currentDpy;
  927.       GLboolean retval = (GLboolean) 0;
  928.       const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
  929.       if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
  930.          GLubyte const *pc =
  931.             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
  932.                                     X_GLvop_AreTexturesResidentEXT,
  933.                                     cmdlen);
  934.          (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
  935.          (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
  936.          if (n & 3) {
  937.             /* see comments in __indirect_glAreTexturesResident() */
  938.             GLboolean *res4 = malloc((n + 3) & ~3);
  939.             retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
  940.             memcpy(residences, res4, n);
  941.             free(res4);
  942.          }
  943.          else {
  944.             retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
  945.          }
  946.          UnlockDisplay(dpy);
  947.          SyncHandle();
  948.       }
  949.       return retval;
  950.    }
  951. }
  952.