Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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