Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  5.  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * 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.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23.  * OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26.  
  27. /**
  28.  * "Fake" GLX API implemented in terms of the XMesa*() functions.
  29.  */
  30.  
  31.  
  32.  
  33. #define GLX_GLXEXT_PROTOTYPES
  34. #include "GL/glx.h"
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <X11/Xmd.h>
  39. #include <GL/glxproto.h>
  40.  
  41. #include "xm_api.h"
  42.  
  43.  
  44. /* This indicates the client-side GLX API and GLX encoder version. */
  45. #define CLIENT_MAJOR_VERSION 1
  46. #define CLIENT_MINOR_VERSION 4  /* but don't have 1.3's pbuffers, etc yet */
  47.  
  48. /* This indicates the server-side GLX decoder version.
  49.  * GLX 1.4 indicates OpenGL 1.3 support
  50.  */
  51. #define SERVER_MAJOR_VERSION 1
  52. #define SERVER_MINOR_VERSION 4
  53.  
  54. /* Who implemented this GLX? */
  55. #define VENDOR "Brian Paul"
  56.  
  57. #define EXTENSIONS \
  58.    "GLX_MESA_copy_sub_buffer " \
  59.    "GLX_MESA_pixmap_colormap " \
  60.    "GLX_MESA_release_buffers " \
  61.    "GLX_ARB_create_context " \
  62.    "GLX_ARB_create_context_profile " \
  63.    "GLX_ARB_get_proc_address " \
  64.    "GLX_EXT_create_context_es_profile " \
  65.    "GLX_EXT_create_context_es2_profile " \
  66.    "GLX_EXT_texture_from_pixmap " \
  67.    "GLX_EXT_visual_info " \
  68.    "GLX_EXT_visual_rating " \
  69.    /*"GLX_SGI_video_sync "*/ \
  70.    "GLX_SGIX_fbconfig " \
  71.    "GLX_SGIX_pbuffer "
  72.  
  73. #define DEFAULT_DIRECT GL_TRUE
  74.  
  75.  
  76. /** XXX this could be based on gallium's max texture size */
  77. #define PBUFFER_MAX_SIZE 16384
  78.  
  79.  
  80. /**
  81.  * The GLXContext typedef is defined as a pointer to this structure.
  82.  */
  83. struct __GLXcontextRec
  84. {
  85.    Display *currentDpy;
  86.    GLboolean isDirect;
  87.    GLXDrawable currentDrawable;
  88.    GLXDrawable currentReadable;
  89.    XID xid;
  90.  
  91.    XMesaContext xmesaContext;
  92. };
  93.  
  94.  
  95.  
  96. static pipe_tsd ContextTSD;
  97.  
  98. /** Set current context for calling thread */
  99. static void
  100. SetCurrentContext(GLXContext c)
  101. {
  102.    pipe_tsd_set(&ContextTSD, c);
  103. }
  104.  
  105. /** Get current context for calling thread */
  106. static GLXContext
  107. GetCurrentContext(void)
  108. {
  109.    return pipe_tsd_get(&ContextTSD);
  110. }
  111.  
  112.  
  113.  
  114. /**********************************************************************/
  115. /***                       GLX Visual Code                          ***/
  116. /**********************************************************************/
  117.  
  118. #define DONT_CARE -1
  119.  
  120.  
  121. static XMesaVisual *VisualTable = NULL;
  122. static int NumVisuals = 0;
  123.  
  124.  
  125.  
  126. /* Macro to handle c_class vs class field name in XVisualInfo struct */
  127. #if defined(__cplusplus) || defined(c_plusplus)
  128. #define CLASS c_class
  129. #else
  130. #define CLASS class
  131. #endif
  132.  
  133.  
  134.  
  135. /*
  136.  * Test if the given XVisualInfo is usable for Mesa rendering.
  137.  */
  138. static GLboolean
  139. is_usable_visual( XVisualInfo *vinfo )
  140. {
  141.    switch (vinfo->CLASS) {
  142.       case StaticGray:
  143.       case GrayScale:
  144.          /* Any StaticGray/GrayScale visual works in RGB or CI mode */
  145.          return GL_TRUE;
  146.       case StaticColor:
  147.       case PseudoColor:
  148.          /* Any StaticColor/PseudoColor visual of at least 4 bits */
  149.          if (vinfo->depth>=4) {
  150.             return GL_TRUE;
  151.          }
  152.          else {
  153.             return GL_FALSE;
  154.          }
  155.       case TrueColor:
  156.       case DirectColor:
  157.          /* Any depth of TrueColor or DirectColor works in RGB mode */
  158.          return GL_TRUE;
  159.       default:
  160.          /* This should never happen */
  161.          return GL_FALSE;
  162.    }
  163. }
  164.  
  165.  
  166. /*
  167.  * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
  168.  * configuration in our list of GLX visuals.
  169.  */
  170. static XMesaVisual
  171. save_glx_visual( Display *dpy, XVisualInfo *vinfo,
  172.                  GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
  173.                  GLboolean stereoFlag,
  174.                  GLint depth_size, GLint stencil_size,
  175.                  GLint accumRedSize, GLint accumGreenSize,
  176.                  GLint accumBlueSize, GLint accumAlphaSize,
  177.                  GLint level, GLint numAuxBuffers )
  178. {
  179.    GLboolean ximageFlag = GL_TRUE;
  180.    XMesaVisual xmvis;
  181.    GLint i;
  182.    GLboolean comparePointers;
  183.  
  184.    if (dbFlag) {
  185.       /* Check if the MESA_BACK_BUFFER env var is set */
  186.       char *backbuffer = getenv("MESA_BACK_BUFFER");
  187.       if (backbuffer) {
  188.          if (backbuffer[0]=='p' || backbuffer[0]=='P') {
  189.             ximageFlag = GL_FALSE;
  190.          }
  191.          else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
  192.             ximageFlag = GL_TRUE;
  193.          }
  194.          else {
  195.             _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
  196.          }
  197.       }
  198.    }
  199.  
  200.    if (stereoFlag) {
  201.       /* stereo not supported */
  202.       return NULL;
  203.    }
  204.  
  205.    if (stencil_size > 0 && depth_size > 0)
  206.       depth_size = 24;
  207.  
  208.    /* Comparing IDs uses less memory but sometimes fails. */
  209.    /* XXX revisit this after 3.0 is finished. */
  210.    if (getenv("MESA_GLX_VISUAL_HACK"))
  211.       comparePointers = GL_TRUE;
  212.    else
  213.       comparePointers = GL_FALSE;
  214.  
  215.    /* Force the visual to have an alpha channel */
  216.    if (rgbFlag && getenv("MESA_GLX_FORCE_ALPHA"))
  217.       alphaFlag = GL_TRUE;
  218.  
  219.    /* First check if a matching visual is already in the list */
  220.    for (i=0; i<NumVisuals; i++) {
  221.       XMesaVisual v = VisualTable[i];
  222.       if (v->display == dpy
  223.           && v->mesa_visual.level == level
  224.           && v->mesa_visual.numAuxBuffers == numAuxBuffers
  225.           && v->ximage_flag == ximageFlag
  226.           && v->mesa_visual.rgbMode == rgbFlag
  227.           && v->mesa_visual.doubleBufferMode == dbFlag
  228.           && v->mesa_visual.stereoMode == stereoFlag
  229.           && (v->mesa_visual.alphaBits > 0) == alphaFlag
  230.           && (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
  231.           && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
  232.           && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
  233.           && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
  234.           && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
  235.           && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
  236.          /* now either compare XVisualInfo pointers or visual IDs */
  237.          if ((!comparePointers && v->visinfo->visualid == vinfo->visualid)
  238.              || (comparePointers && v->vishandle == vinfo)) {
  239.             return v;
  240.          }
  241.       }
  242.    }
  243.  
  244.    /* Create a new visual and add it to the list. */
  245.  
  246.    xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
  247.                               stereoFlag, ximageFlag,
  248.                               depth_size, stencil_size,
  249.                               accumRedSize, accumBlueSize,
  250.                               accumBlueSize, accumAlphaSize, 0, level,
  251.                               GLX_NONE_EXT );
  252.    if (xmvis) {
  253.       /* Save a copy of the pointer now so we can find this visual again
  254.        * if we need to search for it in find_glx_visual().
  255.        */
  256.       xmvis->vishandle = vinfo;
  257.       /* Allocate more space for additional visual */
  258.       VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1));
  259.       /* add xmvis to the list */
  260.       VisualTable[NumVisuals] = xmvis;
  261.       NumVisuals++;
  262.       /* XXX minor hack, because XMesaCreateVisual doesn't support an
  263.        * aux buffers parameter.
  264.        */
  265.       xmvis->mesa_visual.numAuxBuffers = numAuxBuffers;
  266.    }
  267.    return xmvis;
  268. }
  269.  
  270.  
  271. /**
  272.  * Return the default number of bits for the Z buffer.
  273.  * If defined, use the MESA_GLX_DEPTH_BITS env var value.
  274.  * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant.
  275.  * XXX probably do the same thing for stencil, accum, etc.
  276.  */
  277. static GLint
  278. default_depth_bits(void)
  279. {
  280.    int zBits;
  281.    const char *zEnv = getenv("MESA_GLX_DEPTH_BITS");
  282.    if (zEnv)
  283.       zBits = atoi(zEnv);
  284.    else
  285.       zBits = 24;
  286.    return zBits;
  287. }
  288.  
  289. static GLint
  290. default_alpha_bits(void)
  291. {
  292.    int aBits;
  293.    const char *aEnv = getenv("MESA_GLX_ALPHA_BITS");
  294.    if (aEnv)
  295.       aBits = atoi(aEnv);
  296.    else
  297.       aBits = 0;
  298.    return aBits;
  299. }
  300.  
  301. static GLint
  302. default_accum_bits(void)
  303. {
  304.    return 16;
  305. }
  306.  
  307.  
  308.  
  309. /*
  310.  * Create a GLX visual from a regular XVisualInfo.
  311.  * This is called when Fake GLX is given an XVisualInfo which wasn't
  312.  * returned by glXChooseVisual.  Since this is the first time we're
  313.  * considering this visual we'll take a guess at reasonable values
  314.  * for depth buffer size, stencil size, accum size, etc.
  315.  * This is the best we can do with a client-side emulation of GLX.
  316.  */
  317. static XMesaVisual
  318. create_glx_visual( Display *dpy, XVisualInfo *visinfo )
  319. {
  320.    GLint zBits = default_depth_bits();
  321.    GLint accBits = default_accum_bits();
  322.    GLboolean alphaFlag = default_alpha_bits() > 0;
  323.  
  324.    if (is_usable_visual( visinfo )) {
  325.       /* Configure this visual as RGB, double-buffered, depth-buffered. */
  326.       /* This is surely wrong for some people's needs but what else */
  327.       /* can be done?  They should use glXChooseVisual(). */
  328.       return save_glx_visual( dpy, visinfo,
  329.                               GL_TRUE,   /* rgb */
  330.                               alphaFlag, /* alpha */
  331.                               GL_TRUE,   /* double */
  332.                               GL_FALSE,  /* stereo */
  333.                               zBits,
  334.                               8,       /* stencil bits */
  335.                               accBits, /* r */
  336.                               accBits, /* g */
  337.                               accBits, /* b */
  338.                               accBits, /* a */
  339.                               0,         /* level */
  340.                               0          /* numAux */
  341.          );
  342.    }
  343.    else {
  344.       _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
  345.       return NULL;
  346.    }
  347. }
  348.  
  349.  
  350.  
  351. /*
  352.  * Find the GLX visual associated with an XVisualInfo.
  353.  */
  354. static XMesaVisual
  355. find_glx_visual( Display *dpy, XVisualInfo *vinfo )
  356. {
  357.    int i;
  358.  
  359.    /* try to match visual id */
  360.    for (i=0;i<NumVisuals;i++) {
  361.       if (VisualTable[i]->display==dpy
  362.           && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
  363.          return VisualTable[i];
  364.       }
  365.    }
  366.  
  367.    /* if that fails, try to match pointers */
  368.    for (i=0;i<NumVisuals;i++) {
  369.       if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
  370.          return VisualTable[i];
  371.       }
  372.    }
  373.  
  374.    return NULL;
  375. }
  376.  
  377.  
  378. /**
  379.  * Try to get an X visual which matches the given arguments.
  380.  */
  381. static XVisualInfo *
  382. get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
  383. {
  384.    XVisualInfo temp, *vis;
  385.    long mask;
  386.    int n;
  387.    unsigned int default_depth;
  388.    int default_class;
  389.  
  390.    mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
  391.    temp.screen = scr;
  392.    temp.depth = depth;
  393.    temp.CLASS = xclass;
  394.  
  395.    default_depth = DefaultDepth(dpy,scr);
  396.    default_class = DefaultVisual(dpy,scr)->CLASS;
  397.  
  398.    if (depth==default_depth && xclass==default_class) {
  399.       /* try to get root window's visual */
  400.       temp.visualid = DefaultVisual(dpy,scr)->visualid;
  401.       mask |= VisualIDMask;
  402.    }
  403.  
  404.    vis = XGetVisualInfo( dpy, mask, &temp, &n );
  405.  
  406.    /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
  407.     * An SGI Infinite Reality system, for example, can have 30bpp pixels:
  408.     * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
  409.     */
  410.    if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
  411.       if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
  412.           _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
  413.           _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
  414.          return vis;
  415.       }
  416.       else {
  417.          free((void *) vis);
  418.          return NULL;
  419.       }
  420.    }
  421.    
  422.    return vis;
  423. }
  424.  
  425.  
  426. /*
  427.  * Retrieve the value of the given environment variable and find
  428.  * the X visual which matches it.
  429.  * Input:  dpy - the display
  430.  *         screen - the screen number
  431.  *         varname - the name of the environment variable
  432.  * Return:  an XVisualInfo pointer to NULL if error.
  433.  */
  434. static XVisualInfo *
  435. get_env_visual(Display *dpy, int scr, const char *varname)
  436. {
  437.    char value[100], type[100];
  438.    int depth, xclass = -1;
  439.    XVisualInfo *vis;
  440.  
  441.    if (!getenv( varname )) {
  442.       return NULL;
  443.    }
  444.  
  445.    strncpy( value, getenv(varname), 100 );
  446.    value[99] = 0;
  447.  
  448.    sscanf( value, "%s %d", type, &depth );
  449.  
  450.    if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
  451.    else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
  452.    else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
  453.    else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
  454.    else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
  455.    else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
  456.  
  457.    if (xclass>-1 && depth>0) {
  458.       vis = get_visual( dpy, scr, depth, xclass );
  459.       if (vis) {
  460.          return vis;
  461.       }
  462.    }
  463.  
  464.    _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
  465.                  type, depth);
  466.  
  467.    return NULL;
  468. }
  469.  
  470.  
  471.  
  472. /*
  473.  * Select an X visual which satisfies the RGBA flag and minimum depth.
  474.  * Input:  dpy,
  475.  *         screen - X display and screen number
  476.  *         min_depth - minimum visual depth
  477.  *         preferred_class - preferred GLX visual class or DONT_CARE
  478.  * Return:  pointer to an XVisualInfo or NULL.
  479.  */
  480. static XVisualInfo *
  481. choose_x_visual( Display *dpy, int screen, int min_depth,
  482.                  int preferred_class )
  483. {
  484.    XVisualInfo *vis;
  485.    int xclass, visclass = 0;
  486.    int depth;
  487.  
  488.    /* First see if the MESA_RGB_VISUAL env var is defined */
  489.    vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
  490.    if (vis) {
  491.       return vis;
  492.    }
  493.    /* Otherwise, search for a suitable visual */
  494.    if (preferred_class==DONT_CARE) {
  495.       for (xclass=0;xclass<6;xclass++) {
  496.          switch (xclass) {
  497.          case 0:  visclass = TrueColor;    break;
  498.          case 1:  visclass = DirectColor;  break;
  499.          case 2:  visclass = PseudoColor;  break;
  500.          case 3:  visclass = StaticColor;  break;
  501.          case 4:  visclass = GrayScale;    break;
  502.          case 5:  visclass = StaticGray;   break;
  503.          }
  504.          if (min_depth==0) {
  505.             /* start with shallowest */
  506.             for (depth=0;depth<=32;depth++) {
  507.                if (visclass==TrueColor && depth==8) {
  508.                   /* Special case:  try to get 8-bit PseudoColor before */
  509.                   /* 8-bit TrueColor */
  510.                   vis = get_visual( dpy, screen, 8, PseudoColor );
  511.                   if (vis) {
  512.                      return vis;
  513.                   }
  514.                }
  515.                vis = get_visual( dpy, screen, depth, visclass );
  516.                if (vis) {
  517.                   return vis;
  518.                }
  519.             }
  520.          }
  521.          else {
  522.             /* start with deepest */
  523.             for (depth=32;depth>=min_depth;depth--) {
  524.                if (visclass==TrueColor && depth==8) {
  525.                   /* Special case:  try to get 8-bit PseudoColor before */
  526.                   /* 8-bit TrueColor */
  527.                   vis = get_visual( dpy, screen, 8, PseudoColor );
  528.                   if (vis) {
  529.                      return vis;
  530.                   }
  531.                }
  532.                vis = get_visual( dpy, screen, depth, visclass );
  533.                if (vis) {
  534.                   return vis;
  535.                }
  536.             }
  537.          }
  538.       }
  539.    }
  540.    else {
  541.       /* search for a specific visual class */
  542.       switch (preferred_class) {
  543.       case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
  544.       case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
  545.       case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
  546.       case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
  547.       case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
  548.       case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
  549.       default:   return NULL;
  550.       }
  551.       if (min_depth==0) {
  552.          /* start with shallowest */
  553.          for (depth=0;depth<=32;depth++) {
  554.             vis = get_visual( dpy, screen, depth, visclass );
  555.             if (vis) {
  556.                return vis;
  557.             }
  558.          }
  559.       }
  560.       else {
  561.          /* start with deepest */
  562.          for (depth=32;depth>=min_depth;depth--) {
  563.             vis = get_visual( dpy, screen, depth, visclass );
  564.             if (vis) {
  565.                return vis;
  566.             }
  567.          }
  568.       }
  569.    }
  570.  
  571.    /* didn't find a visual */
  572.    return NULL;
  573. }
  574.  
  575.  
  576.  
  577.  
  578. /**********************************************************************/
  579. /***             Display-related functions                          ***/
  580. /**********************************************************************/
  581.  
  582.  
  583. /**
  584.  * Free all XMesaVisuals which are associated with the given display.
  585.  */
  586. static void
  587. destroy_visuals_on_display(Display *dpy)
  588. {
  589.    int i;
  590.    for (i = 0; i < NumVisuals; i++) {
  591.       if (VisualTable[i]->display == dpy) {
  592.          /* remove this visual */
  593.          int j;
  594.          free(VisualTable[i]);
  595.          for (j = i; j < NumVisuals - 1; j++)
  596.             VisualTable[j] = VisualTable[j + 1];
  597.          NumVisuals--;
  598.       }
  599.    }
  600. }
  601.  
  602.  
  603. /**
  604.  * Called from XCloseDisplay() to let us free our display-related data.
  605.  */
  606. static int
  607. close_display_callback(Display *dpy, XExtCodes *codes)
  608. {
  609.    xmesa_destroy_buffers_on_display(dpy);
  610.    destroy_visuals_on_display(dpy);
  611.    return 0;
  612. }
  613.  
  614.  
  615. /**
  616.  * Look for the named extension on given display and return a pointer
  617.  * to the _XExtension data, or NULL if extension not found.
  618.  */
  619. static _XExtension *
  620. lookup_extension(Display *dpy, const char *extName)
  621. {
  622.    _XExtension *ext;
  623.    for (ext = dpy->ext_procs; ext; ext = ext->next) {
  624.       if (ext->name && strcmp(ext->name, extName) == 0) {
  625.          return ext;
  626.       }
  627.    }
  628.    return NULL;
  629. }
  630.  
  631.  
  632. /**
  633.  * Whenever we're given a new Display pointer, call this function to
  634.  * register our close_display_callback function.
  635.  */
  636. static void
  637. register_with_display(Display *dpy)
  638. {
  639.    const char *extName = "MesaGLX";
  640.    _XExtension *ext;
  641.  
  642.    ext = lookup_extension(dpy, extName);
  643.    if (!ext) {
  644.       XExtCodes *c = XAddExtension(dpy);
  645.       ext = dpy->ext_procs;  /* new extension is at head of list */
  646.       assert(c->extension == ext->codes.extension);
  647.       (void) c;
  648.       ext->name = strdup(extName);
  649.       ext->close_display = close_display_callback;
  650.    }
  651. }
  652.  
  653.  
  654. /**
  655.  * Fake an error.
  656.  */
  657. static int
  658. generate_error(Display *dpy,
  659.                unsigned char error_code,
  660.                XID resourceid,
  661.                unsigned char minor_code,
  662.                Bool core)
  663. {
  664.    XErrorHandler handler;
  665.    int major_opcode;
  666.    int first_event;
  667.    int first_error;
  668.    XEvent event;
  669.  
  670.    handler = XSetErrorHandler(NULL);
  671.    XSetErrorHandler(handler);
  672.    if (!handler) {
  673.       return 0;
  674.    }
  675.  
  676.    if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_opcode, &first_event, &first_error)) {
  677.       major_opcode = 0;
  678.       first_event = 0;
  679.       first_error = 0;
  680.    }
  681.  
  682.    if (!core) {
  683.       error_code += first_error;
  684.    }
  685.  
  686.    memset(&event, 0, sizeof event);
  687.  
  688.    event.xerror.type = X_Error;
  689.    event.xerror.display = dpy;
  690.    event.xerror.resourceid = resourceid;
  691.    event.xerror.serial = NextRequest(dpy) - 1;
  692.    event.xerror.error_code = error_code;
  693.    event.xerror.request_code = major_opcode;
  694.    event.xerror.minor_code = minor_code;
  695.  
  696.    return handler(dpy, &event.xerror);
  697. }
  698.  
  699.  
  700. /**********************************************************************/
  701. /***                  Begin Fake GLX API Functions                  ***/
  702. /**********************************************************************/
  703.  
  704.  
  705. /**
  706.  * Helper used by glXChooseVisual and glXChooseFBConfig.
  707.  * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for
  708.  * the later.
  709.  * In either case, the attribute list is terminated with the value 'None'.
  710.  */
  711. static XMesaVisual
  712. choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
  713. {
  714.    const GLboolean rgbModeDefault = fbConfig;
  715.    const int *parselist;
  716.    XVisualInfo *vis;
  717.    int min_red=0, min_green=0, min_blue=0;
  718.    GLboolean rgb_flag = rgbModeDefault;
  719.    GLboolean alpha_flag = GL_FALSE;
  720.    GLboolean double_flag = GL_FALSE;
  721.    GLboolean stereo_flag = GL_FALSE;
  722.    GLint depth_size = 0;
  723.    GLint stencil_size = 0;
  724.    GLint accumRedSize = 0;
  725.    GLint accumGreenSize = 0;
  726.    GLint accumBlueSize = 0;
  727.    GLint accumAlphaSize = 0;
  728.    int level = 0;
  729.    int visual_type = DONT_CARE;
  730.    GLint caveat = DONT_CARE;
  731.    XMesaVisual xmvis = NULL;
  732.    int desiredVisualID = -1;
  733.    int numAux = 0;
  734.  
  735.    xmesa_init( dpy );
  736.  
  737.    parselist = list;
  738.  
  739.    while (*parselist) {
  740.  
  741.       if (fbConfig &&
  742.           parselist[1] == GLX_DONT_CARE &&
  743.           parselist[0] != GLX_LEVEL) {
  744.          /* For glXChooseFBConfig(), skip attributes whose value is
  745.           * GLX_DONT_CARE, unless it's GLX_LEVEL (which can legitimately be
  746.           * a negative value).
  747.           *
  748.           * From page 17 (23 of the pdf) of the GLX 1.4 spec:
  749.           * GLX DONT CARE may be specified for all attributes except GLX LEVEL.
  750.           */
  751.          parselist += 2;
  752.          continue;
  753.       }
  754.  
  755.       switch (*parselist) {
  756.          case GLX_USE_GL:
  757.             if (fbConfig) {
  758.                /* invalid token */
  759.                return NULL;
  760.             }
  761.             else {
  762.                /* skip */
  763.                parselist++;
  764.             }
  765.             break;
  766.          case GLX_BUFFER_SIZE:
  767.             parselist++;
  768.             parselist++;
  769.             break;
  770.          case GLX_LEVEL:
  771.             parselist++;
  772.             level = *parselist++;
  773.             break;
  774.          case GLX_RGBA:
  775.             if (fbConfig) {
  776.                /* invalid token */
  777.                return NULL;
  778.             }
  779.             else {
  780.                rgb_flag = GL_TRUE;
  781.                parselist++;
  782.             }
  783.             break;
  784.          case GLX_DOUBLEBUFFER:
  785.             parselist++;
  786.             if (fbConfig) {
  787.                double_flag = *parselist++;
  788.             }
  789.             else {
  790.                double_flag = GL_TRUE;
  791.             }
  792.             break;
  793.          case GLX_STEREO:
  794.             parselist++;
  795.             if (fbConfig) {
  796.                stereo_flag = *parselist++;
  797.             }
  798.             else {
  799.                stereo_flag = GL_TRUE;
  800.             }
  801.             break;
  802.          case GLX_AUX_BUFFERS:
  803.             parselist++;
  804.             numAux = *parselist++;
  805.             if (numAux > MAX_AUX_BUFFERS)
  806.                return NULL;
  807.             break;
  808.          case GLX_RED_SIZE:
  809.             parselist++;
  810.             min_red = *parselist++;
  811.             break;
  812.          case GLX_GREEN_SIZE:
  813.             parselist++;
  814.             min_green = *parselist++;
  815.             break;
  816.          case GLX_BLUE_SIZE:
  817.             parselist++;
  818.             min_blue = *parselist++;
  819.             break;
  820.          case GLX_ALPHA_SIZE:
  821.             parselist++;
  822.             {
  823.                GLint size = *parselist++;
  824.                alpha_flag = size ? GL_TRUE : GL_FALSE;
  825.             }
  826.             break;
  827.          case GLX_DEPTH_SIZE:
  828.             parselist++;
  829.             depth_size = *parselist++;
  830.             break;
  831.          case GLX_STENCIL_SIZE:
  832.             parselist++;
  833.             stencil_size = *parselist++;
  834.             break;
  835.          case GLX_ACCUM_RED_SIZE:
  836.             parselist++;
  837.             {
  838.                GLint size = *parselist++;
  839.                accumRedSize = MAX2( accumRedSize, size );
  840.             }
  841.             break;
  842.          case GLX_ACCUM_GREEN_SIZE:
  843.             parselist++;
  844.             {
  845.                GLint size = *parselist++;
  846.                accumGreenSize = MAX2( accumGreenSize, size );
  847.             }
  848.             break;
  849.          case GLX_ACCUM_BLUE_SIZE:
  850.             parselist++;
  851.             {
  852.                GLint size = *parselist++;
  853.                accumBlueSize = MAX2( accumBlueSize, size );
  854.             }
  855.             break;
  856.          case GLX_ACCUM_ALPHA_SIZE:
  857.             parselist++;
  858.             {
  859.                GLint size = *parselist++;
  860.                accumAlphaSize = MAX2( accumAlphaSize, size );
  861.             }
  862.             break;
  863.  
  864.          /*
  865.           * GLX_EXT_visual_info extension
  866.           */
  867.          case GLX_X_VISUAL_TYPE_EXT:
  868.             parselist++;
  869.             visual_type = *parselist++;
  870.             break;
  871.          case GLX_TRANSPARENT_TYPE_EXT:
  872.             parselist++;
  873.             parselist++;
  874.             break;
  875.          case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  876.             parselist++;
  877.             parselist++;
  878.             break;
  879.          case GLX_TRANSPARENT_RED_VALUE_EXT:
  880.          case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  881.          case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  882.          case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  883.             /* ignore */
  884.             parselist++;
  885.             parselist++;
  886.             break;
  887.  
  888.          /*
  889.           * GLX_EXT_visual_info extension
  890.           */
  891.          case GLX_VISUAL_CAVEAT_EXT:
  892.             parselist++;
  893.             caveat = *parselist++; /* ignored for now */
  894.             break;
  895.  
  896.          /*
  897.           * GLX_ARB_multisample
  898.           */
  899.          case GLX_SAMPLE_BUFFERS_ARB:
  900.          case GLX_SAMPLES_ARB:
  901.             parselist++;
  902.             if (*parselist++ != 0) {
  903.                /* ms not supported */
  904.                return NULL;
  905.             }
  906.             break;
  907.  
  908.          /*
  909.           * FBConfig attribs.
  910.           */
  911.          case GLX_RENDER_TYPE:
  912.             if (!fbConfig)
  913.                return NULL;
  914.             parselist++;
  915.             if (*parselist & GLX_RGBA_BIT) {
  916.                rgb_flag = GL_TRUE;
  917.             }
  918.             else if (*parselist & GLX_COLOR_INDEX_BIT) {
  919.                rgb_flag = GL_FALSE;
  920.             }
  921.             else if (*parselist == 0) {
  922.                rgb_flag = GL_TRUE;
  923.             }
  924.             parselist++;
  925.             break;
  926.          case GLX_DRAWABLE_TYPE:
  927.             if (!fbConfig)
  928.                return NULL;
  929.             parselist++;
  930.             if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
  931.                return NULL; /* bad bit */
  932.             }
  933.             parselist++;
  934.             break;
  935.          case GLX_FBCONFIG_ID:
  936.          case GLX_VISUAL_ID:
  937.             if (!fbConfig)
  938.                return NULL;
  939.             parselist++;
  940.             desiredVisualID = *parselist++;
  941.             break;
  942.          case GLX_X_RENDERABLE:
  943.          case GLX_MAX_PBUFFER_WIDTH:
  944.          case GLX_MAX_PBUFFER_HEIGHT:
  945.          case GLX_MAX_PBUFFER_PIXELS:
  946.             if (!fbConfig)
  947.                return NULL; /* invalid config option */
  948.             parselist += 2; /* ignore the parameter */
  949.             break;
  950.  
  951. #ifdef GLX_EXT_texture_from_pixmap
  952.          case GLX_BIND_TO_TEXTURE_RGB_EXT:
  953.             parselist++; /*skip*/
  954.             break;
  955.          case GLX_BIND_TO_TEXTURE_RGBA_EXT:
  956.             parselist++; /*skip*/
  957.             break;
  958.          case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
  959.             parselist++; /*skip*/
  960.             break;
  961.          case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
  962.             parselist++;
  963.             if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
  964.                                GLX_TEXTURE_2D_BIT_EXT |
  965.                                GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
  966.                /* invalid bit */
  967.                return NULL;
  968.             }
  969.             break;
  970.          case GLX_Y_INVERTED_EXT:
  971.             parselist++; /*skip*/
  972.             break;
  973. #endif
  974.  
  975.          case None:
  976.             /* end of list */
  977.             break;
  978.  
  979.          default:
  980.             /* undefined attribute */
  981.             _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
  982.                           *parselist);
  983.             return NULL;
  984.       }
  985.    }
  986.  
  987.    (void) caveat;
  988.  
  989.  
  990.    /*
  991.     * Since we're only simulating the GLX extension this function will never
  992.     * find any real GL visuals.  Instead, all we can do is try to find an RGB
  993.     * or CI visual of appropriate depth.  Other requested attributes such as
  994.     * double buffering, depth buffer, etc. will be associated with the X
  995.     * visual and stored in the VisualTable[].
  996.     */
  997.    if (desiredVisualID != -1) {
  998.       /* try to get a specific visual, by visualID */
  999.       XVisualInfo temp;
  1000.       int n;
  1001.       temp.visualid = desiredVisualID;
  1002.       temp.screen = screen;
  1003.       vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
  1004.       if (vis) {
  1005.          /* give the visual some useful GLX attributes */
  1006.          double_flag = GL_TRUE;
  1007.          rgb_flag = GL_TRUE;
  1008.       }
  1009.    }
  1010.    else if (level==0) {
  1011.       /* normal color planes */
  1012.       /* Get an RGB visual */
  1013.       int min_rgb = min_red + min_green + min_blue;
  1014.       if (min_rgb>1 && min_rgb<8) {
  1015.          /* a special case to be sure we can get a monochrome visual */
  1016.          min_rgb = 1;
  1017.       }
  1018.       vis = choose_x_visual( dpy, screen, min_rgb, visual_type );
  1019.    }
  1020.    else {
  1021.       _mesa_warning(NULL, "overlay not supported");
  1022.       return NULL;
  1023.    }
  1024.  
  1025.    if (vis) {
  1026.       /* Note: we're not exactly obeying the glXChooseVisual rules here.
  1027.        * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
  1028.        * largest depth buffer size, which is 32bits/value.  Instead, we
  1029.        * return 16 to maintain performance with earlier versions of Mesa.
  1030.        */
  1031.       if (stencil_size > 0)
  1032.          depth_size = 24;  /* if Z and stencil, always use 24+8 format */
  1033.       else if (depth_size > 24)
  1034.          depth_size = 32;
  1035.       else if (depth_size > 16)
  1036.          depth_size = 24;
  1037.       else if (depth_size > 0) {
  1038.          depth_size = default_depth_bits();
  1039.       }
  1040.  
  1041.       if (!alpha_flag) {
  1042.          alpha_flag = default_alpha_bits() > 0;
  1043.       }
  1044.  
  1045.       /* we only support one size of stencil and accum buffers. */
  1046.       if (stencil_size > 0)
  1047.          stencil_size = 8;
  1048.  
  1049.       if (accumRedSize > 0 ||
  1050.           accumGreenSize > 0 ||
  1051.           accumBlueSize > 0 ||
  1052.           accumAlphaSize > 0) {
  1053.  
  1054.          accumRedSize =
  1055.             accumGreenSize =
  1056.             accumBlueSize = default_accum_bits();
  1057.  
  1058.          accumAlphaSize = alpha_flag ? accumRedSize : 0;
  1059.       }
  1060.  
  1061.       xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
  1062.                                stereo_flag, depth_size, stencil_size,
  1063.                                accumRedSize, accumGreenSize,
  1064.                                accumBlueSize, accumAlphaSize, level, numAux );
  1065.    }
  1066.  
  1067.    return xmvis;
  1068. }
  1069.  
  1070.  
  1071. PUBLIC XVisualInfo *
  1072. glXChooseVisual( Display *dpy, int screen, int *list )
  1073. {
  1074.    XMesaVisual xmvis;
  1075.  
  1076.    /* register ourselves as an extension on this display */
  1077.    register_with_display(dpy);
  1078.  
  1079.    xmvis = choose_visual(dpy, screen, list, GL_FALSE);
  1080.    if (xmvis) {
  1081.       /* create a new vishandle - the cached one may be stale */
  1082.       xmvis->vishandle = malloc(sizeof(XVisualInfo));
  1083.       if (xmvis->vishandle) {
  1084.          memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
  1085.       }
  1086.       return xmvis->vishandle;
  1087.    }
  1088.    else
  1089.       return NULL;
  1090. }
  1091.  
  1092.  
  1093. /**
  1094.  * Helper function used by other glXCreateContext functions.
  1095.  */
  1096. static GLXContext
  1097. create_context(Display *dpy, XMesaVisual xmvis,
  1098.                XMesaContext shareCtx, Bool direct,
  1099.                unsigned major, unsigned minor,
  1100.                unsigned profileMask, unsigned contextFlags)
  1101. {
  1102.    GLXContext glxCtx;
  1103.  
  1104.    if (!dpy || !xmvis)
  1105.       return 0;
  1106.  
  1107.    glxCtx = CALLOC_STRUCT(__GLXcontextRec);
  1108.    if (!glxCtx)
  1109.       return 0;
  1110.  
  1111.    /* deallocate unused windows/buffers */
  1112. #if 0
  1113.    XMesaGarbageCollect();
  1114. #endif
  1115.  
  1116.    glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
  1117.                                              profileMask, contextFlags);
  1118.    if (!glxCtx->xmesaContext) {
  1119.       free(glxCtx);
  1120.       return NULL;
  1121.    }
  1122.  
  1123.    glxCtx->isDirect = DEFAULT_DIRECT;
  1124.    glxCtx->currentDpy = dpy;
  1125.    glxCtx->xid = (XID) glxCtx;  /* self pointer */
  1126.  
  1127.    return glxCtx;
  1128. }
  1129.  
  1130.  
  1131. PUBLIC GLXContext
  1132. glXCreateContext( Display *dpy, XVisualInfo *visinfo,
  1133.                   GLXContext shareCtx, Bool direct )
  1134. {
  1135.    XMesaVisual xmvis;
  1136.  
  1137.    xmvis = find_glx_visual( dpy, visinfo );
  1138.    if (!xmvis) {
  1139.       /* This visual wasn't found with glXChooseVisual() */
  1140.       xmvis = create_glx_visual( dpy, visinfo );
  1141.       if (!xmvis) {
  1142.          /* unusable visual */
  1143.          return NULL;
  1144.       }
  1145.    }
  1146.  
  1147.    return create_context(dpy, xmvis,
  1148.                          shareCtx ? shareCtx->xmesaContext : NULL,
  1149.                          direct,
  1150.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  1151. }
  1152.  
  1153.  
  1154. /* XXX these may have to be removed due to thread-safety issues. */
  1155. static GLXContext MakeCurrent_PrevContext = 0;
  1156. static GLXDrawable MakeCurrent_PrevDrawable = 0;
  1157. static GLXDrawable MakeCurrent_PrevReadable = 0;
  1158. static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
  1159. static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
  1160.  
  1161.  
  1162. /* GLX 1.3 and later */
  1163. PUBLIC Bool
  1164. glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
  1165.                        GLXDrawable read, GLXContext ctx )
  1166. {
  1167.    GLXContext glxCtx = ctx;
  1168.    static boolean firsttime = 1, no_rast = 0;
  1169.  
  1170.    if (firsttime) {
  1171.       no_rast = getenv("SP_NO_RAST") != NULL;
  1172.       firsttime = 0;
  1173.    }
  1174.  
  1175.    if (ctx && draw && read) {
  1176.       XMesaBuffer drawBuffer, readBuffer;
  1177.       XMesaContext xmctx = glxCtx->xmesaContext;
  1178.  
  1179.       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
  1180.       if (ctx == MakeCurrent_PrevContext
  1181.           && draw == MakeCurrent_PrevDrawable) {
  1182.          drawBuffer = MakeCurrent_PrevDrawBuffer;
  1183.       }
  1184.       else {
  1185.          drawBuffer = XMesaFindBuffer( dpy, draw );
  1186.       }
  1187.       if (!drawBuffer) {
  1188.          /* drawable must be a new window! */
  1189.          drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
  1190.          if (!drawBuffer) {
  1191.             /* Out of memory, or context/drawable depth mismatch */
  1192.             return False;
  1193.          }
  1194.       }
  1195.  
  1196.       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
  1197.       if (ctx == MakeCurrent_PrevContext
  1198.           && read == MakeCurrent_PrevReadable) {
  1199.          readBuffer = MakeCurrent_PrevReadBuffer;
  1200.       }
  1201.       else {
  1202.          readBuffer = XMesaFindBuffer( dpy, read );
  1203.       }
  1204.       if (!readBuffer) {
  1205.          /* drawable must be a new window! */
  1206.          readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
  1207.          if (!readBuffer) {
  1208.             /* Out of memory, or context/drawable depth mismatch */
  1209.             return False;
  1210.          }
  1211.       }
  1212.  
  1213.       if (no_rast &&
  1214.           MakeCurrent_PrevContext == ctx &&
  1215.           MakeCurrent_PrevDrawable == draw &&
  1216.           MakeCurrent_PrevReadable == read &&
  1217.           MakeCurrent_PrevDrawBuffer == drawBuffer &&
  1218.           MakeCurrent_PrevReadBuffer == readBuffer)
  1219.          return True;
  1220.          
  1221.       MakeCurrent_PrevContext = ctx;
  1222.       MakeCurrent_PrevDrawable = draw;
  1223.       MakeCurrent_PrevReadable = read;
  1224.       MakeCurrent_PrevDrawBuffer = drawBuffer;
  1225.       MakeCurrent_PrevReadBuffer = readBuffer;
  1226.  
  1227.       /* Now make current! */
  1228.       if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
  1229.          ctx->currentDpy = dpy;
  1230.          ctx->currentDrawable = draw;
  1231.          ctx->currentReadable = read;
  1232.          SetCurrentContext(ctx);
  1233.          return True;
  1234.       }
  1235.       else {
  1236.          return False;
  1237.       }
  1238.    }
  1239.    else if (!ctx && !draw && !read) {
  1240.       /* release current context w/out assigning new one. */
  1241.       XMesaMakeCurrent2( NULL, NULL, NULL );
  1242.       MakeCurrent_PrevContext = 0;
  1243.       MakeCurrent_PrevDrawable = 0;
  1244.       MakeCurrent_PrevReadable = 0;
  1245.       MakeCurrent_PrevDrawBuffer = 0;
  1246.       MakeCurrent_PrevReadBuffer = 0;
  1247.       SetCurrentContext(NULL);
  1248.       return True;
  1249.    }
  1250.    else {
  1251.       /* The args must either all be non-zero or all zero.
  1252.        * This is an error.
  1253.        */
  1254.       return False;
  1255.    }
  1256. }
  1257.  
  1258.  
  1259. PUBLIC Bool
  1260. glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
  1261. {
  1262.    return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
  1263. }
  1264.  
  1265.  
  1266. PUBLIC GLXContext
  1267. glXGetCurrentContext(void)
  1268. {
  1269.    return GetCurrentContext();
  1270. }
  1271.  
  1272.  
  1273. PUBLIC Display *
  1274. glXGetCurrentDisplay(void)
  1275. {
  1276.    GLXContext glxCtx = glXGetCurrentContext();
  1277.  
  1278.    return glxCtx ? glxCtx->currentDpy : NULL;
  1279. }
  1280.  
  1281.  
  1282. PUBLIC Display *
  1283. glXGetCurrentDisplayEXT(void)
  1284. {
  1285.    return glXGetCurrentDisplay();
  1286. }
  1287.  
  1288.  
  1289. PUBLIC GLXDrawable
  1290. glXGetCurrentDrawable(void)
  1291. {
  1292.    GLXContext gc = glXGetCurrentContext();
  1293.    return gc ? gc->currentDrawable : 0;
  1294. }
  1295.  
  1296.  
  1297. PUBLIC GLXDrawable
  1298. glXGetCurrentReadDrawable(void)
  1299. {
  1300.    GLXContext gc = glXGetCurrentContext();
  1301.    return gc ? gc->currentReadable : 0;
  1302. }
  1303.  
  1304.  
  1305. PUBLIC GLXDrawable
  1306. glXGetCurrentReadDrawableSGI(void)
  1307. {
  1308.    return glXGetCurrentReadDrawable();
  1309. }
  1310.  
  1311.  
  1312. PUBLIC GLXPixmap
  1313. glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
  1314. {
  1315.    XMesaVisual v;
  1316.    XMesaBuffer b;
  1317.  
  1318.    v = find_glx_visual( dpy, visinfo );
  1319.    if (!v) {
  1320.       v = create_glx_visual( dpy, visinfo );
  1321.       if (!v) {
  1322.          /* unusable visual */
  1323.          return 0;
  1324.       }
  1325.    }
  1326.  
  1327.    b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
  1328.    if (!b) {
  1329.       return 0;
  1330.    }
  1331.    return b->ws.drawable;
  1332. }
  1333.  
  1334.  
  1335. /*** GLX_MESA_pixmap_colormap ***/
  1336.  
  1337. PUBLIC GLXPixmap
  1338. glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
  1339.                         Pixmap pixmap, Colormap cmap )
  1340. {
  1341.    XMesaVisual v;
  1342.    XMesaBuffer b;
  1343.  
  1344.    v = find_glx_visual( dpy, visinfo );
  1345.    if (!v) {
  1346.       v = create_glx_visual( dpy, visinfo );
  1347.       if (!v) {
  1348.          /* unusable visual */
  1349.          return 0;
  1350.       }
  1351.    }
  1352.  
  1353.    b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
  1354.    if (!b) {
  1355.       return 0;
  1356.    }
  1357.    return b->ws.drawable;
  1358. }
  1359.  
  1360.  
  1361. PUBLIC void
  1362. glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
  1363. {
  1364.    XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
  1365.    if (b) {
  1366.       XMesaDestroyBuffer(b);
  1367.    }
  1368.    else if (getenv("MESA_DEBUG")) {
  1369.       _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
  1370.    }
  1371. }
  1372.  
  1373.  
  1374. PUBLIC void
  1375. glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
  1376.                 unsigned long mask )
  1377. {
  1378.    XMesaContext xm_src = src->xmesaContext;
  1379.    XMesaContext xm_dst = dst->xmesaContext;
  1380.    (void) dpy;
  1381.    if (MakeCurrent_PrevContext == src) {
  1382.       glFlush();
  1383.    }
  1384.    XMesaCopyContext(xm_src, xm_dst, mask);
  1385. }
  1386.  
  1387.  
  1388. PUBLIC Bool
  1389. glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
  1390. {
  1391.    int op, ev, err;
  1392.    /* Mesa's GLX isn't really an X extension but we try to act like one. */
  1393.    if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err))
  1394.       ev = err = 0;
  1395.    if (errorBase)
  1396.       *errorBase = err;
  1397.    if (eventBase)
  1398.       *eventBase = ev;
  1399.    return True; /* we're faking GLX so always return success */
  1400. }
  1401.  
  1402.  
  1403. PUBLIC void
  1404. glXDestroyContext( Display *dpy, GLXContext ctx )
  1405. {
  1406.    if (ctx) {
  1407.       GLXContext glxCtx = ctx;
  1408.       (void) dpy;
  1409.       MakeCurrent_PrevContext = 0;
  1410.       MakeCurrent_PrevDrawable = 0;
  1411.       MakeCurrent_PrevReadable = 0;
  1412.       MakeCurrent_PrevDrawBuffer = 0;
  1413.       MakeCurrent_PrevReadBuffer = 0;
  1414.       XMesaDestroyContext( glxCtx->xmesaContext );
  1415.       XMesaGarbageCollect();
  1416.       free(glxCtx);
  1417.    }
  1418. }
  1419.  
  1420.  
  1421. PUBLIC Bool
  1422. glXIsDirect( Display *dpy, GLXContext ctx )
  1423. {
  1424.    return ctx ? ctx->isDirect : False;
  1425. }
  1426.  
  1427.  
  1428.  
  1429. PUBLIC void
  1430. glXSwapBuffers( Display *dpy, GLXDrawable drawable )
  1431. {
  1432.    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
  1433.    static boolean firsttime = 1, no_rast = 0;
  1434.  
  1435.    if (firsttime) {
  1436.       no_rast = getenv("SP_NO_RAST") != NULL;
  1437.       firsttime = 0;
  1438.    }
  1439.  
  1440.    if (no_rast)
  1441.       return;
  1442.  
  1443.    if (buffer) {
  1444.       XMesaSwapBuffers(buffer);
  1445.    }
  1446.    else if (getenv("MESA_DEBUG")) {
  1447.       _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
  1448.                     (int) drawable);
  1449.    }
  1450. }
  1451.  
  1452.  
  1453.  
  1454. /*** GLX_MESA_copy_sub_buffer ***/
  1455.  
  1456. PUBLIC void
  1457. glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
  1458.                      int x, int y, int width, int height)
  1459. {
  1460.    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
  1461.    if (buffer) {
  1462.       XMesaCopySubBuffer(buffer, x, y, width, height);
  1463.    }
  1464.    else if (getenv("MESA_DEBUG")) {
  1465.       _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
  1466.    }
  1467. }
  1468.  
  1469.  
  1470. PUBLIC Bool
  1471. glXQueryVersion( Display *dpy, int *maj, int *min )
  1472. {
  1473.    (void) dpy;
  1474.    /* Return GLX version, not Mesa version */
  1475.    assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
  1476.    *maj = CLIENT_MAJOR_VERSION;
  1477.    *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
  1478.    return True;
  1479. }
  1480.  
  1481.  
  1482. /*
  1483.  * Query the GLX attributes of the given XVisualInfo.
  1484.  */
  1485. static int
  1486. get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
  1487. {
  1488.    assert(xmvis);
  1489.    switch(attrib) {
  1490.       case GLX_USE_GL:
  1491.          if (fbconfig)
  1492.             return GLX_BAD_ATTRIBUTE;
  1493.          *value = (int) True;
  1494.          return 0;
  1495.       case GLX_BUFFER_SIZE:
  1496.          *value = xmvis->visinfo->depth;
  1497.          return 0;
  1498.       case GLX_LEVEL:
  1499.          *value = xmvis->mesa_visual.level;
  1500.          return 0;
  1501.       case GLX_RGBA:
  1502.          if (fbconfig)
  1503.             return GLX_BAD_ATTRIBUTE;
  1504.          if (xmvis->mesa_visual.rgbMode) {
  1505.             *value = True;
  1506.          }
  1507.          else {
  1508.             *value = False;
  1509.          }
  1510.          return 0;
  1511.       case GLX_DOUBLEBUFFER:
  1512.          *value = (int) xmvis->mesa_visual.doubleBufferMode;
  1513.          return 0;
  1514.       case GLX_STEREO:
  1515.          *value = (int) xmvis->mesa_visual.stereoMode;
  1516.          return 0;
  1517.       case GLX_AUX_BUFFERS:
  1518.          *value = xmvis->mesa_visual.numAuxBuffers;
  1519.          return 0;
  1520.       case GLX_RED_SIZE:
  1521.          *value = xmvis->mesa_visual.redBits;
  1522.          return 0;
  1523.       case GLX_GREEN_SIZE:
  1524.          *value = xmvis->mesa_visual.greenBits;
  1525.          return 0;
  1526.       case GLX_BLUE_SIZE:
  1527.          *value = xmvis->mesa_visual.blueBits;
  1528.          return 0;
  1529.       case GLX_ALPHA_SIZE:
  1530.          *value = xmvis->mesa_visual.alphaBits;
  1531.          return 0;
  1532.       case GLX_DEPTH_SIZE:
  1533.          *value = xmvis->mesa_visual.depthBits;
  1534.          return 0;
  1535.       case GLX_STENCIL_SIZE:
  1536.          *value = xmvis->mesa_visual.stencilBits;
  1537.          return 0;
  1538.       case GLX_ACCUM_RED_SIZE:
  1539.          *value = xmvis->mesa_visual.accumRedBits;
  1540.          return 0;
  1541.       case GLX_ACCUM_GREEN_SIZE:
  1542.          *value = xmvis->mesa_visual.accumGreenBits;
  1543.          return 0;
  1544.       case GLX_ACCUM_BLUE_SIZE:
  1545.          *value = xmvis->mesa_visual.accumBlueBits;
  1546.          return 0;
  1547.       case GLX_ACCUM_ALPHA_SIZE:
  1548.          *value = xmvis->mesa_visual.accumAlphaBits;
  1549.          return 0;
  1550.  
  1551.       /*
  1552.        * GLX_EXT_visual_info extension
  1553.        */
  1554.       case GLX_X_VISUAL_TYPE_EXT:
  1555.          switch (xmvis->visinfo->CLASS) {
  1556.             case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
  1557.             case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
  1558.             case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
  1559.             case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
  1560.             case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
  1561.             case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
  1562.          }
  1563.          return 0;
  1564.       case GLX_TRANSPARENT_TYPE_EXT:
  1565.          /* normal planes */
  1566.          *value = GLX_NONE_EXT;
  1567.          return 0;
  1568.       case GLX_TRANSPARENT_INDEX_VALUE_EXT:
  1569.          /* undefined */
  1570.          return 0;
  1571.       case GLX_TRANSPARENT_RED_VALUE_EXT:
  1572.          /* undefined */
  1573.          return 0;
  1574.       case GLX_TRANSPARENT_GREEN_VALUE_EXT:
  1575.          /* undefined */
  1576.          return 0;
  1577.       case GLX_TRANSPARENT_BLUE_VALUE_EXT:
  1578.          /* undefined */
  1579.          return 0;
  1580.       case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
  1581.          /* undefined */
  1582.          return 0;
  1583.  
  1584.       /*
  1585.        * GLX_EXT_visual_info extension
  1586.        */
  1587.       case GLX_VISUAL_CAVEAT_EXT:
  1588.          /* test for zero, just in case */
  1589.          if (xmvis->mesa_visual.visualRating > 0)
  1590.             *value = xmvis->mesa_visual.visualRating;
  1591.          else
  1592.             *value = GLX_NONE_EXT;
  1593.          return 0;
  1594.  
  1595.       /*
  1596.        * GLX_ARB_multisample
  1597.        */
  1598.       case GLX_SAMPLE_BUFFERS_ARB:
  1599.          *value = 0;
  1600.          return 0;
  1601.       case GLX_SAMPLES_ARB:
  1602.          *value = 0;
  1603.          return 0;
  1604.  
  1605.       /*
  1606.        * For FBConfigs:
  1607.        */
  1608.       case GLX_SCREEN_EXT:
  1609.          if (!fbconfig)
  1610.             return GLX_BAD_ATTRIBUTE;
  1611.          *value = xmvis->visinfo->screen;
  1612.          break;
  1613.       case GLX_DRAWABLE_TYPE: /*SGIX too */
  1614.          if (!fbconfig)
  1615.             return GLX_BAD_ATTRIBUTE;
  1616.          *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
  1617.          break;
  1618.       case GLX_RENDER_TYPE_SGIX:
  1619.          if (!fbconfig)
  1620.             return GLX_BAD_ATTRIBUTE;
  1621.          if (xmvis->mesa_visual.rgbMode)
  1622.             *value = GLX_RGBA_BIT;
  1623.          else
  1624.             *value = GLX_COLOR_INDEX_BIT;
  1625.          break;
  1626.       case GLX_X_RENDERABLE_SGIX:
  1627.          if (!fbconfig)
  1628.             return GLX_BAD_ATTRIBUTE;
  1629.          *value = True; /* XXX really? */
  1630.          break;
  1631.       case GLX_FBCONFIG_ID_SGIX:
  1632.          if (!fbconfig)
  1633.             return GLX_BAD_ATTRIBUTE;
  1634.          *value = xmvis->visinfo->visualid;
  1635.          break;
  1636.       case GLX_MAX_PBUFFER_WIDTH:
  1637.          if (!fbconfig)
  1638.             return GLX_BAD_ATTRIBUTE;
  1639.          /* XXX should be same as ctx->Const.MaxRenderbufferSize */
  1640.          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
  1641.          break;
  1642.       case GLX_MAX_PBUFFER_HEIGHT:
  1643.          if (!fbconfig)
  1644.             return GLX_BAD_ATTRIBUTE;
  1645.          *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
  1646.          break;
  1647.       case GLX_MAX_PBUFFER_PIXELS:
  1648.          if (!fbconfig)
  1649.             return GLX_BAD_ATTRIBUTE;
  1650.          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
  1651.                   DisplayHeight(xmvis->display, xmvis->visinfo->screen);
  1652.          break;
  1653.       case GLX_VISUAL_ID:
  1654.          if (!fbconfig)
  1655.             return GLX_BAD_ATTRIBUTE;
  1656.          *value = xmvis->visinfo->visualid;
  1657.          break;
  1658.  
  1659. #ifdef GLX_EXT_texture_from_pixmap
  1660.       case GLX_BIND_TO_TEXTURE_RGB_EXT:
  1661.          *value = True; /*XXX*/
  1662.          break;
  1663.       case GLX_BIND_TO_TEXTURE_RGBA_EXT:
  1664.          /* XXX review */
  1665.          *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
  1666.          break;
  1667.       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
  1668.          *value = True; /*XXX*/
  1669.          break;
  1670.       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
  1671.          *value = (GLX_TEXTURE_1D_BIT_EXT |
  1672.                    GLX_TEXTURE_2D_BIT_EXT |
  1673.                    GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
  1674.          break;
  1675.       case GLX_Y_INVERTED_EXT:
  1676.          *value = True; /*XXX*/
  1677.          break;
  1678. #endif
  1679.  
  1680.       default:
  1681.          return GLX_BAD_ATTRIBUTE;
  1682.    }
  1683.    return Success;
  1684. }
  1685.  
  1686.  
  1687. PUBLIC int
  1688. glXGetConfig( Display *dpy, XVisualInfo *visinfo,
  1689.                    int attrib, int *value )
  1690. {
  1691.    XMesaVisual xmvis;
  1692.    int k;
  1693.    if (!dpy || !visinfo)
  1694.       return GLX_BAD_ATTRIBUTE;
  1695.  
  1696.    xmvis = find_glx_visual( dpy, visinfo );
  1697.    if (!xmvis) {
  1698.       /* this visual wasn't obtained with glXChooseVisual */
  1699.       xmvis = create_glx_visual( dpy, visinfo );
  1700.       if (!xmvis) {
  1701.          /* this visual can't be used for GL rendering */
  1702.          if (attrib==GLX_USE_GL) {
  1703.             *value = (int) False;
  1704.             return 0;
  1705.          }
  1706.          else {
  1707.             return GLX_BAD_VISUAL;
  1708.          }
  1709.       }
  1710.    }
  1711.  
  1712.    k = get_config(xmvis, attrib, value, GL_FALSE);
  1713.    return k;
  1714. }
  1715.  
  1716.  
  1717. PUBLIC void
  1718. glXWaitGL( void )
  1719. {
  1720.    XMesaContext xmesa = XMesaGetCurrentContext();
  1721.    XMesaFlush( xmesa );
  1722. }
  1723.  
  1724.  
  1725.  
  1726. PUBLIC void
  1727. glXWaitX( void )
  1728. {
  1729.    XMesaContext xmesa = XMesaGetCurrentContext();
  1730.    XMesaFlush( xmesa );
  1731. }
  1732.  
  1733.  
  1734. static const char *
  1735. get_extensions( void )
  1736. {
  1737.    return EXTENSIONS;
  1738. }
  1739.  
  1740.  
  1741.  
  1742. /* GLX 1.1 and later */
  1743. PUBLIC const char *
  1744. glXQueryExtensionsString( Display *dpy, int screen )
  1745. {
  1746.    (void) dpy;
  1747.    (void) screen;
  1748.    return get_extensions();
  1749. }
  1750.  
  1751.  
  1752.  
  1753. /* GLX 1.1 and later */
  1754. PUBLIC const char *
  1755. glXQueryServerString( Display *dpy, int screen, int name )
  1756. {
  1757.    static char version[1000];
  1758.    sprintf(version, "%d.%d %s",
  1759.            SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, xmesa_get_name());
  1760.  
  1761.    (void) dpy;
  1762.    (void) screen;
  1763.  
  1764.    switch (name) {
  1765.       case GLX_EXTENSIONS:
  1766.          return get_extensions();
  1767.       case GLX_VENDOR:
  1768.          return VENDOR;
  1769.       case GLX_VERSION:
  1770.          return version;
  1771.       default:
  1772.          return NULL;
  1773.    }
  1774. }
  1775.  
  1776.  
  1777.  
  1778. /* GLX 1.1 and later */
  1779. PUBLIC const char *
  1780. glXGetClientString( Display *dpy, int name )
  1781. {
  1782.    static char version[1000];
  1783.    sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
  1784.            CLIENT_MINOR_VERSION, xmesa_get_name());
  1785.  
  1786.    (void) dpy;
  1787.  
  1788.    switch (name) {
  1789.       case GLX_EXTENSIONS:
  1790.          return get_extensions();
  1791.       case GLX_VENDOR:
  1792.          return VENDOR;
  1793.       case GLX_VERSION:
  1794.          return version;
  1795.       default:
  1796.          return NULL;
  1797.    }
  1798. }
  1799.  
  1800.  
  1801.  
  1802. /*
  1803.  * GLX 1.3 and later
  1804.  */
  1805.  
  1806.  
  1807. PUBLIC int
  1808. glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
  1809.                      int attribute, int *value)
  1810. {
  1811.    XMesaVisual v = (XMesaVisual) config;
  1812.    (void) dpy;
  1813.    (void) config;
  1814.  
  1815.    if (!dpy || !config || !value)
  1816.       return -1;
  1817.  
  1818.    return get_config(v, attribute, value, GL_TRUE);
  1819. }
  1820.  
  1821.  
  1822. PUBLIC GLXFBConfig *
  1823. glXGetFBConfigs( Display *dpy, int screen, int *nelements )
  1824. {
  1825.    XVisualInfo *visuals, visTemplate;
  1826.    const long visMask = VisualScreenMask;
  1827.    int i;
  1828.  
  1829.    /* Get list of all X visuals */
  1830.    visTemplate.screen = screen;
  1831.    visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
  1832.    if (*nelements > 0) {
  1833.       XMesaVisual *results = malloc(*nelements * sizeof(XMesaVisual));
  1834.       if (!results) {
  1835.          *nelements = 0;
  1836.          return NULL;
  1837.       }
  1838.       for (i = 0; i < *nelements; i++) {
  1839.          results[i] = create_glx_visual(dpy, visuals + i);
  1840.          if (!results[i]) {
  1841.             *nelements = i;
  1842.             break;
  1843.          }
  1844.       }
  1845.       return (GLXFBConfig *) results;
  1846.    }
  1847.    return NULL;
  1848. }
  1849.  
  1850.  
  1851. PUBLIC GLXFBConfig *
  1852. glXChooseFBConfig(Display *dpy, int screen,
  1853.                   const int *attribList, int *nitems)
  1854. {
  1855.    XMesaVisual xmvis;
  1856.  
  1857.    /* register ourselves as an extension on this display */
  1858.    register_with_display(dpy);
  1859.  
  1860.    if (!attribList || !attribList[0]) {
  1861.       /* return list of all configs (per GLX_SGIX_fbconfig spec) */
  1862.       return glXGetFBConfigs(dpy, screen, nitems);
  1863.    }
  1864.  
  1865.    xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
  1866.    if (xmvis) {
  1867.       GLXFBConfig *config = malloc(sizeof(XMesaVisual));
  1868.       if (!config) {
  1869.          *nitems = 0;
  1870.          return NULL;
  1871.       }
  1872.       *nitems = 1;
  1873.       config[0] = (GLXFBConfig) xmvis;
  1874.       return (GLXFBConfig *) config;
  1875.    }
  1876.    else {
  1877.       *nitems = 0;
  1878.       return NULL;
  1879.    }
  1880. }
  1881.  
  1882.  
  1883. PUBLIC XVisualInfo *
  1884. glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
  1885. {
  1886.    if (dpy && config) {
  1887.       XMesaVisual xmvis = (XMesaVisual) config;
  1888. #if 0      
  1889.       return xmvis->vishandle;
  1890. #else
  1891.       /* create a new vishandle - the cached one may be stale */
  1892.       xmvis->vishandle = malloc(sizeof(XVisualInfo));
  1893.       if (xmvis->vishandle) {
  1894.          memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
  1895.       }
  1896.       return xmvis->vishandle;
  1897. #endif
  1898.    }
  1899.    else {
  1900.       return NULL;
  1901.    }
  1902. }
  1903.  
  1904.  
  1905. PUBLIC GLXWindow
  1906. glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
  1907.                 const int *attribList)
  1908. {
  1909.    XMesaVisual xmvis = (XMesaVisual) config;
  1910.    XMesaBuffer xmbuf;
  1911.    if (!xmvis)
  1912.       return 0;
  1913.  
  1914.    xmbuf = XMesaCreateWindowBuffer(xmvis, win);
  1915.    if (!xmbuf)
  1916.       return 0;
  1917.  
  1918.    (void) dpy;
  1919.    (void) attribList;  /* Ignored in GLX 1.3 */
  1920.  
  1921.    return win;  /* A hack for now */
  1922. }
  1923.  
  1924.  
  1925. PUBLIC void
  1926. glXDestroyWindow( Display *dpy, GLXWindow window )
  1927. {
  1928.    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
  1929.    if (b)
  1930.       XMesaDestroyBuffer(b);
  1931.    /* don't destroy X window */
  1932. }
  1933.  
  1934.  
  1935. /* XXX untested */
  1936. PUBLIC GLXPixmap
  1937. glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
  1938.                 const int *attribList)
  1939. {
  1940.    XMesaVisual v = (XMesaVisual) config;
  1941.    XMesaBuffer b;
  1942.    const int *attr;
  1943.    int target = 0, format = 0, mipmap = 0;
  1944.    int value;
  1945.  
  1946.    if (!dpy || !config || !pixmap)
  1947.       return 0;
  1948.  
  1949.    for (attr = attribList; attr && *attr; attr++) {
  1950.       switch (*attr) {
  1951.       case GLX_TEXTURE_FORMAT_EXT:
  1952.          attr++;
  1953.          switch (*attr) {
  1954.          case GLX_TEXTURE_FORMAT_NONE_EXT:
  1955.          case GLX_TEXTURE_FORMAT_RGB_EXT:
  1956.          case GLX_TEXTURE_FORMAT_RGBA_EXT:
  1957.             format = *attr;
  1958.             break;
  1959.          default:
  1960.             /* error */
  1961.             return 0;
  1962.          }
  1963.          break;
  1964.       case GLX_TEXTURE_TARGET_EXT:
  1965.          attr++;
  1966.          switch (*attr) {
  1967.          case GLX_TEXTURE_1D_EXT:
  1968.          case GLX_TEXTURE_2D_EXT:
  1969.          case GLX_TEXTURE_RECTANGLE_EXT:
  1970.             target = *attr;
  1971.             break;
  1972.          default:
  1973.             /* error */
  1974.             return 0;
  1975.          }
  1976.          break;
  1977.       case GLX_MIPMAP_TEXTURE_EXT:
  1978.          attr++;
  1979.          if (*attr)
  1980.             mipmap = 1;
  1981.          break;
  1982.       default:
  1983.          /* error */
  1984.          return 0;
  1985.       }
  1986.    }
  1987.  
  1988.    if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
  1989.       if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
  1990.                      &value, GL_TRUE) != Success
  1991.           || !value) {
  1992.          return 0; /* error! */
  1993.       }
  1994.    }
  1995.    else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
  1996.       if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
  1997.                      &value, GL_TRUE) != Success
  1998.           || !value) {
  1999.          return 0; /* error! */
  2000.       }
  2001.    }
  2002.    if (mipmap) {
  2003.       if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
  2004.                      &value, GL_TRUE) != Success
  2005.           || !value) {
  2006.          return 0; /* error! */
  2007.       }
  2008.    }
  2009.    if (target == GLX_TEXTURE_1D_EXT) {
  2010.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  2011.                      &value, GL_TRUE) != Success
  2012.           || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
  2013.          return 0; /* error! */
  2014.       }
  2015.    }
  2016.    else if (target == GLX_TEXTURE_2D_EXT) {
  2017.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  2018.                      &value, GL_TRUE) != Success
  2019.           || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
  2020.          return 0; /* error! */
  2021.       }
  2022.    }
  2023.    if (target == GLX_TEXTURE_RECTANGLE_EXT) {
  2024.       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
  2025.                      &value, GL_TRUE) != Success
  2026.           || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
  2027.          return 0; /* error! */
  2028.       }
  2029.    }
  2030.  
  2031.    if (format || target || mipmap) {
  2032.       /* texture from pixmap */
  2033.       b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
  2034.    }
  2035.    else {
  2036.       b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
  2037.    }
  2038.    if (!b) {
  2039.       return 0;
  2040.    }
  2041.  
  2042.    return pixmap;
  2043. }
  2044.  
  2045.  
  2046. PUBLIC void
  2047. glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
  2048. {
  2049.    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
  2050.    if (b)
  2051.       XMesaDestroyBuffer(b);
  2052.    /* don't destroy X pixmap */
  2053. }
  2054.  
  2055.  
  2056. PUBLIC GLXPbuffer
  2057. glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
  2058. {
  2059.    XMesaVisual xmvis = (XMesaVisual) config;
  2060.    XMesaBuffer xmbuf;
  2061.    const int *attrib;
  2062.    int width = 0, height = 0;
  2063.    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
  2064.  
  2065.    (void) dpy;
  2066.  
  2067.    for (attrib = attribList; *attrib; attrib++) {
  2068.       switch (*attrib) {
  2069.          case GLX_PBUFFER_WIDTH:
  2070.             attrib++;
  2071.             width = *attrib;
  2072.             break;
  2073.          case GLX_PBUFFER_HEIGHT:
  2074.             attrib++;
  2075.             height = *attrib;
  2076.             break;
  2077.          case GLX_PRESERVED_CONTENTS:
  2078.             attrib++;
  2079.             preserveContents = *attrib;
  2080.             break;
  2081.          case GLX_LARGEST_PBUFFER:
  2082.             attrib++;
  2083.             useLargest = *attrib;
  2084.             break;
  2085.          default:
  2086.             return 0;
  2087.       }
  2088.    }
  2089.  
  2090.    if (width == 0 || height == 0)
  2091.       return 0;
  2092.  
  2093.    if (width > PBUFFER_MAX_SIZE || height > PBUFFER_MAX_SIZE) {
  2094.       /* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
  2095.        * allocate the largest possible buffer.
  2096.        */
  2097.       if (useLargest) {
  2098.          width = PBUFFER_MAX_SIZE;
  2099.          height = PBUFFER_MAX_SIZE;
  2100.       }
  2101.    }
  2102.  
  2103.    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
  2104.    /* A GLXPbuffer handle must be an X Drawable because that's what
  2105.     * glXMakeCurrent takes.
  2106.     */
  2107.    if (xmbuf) {
  2108.       xmbuf->largestPbuffer = useLargest;
  2109.       xmbuf->preservedContents = preserveContents;
  2110.       return (GLXPbuffer) xmbuf->ws.drawable;
  2111.    }
  2112.    else {
  2113.       return 0;
  2114.    }
  2115. }
  2116.  
  2117.  
  2118. PUBLIC void
  2119. glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
  2120. {
  2121.    XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
  2122.    if (b) {
  2123.       XMesaDestroyBuffer(b);
  2124.    }
  2125. }
  2126.  
  2127.  
  2128. PUBLIC void
  2129. glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
  2130.                  unsigned int *value)
  2131. {
  2132.    GLuint width, height;
  2133.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
  2134.    if (!xmbuf) {
  2135.       generate_error(dpy, GLXBadDrawable, draw, X_GLXGetDrawableAttributes, False);
  2136.       return;
  2137.    }
  2138.  
  2139.    /* make sure buffer's dimensions are up to date */
  2140.    xmesa_get_window_size(dpy, xmbuf, &width, &height);
  2141.  
  2142.    switch (attribute) {
  2143.       case GLX_WIDTH:
  2144.          *value = width;
  2145.          break;
  2146.       case GLX_HEIGHT:
  2147.          *value = height;
  2148.          break;
  2149.       case GLX_PRESERVED_CONTENTS:
  2150.          *value = xmbuf->preservedContents;
  2151.          break;
  2152.       case GLX_LARGEST_PBUFFER:
  2153.          *value = xmbuf->largestPbuffer;
  2154.          break;
  2155.       case GLX_FBCONFIG_ID:
  2156.          *value = xmbuf->xm_visual->visinfo->visualid;
  2157.          return;
  2158. #ifdef GLX_EXT_texture_from_pixmap
  2159.       case GLX_TEXTURE_FORMAT_EXT:
  2160.          *value = xmbuf->TextureFormat;
  2161.          break;
  2162.       case GLX_TEXTURE_TARGET_EXT:
  2163.          *value = xmbuf->TextureTarget;
  2164.          break;
  2165.       case GLX_MIPMAP_TEXTURE_EXT:
  2166.          *value = xmbuf->TextureMipmap;
  2167.          break;
  2168. #endif
  2169.  
  2170.       default:
  2171.          generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, true);
  2172.          return;
  2173.    }
  2174. }
  2175.  
  2176.  
  2177. PUBLIC GLXContext
  2178. glXCreateNewContext( Display *dpy, GLXFBConfig config,
  2179.                      int renderType, GLXContext shareCtx, Bool direct )
  2180. {
  2181.    XMesaVisual xmvis = (XMesaVisual) config;
  2182.  
  2183.    if (!dpy || !config ||
  2184.        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
  2185.       return 0;
  2186.  
  2187.    return create_context(dpy, xmvis,
  2188.                          shareCtx ? shareCtx->xmesaContext : NULL,
  2189.                          direct,
  2190.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  2191. }
  2192.  
  2193.  
  2194. PUBLIC int
  2195. glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
  2196. {
  2197.    GLXContext glxCtx = ctx;
  2198.    XMesaContext xmctx = glxCtx->xmesaContext;
  2199.  
  2200.    (void) dpy;
  2201.    (void) ctx;
  2202.  
  2203.    switch (attribute) {
  2204.    case GLX_FBCONFIG_ID:
  2205.       *value = xmctx->xm_visual->visinfo->visualid;
  2206.       break;
  2207.    case GLX_RENDER_TYPE:
  2208.       if (xmctx->xm_visual->mesa_visual.rgbMode)
  2209.          *value = GLX_RGBA_TYPE;
  2210.       else
  2211.          *value = GLX_COLOR_INDEX_TYPE;
  2212.       break;
  2213.    case GLX_SCREEN:
  2214.       *value = 0;
  2215.       return Success;
  2216.    default:
  2217.       return GLX_BAD_ATTRIBUTE;
  2218.    }
  2219.    return 0;
  2220. }
  2221.  
  2222.  
  2223. PUBLIC void
  2224. glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
  2225. {
  2226.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2227.    if (xmbuf)
  2228.       xmbuf->selectedEvents = mask;
  2229. }
  2230.  
  2231.  
  2232. PUBLIC void
  2233. glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
  2234. {
  2235.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2236.    if (xmbuf)
  2237.       *mask = xmbuf->selectedEvents;
  2238.    else
  2239.       *mask = 0;
  2240. }
  2241.  
  2242.  
  2243.  
  2244. /*** GLX_SGI_swap_control ***/
  2245.  
  2246. PUBLIC int
  2247. glXSwapIntervalSGI(int interval)
  2248. {
  2249.    (void) interval;
  2250.    return 0;
  2251. }
  2252.  
  2253.  
  2254.  
  2255. /*** GLX_SGI_video_sync ***/
  2256.  
  2257. static unsigned int FrameCounter = 0;
  2258.  
  2259. PUBLIC int
  2260. glXGetVideoSyncSGI(unsigned int *count)
  2261. {
  2262.    /* this is a bogus implementation */
  2263.    *count = FrameCounter++;
  2264.    return 0;
  2265. }
  2266.  
  2267. PUBLIC int
  2268. glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
  2269. {
  2270.    if (divisor <= 0 || remainder < 0)
  2271.       return GLX_BAD_VALUE;
  2272.    /* this is a bogus implementation */
  2273.    FrameCounter++;
  2274.    while (FrameCounter % divisor != remainder)
  2275.       FrameCounter++;
  2276.    *count = FrameCounter;
  2277.    return 0;
  2278. }
  2279.  
  2280.  
  2281.  
  2282. /*** GLX_SGI_make_current_read ***/
  2283.  
  2284. PUBLIC Bool
  2285. glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
  2286.                       GLXContext ctx)
  2287. {
  2288.    return glXMakeContextCurrent( dpy, draw, read, ctx );
  2289. }
  2290.  
  2291. /* not used
  2292. static GLXDrawable
  2293. glXGetCurrentReadDrawableSGI(void)
  2294. {
  2295.    return 0;
  2296. }
  2297. */
  2298.  
  2299.  
  2300. /*** GLX_SGIX_video_source ***/
  2301. #if defined(_VL_H)
  2302.  
  2303. PUBLIC GLXVideoSourceSGIX
  2304. glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
  2305.                             VLPath path, int nodeClass, VLNode drainNode)
  2306. {
  2307.    (void) dpy;
  2308.    (void) screen;
  2309.    (void) server;
  2310.    (void) path;
  2311.    (void) nodeClass;
  2312.    (void) drainNode;
  2313.    return 0;
  2314. }
  2315.  
  2316. PUBLIC void
  2317. glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
  2318. {
  2319.    (void) dpy;
  2320.    (void) src;
  2321. }
  2322.  
  2323. #endif
  2324.  
  2325.  
  2326. /*** GLX_EXT_import_context ***/
  2327.  
  2328. PUBLIC void
  2329. glXFreeContextEXT(Display *dpy, GLXContext context)
  2330. {
  2331.    (void) dpy;
  2332.    (void) context;
  2333. }
  2334.  
  2335. PUBLIC GLXContextID
  2336. glXGetContextIDEXT(const GLXContext context)
  2337. {
  2338.    (void) context;
  2339.    return 0;
  2340. }
  2341.  
  2342. PUBLIC GLXContext
  2343. glXImportContextEXT(Display *dpy, GLXContextID contextID)
  2344. {
  2345.    (void) dpy;
  2346.    (void) contextID;
  2347.    return 0;
  2348. }
  2349.  
  2350. PUBLIC int
  2351. glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
  2352.                        int *value)
  2353. {
  2354.    (void) dpy;
  2355.    (void) context;
  2356.    (void) attribute;
  2357.    (void) value;
  2358.    return 0;
  2359. }
  2360.  
  2361.  
  2362.  
  2363. /*** GLX_SGIX_fbconfig ***/
  2364.  
  2365. PUBLIC int
  2366. glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
  2367.                          int attribute, int *value)
  2368. {
  2369.    return glXGetFBConfigAttrib(dpy, config, attribute, value);
  2370. }
  2371.  
  2372. PUBLIC GLXFBConfigSGIX *
  2373. glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
  2374.                       int *nelements)
  2375. {
  2376.    return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
  2377.                                             attrib_list, nelements);
  2378. }
  2379.  
  2380.  
  2381. PUBLIC GLXPixmap
  2382. glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
  2383.                                  Pixmap pixmap)
  2384. {
  2385.    XMesaVisual xmvis = (XMesaVisual) config;
  2386.    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
  2387.    return xmbuf->ws.drawable; /* need to return an X ID */
  2388. }
  2389.  
  2390.  
  2391. PUBLIC GLXContext
  2392. glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
  2393.                                int renderType, GLXContext shareCtx,
  2394.                                Bool direct)
  2395. {
  2396.    XMesaVisual xmvis = (XMesaVisual) config;
  2397.  
  2398.    if (!dpy || !config ||
  2399.        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
  2400.       return 0;
  2401.  
  2402.    return create_context(dpy, xmvis,
  2403.                          shareCtx ? shareCtx->xmesaContext : NULL,
  2404.                          direct,
  2405.                          1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
  2406. }
  2407.  
  2408.  
  2409. PUBLIC XVisualInfo *
  2410. glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
  2411. {
  2412.    return glXGetVisualFromFBConfig(dpy, config);
  2413. }
  2414.  
  2415.  
  2416. PUBLIC GLXFBConfigSGIX
  2417. glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
  2418. {
  2419.    XMesaVisual xmvis = find_glx_visual(dpy, vis);
  2420.    if (!xmvis) {
  2421.       /* This visual wasn't found with glXChooseVisual() */
  2422.       xmvis = create_glx_visual(dpy, vis);
  2423.    }
  2424.  
  2425.    return (GLXFBConfigSGIX) xmvis;
  2426. }
  2427.  
  2428.  
  2429.  
  2430. /*** GLX_SGIX_pbuffer ***/
  2431.  
  2432. PUBLIC GLXPbufferSGIX
  2433. glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
  2434.                         unsigned int width, unsigned int height,
  2435.                         int *attribList)
  2436. {
  2437.    XMesaVisual xmvis = (XMesaVisual) config;
  2438.    XMesaBuffer xmbuf;
  2439.    const int *attrib;
  2440.    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
  2441.  
  2442.    (void) dpy;
  2443.  
  2444.    for (attrib = attribList; attrib && *attrib; attrib++) {
  2445.       switch (*attrib) {
  2446.          case GLX_PRESERVED_CONTENTS_SGIX:
  2447.             attrib++;
  2448.             preserveContents = *attrib; /* ignored */
  2449.             break;
  2450.          case GLX_LARGEST_PBUFFER_SGIX:
  2451.             attrib++;
  2452.             useLargest = *attrib; /* ignored */
  2453.             break;
  2454.          default:
  2455.             return 0;
  2456.       }
  2457.    }
  2458.  
  2459.    /* not used at this time */
  2460.    (void) useLargest;
  2461.    (void) preserveContents;
  2462.  
  2463.    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
  2464.    /* A GLXPbuffer handle must be an X Drawable because that's what
  2465.     * glXMakeCurrent takes.
  2466.     */
  2467.    return (GLXPbuffer) xmbuf->ws.drawable;
  2468. }
  2469.  
  2470.  
  2471. PUBLIC void
  2472. glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
  2473. {
  2474.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
  2475.    if (xmbuf) {
  2476.       XMesaDestroyBuffer(xmbuf);
  2477.    }
  2478. }
  2479.  
  2480.  
  2481. PUBLIC int
  2482. glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
  2483.                        unsigned int *value)
  2484. {
  2485.    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
  2486.  
  2487.    if (!xmbuf) {
  2488.       /* Generate GLXBadPbufferSGIX for bad pbuffer */
  2489.       return 0;
  2490.    }
  2491.  
  2492.    switch (attribute) {
  2493.       case GLX_PRESERVED_CONTENTS_SGIX:
  2494.          *value = True;
  2495.          break;
  2496.       case GLX_LARGEST_PBUFFER_SGIX:
  2497.          *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf);
  2498.          break;
  2499.       case GLX_WIDTH_SGIX:
  2500.          *value = xmesa_buffer_width(xmbuf);
  2501.          break;
  2502.       case GLX_HEIGHT_SGIX:
  2503.          *value = xmesa_buffer_height(xmbuf);
  2504.          break;
  2505.       case GLX_EVENT_MASK_SGIX:
  2506.          *value = 0;  /* XXX might be wrong */
  2507.          break;
  2508.       default:
  2509.          *value = 0;
  2510.    }
  2511.    return 0;
  2512. }
  2513.  
  2514.  
  2515. PUBLIC void
  2516. glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
  2517. {
  2518.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2519.    if (xmbuf) {
  2520.       /* Note: we'll never generate clobber events */
  2521.       xmbuf->selectedEvents = mask;
  2522.    }
  2523. }
  2524.  
  2525.  
  2526. PUBLIC void
  2527. glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
  2528.                         unsigned long *mask)
  2529. {
  2530.    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
  2531.    if (xmbuf) {
  2532.       *mask = xmbuf->selectedEvents;
  2533.    }
  2534.    else {
  2535.       *mask = 0;
  2536.    }
  2537. }
  2538.  
  2539.  
  2540.  
  2541. /*** GLX_SGI_cushion ***/
  2542.  
  2543. PUBLIC void
  2544. glXCushionSGI(Display *dpy, Window win, float cushion)
  2545. {
  2546.    (void) dpy;
  2547.    (void) win;
  2548.    (void) cushion;
  2549. }
  2550.  
  2551.  
  2552.  
  2553. /*** GLX_SGIX_video_resize ***/
  2554.  
  2555. PUBLIC int
  2556. glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
  2557.                            Window window)
  2558. {
  2559.    (void) dpy;
  2560.    (void) screen;
  2561.    (void) channel;
  2562.    (void) window;
  2563.    return 0;
  2564. }
  2565.  
  2566. PUBLIC int
  2567. glXChannelRectSGIX(Display *dpy, int screen, int channel,
  2568.                    int x, int y, int w, int h)
  2569. {
  2570.    (void) dpy;
  2571.    (void) screen;
  2572.    (void) channel;
  2573.    (void) x;
  2574.    (void) y;
  2575.    (void) w;
  2576.    (void) h;
  2577.    return 0;
  2578. }
  2579.  
  2580. PUBLIC int
  2581. glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
  2582.                         int *x, int *y, int *w, int *h)
  2583. {
  2584.    (void) dpy;
  2585.    (void) screen;
  2586.    (void) channel;
  2587.    (void) x;
  2588.    (void) y;
  2589.    (void) w;
  2590.    (void) h;
  2591.    return 0;
  2592. }
  2593.  
  2594. PUBLIC int
  2595. glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
  2596.                           int *dx, int *dy, int *dw, int *dh)
  2597. {
  2598.    (void) dpy;
  2599.    (void) screen;
  2600.    (void) channel;
  2601.    (void) dx;
  2602.    (void) dy;
  2603.    (void) dw;
  2604.    (void) dh;
  2605.    return 0;
  2606. }
  2607.  
  2608. PUBLIC int
  2609. glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
  2610. {
  2611.    (void) dpy;
  2612.    (void) screen;
  2613.    (void) channel;
  2614.    (void) synctype;
  2615.    return 0;
  2616. }
  2617.  
  2618.  
  2619.  
  2620. /*** GLX_SGIX_dmbuffer **/
  2621.  
  2622. #if defined(_DM_BUFFER_H_)
  2623. PUBLIC Bool
  2624. glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
  2625.                           DMparams *params, DMbuffer dmbuffer)
  2626. {
  2627.    (void) dpy;
  2628.    (void) pbuffer;
  2629.    (void) params;
  2630.    (void) dmbuffer;
  2631.    return False;
  2632. }
  2633. #endif
  2634.  
  2635.  
  2636. /*** GLX_SGIX_swap_group ***/
  2637.  
  2638. PUBLIC void
  2639. glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
  2640. {
  2641.    (void) dpy;
  2642.    (void) drawable;
  2643.    (void) member;
  2644. }
  2645.  
  2646.  
  2647.  
  2648. /*** GLX_SGIX_swap_barrier ***/
  2649.  
  2650. PUBLIC void
  2651. glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
  2652. {
  2653.    (void) dpy;
  2654.    (void) drawable;
  2655.    (void) barrier;
  2656. }
  2657.  
  2658. PUBLIC Bool
  2659. glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
  2660. {
  2661.    (void) dpy;
  2662.    (void) screen;
  2663.    (void) max;
  2664.    return False;
  2665. }
  2666.  
  2667.  
  2668.  
  2669. /*** GLX_SUN_get_transparent_index ***/
  2670.  
  2671. PUBLIC Status
  2672. glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
  2673.                           long *pTransparent)
  2674. {
  2675.    (void) dpy;
  2676.    (void) overlay;
  2677.    (void) underlay;
  2678.    (void) pTransparent;
  2679.    return 0;
  2680. }
  2681.  
  2682.  
  2683.  
  2684. /*** GLX_MESA_release_buffers ***/
  2685.  
  2686. /*
  2687.  * Release the depth, stencil, accum buffers attached to a GLXDrawable
  2688.  * (a window or pixmap) prior to destroying the GLXDrawable.
  2689.  */
  2690. PUBLIC Bool
  2691. glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
  2692. {
  2693.    XMesaBuffer b = XMesaFindBuffer(dpy, d);
  2694.    if (b) {
  2695.       XMesaDestroyBuffer(b);
  2696.       return True;
  2697.    }
  2698.    return False;
  2699. }
  2700.  
  2701. /*** GLX_EXT_texture_from_pixmap ***/
  2702.  
  2703. PUBLIC void
  2704. glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
  2705.                         const int *attrib_list)
  2706. {
  2707.    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
  2708.    if (b)
  2709.       XMesaBindTexImage(dpy, b, buffer, attrib_list);
  2710. }
  2711.  
  2712. PUBLIC void
  2713. glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
  2714. {
  2715.    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
  2716.    if (b)
  2717.       XMesaReleaseTexImage(dpy, b, buffer);
  2718. }
  2719.  
  2720.  
  2721.  
  2722. /*** GLX_ARB_create_context ***/
  2723.  
  2724.  
  2725. GLXContext
  2726. glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
  2727.                            GLXContext shareCtx, Bool direct,
  2728.                            const int *attrib_list)
  2729. {
  2730.    XMesaVisual xmvis = (XMesaVisual) config;
  2731.    int majorVersion = 1, minorVersion = 0;
  2732.    int contextFlags = 0x0;
  2733.    int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
  2734.    int renderType = GLX_RGBA_TYPE;
  2735.    unsigned i;
  2736.    Bool done = False;
  2737.    const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
  2738.                                 GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
  2739.    GLXContext ctx;
  2740.  
  2741.    /* parse attrib_list */
  2742.    for (i = 0; !done && attrib_list && attrib_list[i]; i++) {
  2743.       switch (attrib_list[i]) {
  2744.       case GLX_CONTEXT_MAJOR_VERSION_ARB:
  2745.          majorVersion = attrib_list[++i];
  2746.          break;
  2747.       case GLX_CONTEXT_MINOR_VERSION_ARB:
  2748.          minorVersion = attrib_list[++i];
  2749.          break;
  2750.       case GLX_CONTEXT_FLAGS_ARB:
  2751.          contextFlags = attrib_list[++i];
  2752.          break;
  2753.       case GLX_CONTEXT_PROFILE_MASK_ARB:
  2754.          profileMask = attrib_list[++i];
  2755.          break;
  2756.       case GLX_RENDER_TYPE:
  2757.          renderType = attrib_list[++i];
  2758.          break;
  2759.       case 0:
  2760.          /* end of list */
  2761.          done = True;
  2762.          break;
  2763.       default:
  2764.          /* bad attribute */
  2765.          generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
  2766.          return NULL;
  2767.       }
  2768.    }
  2769.  
  2770.    /* check contextFlags */
  2771.    if (contextFlags & ~contextFlagsAll) {
  2772.       generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
  2773.       return NULL;
  2774.    }
  2775.  
  2776.    /* check profileMask */
  2777.    if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
  2778.        profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
  2779.        profileMask != GLX_CONTEXT_ES_PROFILE_BIT_EXT) {
  2780.       generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAtrribsARB, False);
  2781.       return NULL;
  2782.    }
  2783.  
  2784.    /* check renderType */
  2785.    if (renderType != GLX_RGBA_TYPE &&
  2786.        renderType != GLX_COLOR_INDEX_TYPE) {
  2787.       generate_error(dpy, BadValue, 0, X_GLXCreateContextAtrribsARB, True);
  2788.       return NULL;
  2789.    }
  2790.  
  2791.    /* check version */
  2792.    if (majorVersion <= 0 ||
  2793.        minorVersion < 0 ||
  2794.        (profileMask != GLX_CONTEXT_ES_PROFILE_BIT_EXT &&
  2795.         ((majorVersion == 1 && minorVersion > 5) ||
  2796.          (majorVersion == 2 && minorVersion > 1) ||
  2797.          (majorVersion == 3 && minorVersion > 3) ||
  2798.          (majorVersion == 4 && minorVersion > 5) ||
  2799.          majorVersion > 4))) {
  2800.       generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
  2801.       return NULL;
  2802.    }
  2803.    if (profileMask == GLX_CONTEXT_ES_PROFILE_BIT_EXT &&
  2804.        ((majorVersion == 1 && minorVersion > 1) ||
  2805.         (majorVersion == 2 && minorVersion > 0) ||
  2806.         (majorVersion == 3 && minorVersion > 1) ||
  2807.         majorVersion > 3)) {
  2808.       /* GLX_EXT_create_context_es2_profile says nothing to justifying a
  2809.        * different error code for invalid ES versions, but this is what NVIDIA
  2810.        * does and piglit expects.
  2811.        */
  2812.       generate_error(dpy, GLXBadProfileARB, 0, X_GLXCreateContextAtrribsARB, False);
  2813.       return NULL;
  2814.    }
  2815.  
  2816.    if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
  2817.        majorVersion < 3) {
  2818.       generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
  2819.       return NULL;
  2820.    }
  2821.  
  2822.    if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3) {
  2823.       generate_error(dpy, BadMatch, 0, X_GLXCreateContextAtrribsARB, True);
  2824.       return NULL;
  2825.    }
  2826.  
  2827.    ctx = create_context(dpy, xmvis,
  2828.                         shareCtx ? shareCtx->xmesaContext : NULL,
  2829.                         direct,
  2830.                         majorVersion, minorVersion,
  2831.                         profileMask, contextFlags);
  2832.    if (!ctx) {
  2833.       generate_error(dpy, GLXBadFBConfig, 0, X_GLXCreateContextAtrribsARB, False);
  2834.    }
  2835.  
  2836.    return ctx;
  2837. }
  2838.