Subversion Repositories Kolibri OS

Rev

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