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