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 #ifdef GLX_EXT_texture_from_pixmap
   1106          case GLX_BIND_TO_TEXTURE_RGB_EXT:
   1107             parselist++; /*skip*/
   1108             break;
   1109          case GLX_BIND_TO_TEXTURE_RGBA_EXT:
   1110             parselist++; /*skip*/
   1111             break;
   1112          case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
   1113             parselist++; /*skip*/
   1114             break;
   1115          case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
   1116             parselist++;
   1117             if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
   1118                                GLX_TEXTURE_2D_BIT_EXT |
   1119                                GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
   1120                /* invalid bit */
   1121                return NULL;
   1122             }
   1123             break;
   1124          case GLX_Y_INVERTED_EXT:
   1125             parselist++; /*skip*/
   1126             break;
   1127 #endif
   1128 
   1129 	 case None:
   1130             /* end of list */
   1131 	    break;
   1132 
   1133 	 default:
   1134 	    /* undefined attribute */
   1135             _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
   1136                           *parselist);
   1137 	    return NULL;
   1138       }
   1139    }
   1140 
   1141    if (!rgb_flag)
   1142       return NULL;
   1143 
   1144    (void) caveat;
   1145    (void) min_ci;
   1146 
   1147    /*
   1148     * Since we're only simulating the GLX extension this function will never
   1149     * find any real GL visuals.  Instead, all we can do is try to find an RGB
   1150     * or CI visual of appropriate depth.  Other requested attributes such as
   1151     * double buffering, depth buffer, etc. will be associated with the X
   1152     * visual and stored in the VisualTable[].
   1153     */
   1154    if (desiredVisualID != -1) {
   1155       /* try to get a specific visual, by visualID */
   1156       XVisualInfo temp;
   1157       int n;
   1158       temp.visualid = desiredVisualID;
   1159       temp.screen = screen;
   1160       vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
   1161       if (vis) {
   1162          /* give the visual some useful GLX attributes */
   1163          double_flag = GL_TRUE;
   1164          if (vis->depth <= 8)
   1165 	    return NULL;
   1166          depth_size = default_depth_bits();
   1167          stencil_size = 8;
   1168          /* XXX accum??? */
   1169       }
   1170    }
   1171    else {
   1172       /* RGB visual */
   1173       int min_rgb = min_red + min_green + min_blue;
   1174       if (min_rgb>1 && min_rgb<8) {
   1175 	 /* a special case to be sure we can get a monochrome visual */
   1176 	 min_rgb = 1;
   1177       }
   1178 
   1179       if (level==0) {
   1180 	 vis = choose_x_visual(dpy, screen, min_rgb, visual_type);
   1181       }
   1182       else {
   1183 	 vis = choose_x_overlay_visual(dpy, screen, level,
   1184 				       trans_type, trans_value, min_rgb, visual_type);
   1185       }
   1186    }
   1187 
   1188    if (vis) {
   1189       /* Note: we're not exactly obeying the glXChooseVisual rules here.
   1190        * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
   1191        * largest depth buffer size, which is 32bits/value.  Instead, we
   1192        * return 16 to maintain performance with earlier versions of Mesa.
   1193        */
   1194       if (depth_size > 24)
   1195          depth_size = 32;
   1196       else if (depth_size > 16)
   1197          depth_size = 24;
   1198       else if (depth_size > 0) {
   1199          depth_size = default_depth_bits();
   1200       }
   1201 
   1202       if (!alpha_flag) {
   1203          alpha_flag = default_alpha_bits() > 0;
   1204       }
   1205 
   1206       /* we only support one size of stencil and accum buffers. */
   1207       if (stencil_size > 0)
   1208          stencil_size = 8;
   1209       if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
   1210           accumAlphaSize > 0) {
   1211          accumRedSize =
   1212          accumGreenSize =
   1213          accumBlueSize = default_accum_bits();
   1214          accumAlphaSize = alpha_flag ? accumRedSize : 0;
   1215       }
   1216 
   1217       xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag,
   1218                                stereo_flag, depth_size, stencil_size,
   1219                                accumRedSize, accumGreenSize,
   1220                                accumBlueSize, accumAlphaSize, level, numAux );
   1221       free(vis);
   1222    }
   1223 
   1224    return xmvis;
   1225 }
   1226 
   1227 
   1228 static XVisualInfo *
   1229 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
   1230 {
   1231    XMesaVisual xmvis;
   1232 
   1233    /* register ourselves as an extension on this display */
   1234    register_with_display(dpy);
   1235 
   1236    xmvis = choose_visual(dpy, screen, list, GL_FALSE);
   1237    if (xmvis) {
   1238       XVisualInfo* visinfo = malloc(sizeof(XVisualInfo));
   1239       if (visinfo) {
   1240          memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo));
   1241       }
   1242       return visinfo;
   1243    }
   1244    else
   1245       return NULL;
   1246 }
   1247 
   1248 
   1249 static GLXContext
   1250 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
   1251                        GLXContext share_list, Bool direct )
   1252 {
   1253    XMesaVisual xmvis;
   1254    XMesaContext xmesaCtx;
   1255 
   1256    if (!dpy || !visinfo)
   1257       return 0;
   1258 
   1259    /* deallocate unused windows/buffers */
   1260 #if 0
   1261    XMesaGarbageCollect(dpy);
   1262 #endif
   1263 
   1264    xmvis = find_glx_visual( dpy, visinfo );
   1265    if (!xmvis) {
   1266       /* This visual wasn't found with glXChooseVisual() */
   1267       xmvis = create_glx_visual( dpy, visinfo );
   1268       if (!xmvis) {
   1269          return NULL;
   1270       }
   1271    }
   1272 
   1273    xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list);
   1274 
   1275    return (GLXContext) xmesaCtx;
   1276 }
   1277 
   1278 
   1279 /* XXX these may have to be removed due to thread-safety issues. */
   1280 static GLXContext MakeCurrent_PrevContext = 0;
   1281 static GLXDrawable MakeCurrent_PrevDrawable = 0;
   1282 static GLXDrawable MakeCurrent_PrevReadable = 0;
   1283 static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
   1284 static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
   1285 
   1286 
   1287 /* GLX 1.3 and later */
   1288 static Bool
   1289 Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
   1290                             GLXDrawable read, GLXContext ctx )
   1291 {
   1292    if (ctx && draw && read) {
   1293       XMesaBuffer drawBuffer, readBuffer;
   1294       XMesaContext xmctx = (XMesaContext) ctx;
   1295 
   1296       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
   1297       if (ctx == MakeCurrent_PrevContext
   1298           && draw == MakeCurrent_PrevDrawable) {
   1299          drawBuffer = MakeCurrent_PrevDrawBuffer;
   1300       }
   1301       else {
   1302          drawBuffer = XMesaFindBuffer( dpy, draw );
   1303       }
   1304       if (!drawBuffer) {
   1305          /* drawable must be a new window! */
   1306          drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
   1307          if (!drawBuffer) {
   1308             /* Out of memory, or context/drawable depth mismatch */
   1309             return False;
   1310          }
   1311       }
   1312 
   1313       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
   1314       if (ctx == MakeCurrent_PrevContext
   1315           && read == MakeCurrent_PrevReadable) {
   1316          readBuffer = MakeCurrent_PrevReadBuffer;
   1317       }
   1318       else {
   1319          readBuffer = XMesaFindBuffer( dpy, read );
   1320       }
   1321       if (!readBuffer) {
   1322          /* drawable must be a new window! */
   1323          readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
   1324          if (!readBuffer) {
   1325             /* Out of memory, or context/drawable depth mismatch */
   1326             return False;
   1327          }
   1328       }
   1329 
   1330       MakeCurrent_PrevContext = ctx;
   1331       MakeCurrent_PrevDrawable = draw;
   1332       MakeCurrent_PrevReadable = read;
   1333       MakeCurrent_PrevDrawBuffer = drawBuffer;
   1334       MakeCurrent_PrevReadBuffer = readBuffer;
   1335 
   1336       /* Now make current! */
   1337       return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer);
   1338    }
   1339    else if (!ctx && !draw && !read) {
   1340       /* release current context w/out assigning new one. */
   1341       XMesaMakeCurrent( NULL, NULL );
   1342       MakeCurrent_PrevContext = 0;
   1343       MakeCurrent_PrevDrawable = 0;
   1344       MakeCurrent_PrevReadable = 0;
   1345       MakeCurrent_PrevDrawBuffer = 0;
   1346       MakeCurrent_PrevReadBuffer = 0;
   1347       return True;
   1348    }
   1349    else {
   1350       /* The args must either all be non-zero or all zero.
   1351        * This is an error.
   1352        */
   1353       return False;
   1354    }
   1355 }
   1356 
   1357 
   1358 static Bool
   1359 Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
   1360 {
   1361    return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
   1362 }
   1363 
   1364 
   1365 static GLXPixmap
   1366 Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
   1367 {
   1368    XMesaVisual v;
   1369    XMesaBuffer b;
   1370 
   1371    v = find_glx_visual( dpy, visinfo );
   1372    if (!v) {
   1373       v = create_glx_visual( dpy, visinfo );
   1374       if (!v) {
   1375          /* unusable visual */
   1376          return 0;
   1377       }
   1378    }
   1379 
   1380    b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
   1381    if (!b) {
   1382       return 0;
   1383    }
   1384    return b->frontxrb->pixmap;
   1385 }
   1386 
   1387 
   1388 /*** GLX_MESA_pixmap_colormap ***/
   1389 
   1390 static GLXPixmap
   1391 Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
   1392                              Pixmap pixmap, Colormap cmap )
   1393 {
   1394    XMesaVisual v;
   1395    XMesaBuffer b;
   1396 
   1397    v = find_glx_visual( dpy, visinfo );
   1398    if (!v) {
   1399       v = create_glx_visual( dpy, visinfo );
   1400       if (!v) {
   1401          /* unusable visual */
   1402          return 0;
   1403       }
   1404    }
   1405 
   1406    b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
   1407    if (!b) {
   1408       return 0;
   1409    }
   1410    return b->frontxrb->pixmap;
   1411 }
   1412 
   1413 
   1414 static void
   1415 Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
   1416 {
   1417    XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
   1418    if (b) {
   1419       XMesaDestroyBuffer(b);
   1420    }
   1421    else if (getenv("MESA_DEBUG")) {
   1422       _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
   1423    }
   1424 }
   1425 
   1426 
   1427 static void
   1428 Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
   1429                      unsigned long mask )
   1430 {
   1431    XMesaContext xmSrc = (XMesaContext) src;
   1432    XMesaContext xmDst = (XMesaContext) dst;
   1433    (void) dpy;
   1434    if (MakeCurrent_PrevContext == src) {
   1435       _mesa_Flush();
   1436    }
   1437    _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask );
   1438 }
   1439 
   1440 
   1441 static Bool
   1442 Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
   1443 {
   1444    int op, ev, err;
   1445    /* Mesa's GLX isn't really an X extension but we try to act like one. */
   1446    if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err))
   1447       ev = err = 0;
   1448    if (errorBase)
   1449       *errorBase = err;
   1450    if (eventBase)
   1451       *eventBase = ev;
   1452    return True; /* we're faking GLX so always return success */
   1453 }
   1454 
   1455 
   1456 extern void _kw_ungrab_all( Display *dpy );
   1457 void _kw_ungrab_all( Display *dpy )
   1458 {
   1459    XUngrabPointer( dpy, CurrentTime );
   1460    XUngrabKeyboard( dpy, CurrentTime );
   1461 }
   1462 
   1463 
   1464 static void
   1465 Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
   1466 {
   1467    if (ctx) {
   1468       (void) dpy;
   1469       MakeCurrent_PrevContext = 0;
   1470       MakeCurrent_PrevDrawable = 0;
   1471       MakeCurrent_PrevReadable = 0;
   1472       MakeCurrent_PrevDrawBuffer = 0;
   1473       MakeCurrent_PrevReadBuffer = 0;
   1474       XMesaDestroyContext((XMesaContext) ctx);
   1475       XMesaGarbageCollect(dpy);
   1476    }
   1477 }
   1478 
   1479 
   1480 static Bool
   1481 Fake_glXIsDirect( Display *dpy, GLXContext ctx )
   1482 {
   1483    XMesaContext xmCtx = (XMesaContext) ctx;
   1484    return xmCtx ? xmCtx->direct : False;
   1485 }
   1486 
   1487 
   1488 
   1489 static void
   1490 Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
   1491 {
   1492    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
   1493 
   1494    if (buffer) {
   1495       XMesaSwapBuffers(buffer);
   1496    }
   1497    else if (getenv("MESA_DEBUG")) {
   1498       _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
   1499                     (int) drawable);
   1500    }
   1501 }
   1502 
   1503 
   1504 
   1505 /*** GLX_MESA_copy_sub_buffer ***/
   1506 
   1507 static void
   1508 Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
   1509                            int x, int y, int width, int height )
   1510 {
   1511    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
   1512    if (buffer) {
   1513       XMesaCopySubBuffer(buffer, x, y, width, height);
   1514    }
   1515    else if (getenv("MESA_DEBUG")) {
   1516       _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
   1517    }
   1518 }
   1519 
   1520 
   1521 static Bool
   1522 Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
   1523 {
   1524    (void) dpy;
   1525    /* Return GLX version, not Mesa version */
   1526    assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
   1527    *maj = CLIENT_MAJOR_VERSION;
   1528    *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
   1529    return True;
   1530 }
   1531 
   1532 
   1533 /*
   1534  * Query the GLX attributes of the given XVisualInfo.
   1535  */
   1536 static int
   1537 get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
   1538 {
   1539    assert(xmvis);
   1540    switch(attrib) {
   1541       case GLX_USE_GL:
   1542          if (fbconfig)
   1543             return GLX_BAD_ATTRIBUTE;
   1544          *value = (int) True;
   1545 	 return 0;
   1546       case GLX_BUFFER_SIZE:
   1547 	 *value = xmvis->visinfo->depth;
   1548 	 return 0;
   1549       case GLX_LEVEL:
   1550 	 *value = xmvis->mesa_visual.level;
   1551 	 return 0;
   1552       case GLX_RGBA:
   1553          if (fbconfig)
   1554             return GLX_BAD_ATTRIBUTE;
   1555 	 if (xmvis->mesa_visual.rgbMode) {
   1556 	    *value = True;
   1557 	 }
   1558 	 else {
   1559 	    *value = False;
   1560 	 }
   1561 	 return 0;
   1562       case GLX_DOUBLEBUFFER:
   1563 	 *value = (int) xmvis->mesa_visual.doubleBufferMode;
   1564 	 return 0;
   1565       case GLX_STEREO:
   1566 	 *value = (int) xmvis->mesa_visual.stereoMode;
   1567 	 return 0;
   1568       case GLX_AUX_BUFFERS:
   1569 	 *value = xmvis->mesa_visual.numAuxBuffers;
   1570 	 return 0;
   1571       case GLX_RED_SIZE:
   1572          *value = xmvis->mesa_visual.redBits;
   1573 	 return 0;
   1574       case GLX_GREEN_SIZE:
   1575          *value = xmvis->mesa_visual.greenBits;
   1576 	 return 0;
   1577       case GLX_BLUE_SIZE:
   1578          *value = xmvis->mesa_visual.blueBits;
   1579 	 return 0;
   1580       case GLX_ALPHA_SIZE:
   1581          *value = xmvis->mesa_visual.alphaBits;
   1582 	 return 0;
   1583       case GLX_DEPTH_SIZE:
   1584          *value = xmvis->mesa_visual.depthBits;
   1585 	 return 0;
   1586       case GLX_STENCIL_SIZE:
   1587 	 *value = xmvis->mesa_visual.stencilBits;
   1588 	 return 0;
   1589       case GLX_ACCUM_RED_SIZE:
   1590 	 *value = xmvis->mesa_visual.accumRedBits;
   1591 	 return 0;
   1592       case GLX_ACCUM_GREEN_SIZE:
   1593 	 *value = xmvis->mesa_visual.accumGreenBits;
   1594 	 return 0;
   1595       case GLX_ACCUM_BLUE_SIZE:
   1596 	 *value = xmvis->mesa_visual.accumBlueBits;
   1597 	 return 0;
   1598       case GLX_ACCUM_ALPHA_SIZE:
   1599          *value = xmvis->mesa_visual.accumAlphaBits;
   1600 	 return 0;
   1601 
   1602       /*
   1603        * GLX_EXT_visual_info extension
   1604        */
   1605       case GLX_X_VISUAL_TYPE_EXT:
   1606          switch (xmvis->visinfo->CLASS) {
   1607             case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
   1608             case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
   1609             case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
   1610             case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
   1611             case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
   1612             case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
   1613          }
   1614          return 0;
   1615       case GLX_TRANSPARENT_TYPE_EXT:
   1616          if (xmvis->mesa_visual.level==0) {
   1617             /* normal planes */
   1618             *value = GLX_NONE_EXT;
   1619          }
   1620          else if (xmvis->mesa_visual.level>0) {
   1621             /* overlay */
   1622             if (xmvis->mesa_visual.rgbMode) {
   1623                *value = GLX_TRANSPARENT_RGB_EXT;
   1624             }
   1625             else {
   1626                *value = GLX_TRANSPARENT_INDEX_EXT;
   1627             }
   1628          }
   1629          else if (xmvis->mesa_visual.level<0) {
   1630             /* underlay */
   1631             *value = GLX_NONE_EXT;
   1632          }
   1633          return 0;
   1634       case GLX_TRANSPARENT_INDEX_VALUE_EXT:
   1635          {
   1636             int pixel = transparent_pixel( xmvis );
   1637             if (pixel>=0) {
   1638                *value = pixel;
   1639             }
   1640             /* else undefined */
   1641          }
   1642          return 0;
   1643       case GLX_TRANSPARENT_RED_VALUE_EXT:
   1644          /* undefined */
   1645          return 0;
   1646       case GLX_TRANSPARENT_GREEN_VALUE_EXT:
   1647          /* undefined */
   1648          return 0;
   1649       case GLX_TRANSPARENT_BLUE_VALUE_EXT:
   1650          /* undefined */
   1651          return 0;
   1652       case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
   1653          /* undefined */
   1654          return 0;
   1655 
   1656       /*
   1657        * GLX_EXT_visual_info extension
   1658        */
   1659       case GLX_VISUAL_CAVEAT_EXT:
   1660          /* test for zero, just in case */
   1661          if (xmvis->mesa_visual.visualRating > 0)
   1662             *value = xmvis->mesa_visual.visualRating;
   1663          else
   1664             *value = GLX_NONE_EXT;
   1665          return 0;
   1666 
   1667       /*
   1668        * GLX_ARB_multisample
   1669        */
   1670       case GLX_SAMPLE_BUFFERS_ARB:
   1671          *value = 0;
   1672          return 0;
   1673       case GLX_SAMPLES_ARB:
   1674          *value = 0;
   1675          return 0;
   1676 
   1677       /*
   1678        * For FBConfigs:
   1679        */
   1680       case GLX_SCREEN_EXT:
   1681          if (!fbconfig)
   1682             return GLX_BAD_ATTRIBUTE;
   1683          *value = xmvis->visinfo->screen;
   1684          break;
   1685       case GLX_DRAWABLE_TYPE: /*SGIX too */
   1686          if (!fbconfig)
   1687             return GLX_BAD_ATTRIBUTE;
   1688          *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
   1689          break;
   1690       case GLX_RENDER_TYPE_SGIX:
   1691          if (!fbconfig)
   1692             return GLX_BAD_ATTRIBUTE;
   1693          if (xmvis->mesa_visual.floatMode)
   1694             *value = GLX_RGBA_FLOAT_BIT_ARB;
   1695          else if (xmvis->mesa_visual.rgbMode)
   1696             *value = GLX_RGBA_BIT;
   1697          else
   1698             *value = GLX_COLOR_INDEX_BIT;
   1699          break;
   1700       case GLX_X_RENDERABLE_SGIX:
   1701          if (!fbconfig)
   1702             return GLX_BAD_ATTRIBUTE;
   1703          *value = True; /* XXX really? */
   1704          break;
   1705       case GLX_FBCONFIG_ID_SGIX:
   1706          if (!fbconfig)
   1707             return GLX_BAD_ATTRIBUTE;
   1708          *value = xmvis->visinfo->visualid;
   1709          break;
   1710       case GLX_MAX_PBUFFER_WIDTH:
   1711          if (!fbconfig)
   1712             return GLX_BAD_ATTRIBUTE;
   1713          /* XXX should be same as ctx->Const.MaxRenderbufferSize */
   1714          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
   1715          break;
   1716       case GLX_MAX_PBUFFER_HEIGHT:
   1717          if (!fbconfig)
   1718             return GLX_BAD_ATTRIBUTE;
   1719          *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
   1720          break;
   1721       case GLX_MAX_PBUFFER_PIXELS:
   1722          if (!fbconfig)
   1723             return GLX_BAD_ATTRIBUTE;
   1724          *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
   1725                   DisplayHeight(xmvis->display, xmvis->visinfo->screen);
   1726          break;
   1727       case GLX_VISUAL_ID:
   1728          if (!fbconfig)
   1729             return GLX_BAD_ATTRIBUTE;
   1730          *value = xmvis->visinfo->visualid;
   1731          break;
   1732 
   1733 #ifdef GLX_EXT_texture_from_pixmap
   1734       case GLX_BIND_TO_TEXTURE_RGB_EXT:
   1735          *value = True; /*XXX*/
   1736          break;
   1737       case GLX_BIND_TO_TEXTURE_RGBA_EXT:
   1738          /* XXX review */
   1739          *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
   1740          break;
   1741       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
   1742          *value = True; /*XXX*/
   1743          break;
   1744       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
   1745          *value = (GLX_TEXTURE_1D_BIT_EXT |
   1746                    GLX_TEXTURE_2D_BIT_EXT |
   1747                    GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
   1748          break;
   1749       case GLX_Y_INVERTED_EXT:
   1750          *value = True; /*XXX*/
   1751          break;
   1752 #endif
   1753 
   1754       default:
   1755 	 return GLX_BAD_ATTRIBUTE;
   1756    }
   1757    return Success;
   1758 }
   1759 
   1760 
   1761 static int
   1762 Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
   1763                    int attrib, int *value )
   1764 {
   1765    XMesaVisual xmvis;
   1766    int k;
   1767    if (!dpy || !visinfo)
   1768       return GLX_BAD_ATTRIBUTE;
   1769 
   1770    xmvis = find_glx_visual( dpy, visinfo );
   1771    if (!xmvis) {
   1772       /* this visual wasn't obtained with glXChooseVisual */
   1773       xmvis = create_glx_visual( dpy, visinfo );
   1774       if (!xmvis) {
   1775 	 /* this visual can't be used for GL rendering */
   1776 	 if (attrib==GLX_USE_GL) {
   1777 	    *value = (int) False;
   1778 	    return 0;
   1779 	 }
   1780 	 else {
   1781 	    return GLX_BAD_VISUAL;
   1782 	 }
   1783       }
   1784    }
   1785 
   1786    k = get_config(xmvis, attrib, value, GL_FALSE);
   1787    return k;
   1788 }
   1789 
   1790 
   1791 static GLXContext
   1792 Fake_glXGetCurrentContext(void)
   1793 {
   1794    XMesaContext xmesa = XMesaGetCurrentContext();
   1795    return (GLXContext) xmesa;
   1796 }
   1797 
   1798 static void
   1799 Fake_glXWaitGL( void )
   1800 {
   1801    XMesaContext xmesa = XMesaGetCurrentContext();
   1802    XMesaFlush( xmesa );
   1803 }
   1804 
   1805 
   1806 
   1807 static void
   1808 Fake_glXWaitX( void )
   1809 {
   1810    XMesaContext xmesa = XMesaGetCurrentContext();
   1811    XMesaFlush( xmesa );
   1812 }
   1813 
   1814 
   1815 static const char *
   1816 get_extensions( void )
   1817 {
   1818    return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */
   1819 }
   1820 
   1821 
   1822 
   1823 /* GLX 1.1 and later */
   1824 static const char *
   1825 Fake_glXQueryExtensionsString( Display *dpy, int screen )
   1826 {
   1827    (void) dpy;
   1828    (void) screen;
   1829    return get_extensions();
   1830 }
   1831 
   1832 
   1833 
   1834 /* GLX 1.1 and later */
   1835 static const char *
   1836 Fake_glXQueryServerString( Display *dpy, int screen, int name )
   1837 {
   1838    static char version[1000];
   1839    sprintf(version, "%d.%d %s",
   1840 	   SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
   1841 
   1842    (void) dpy;
   1843    (void) screen;
   1844 
   1845    switch (name) {
   1846       case GLX_EXTENSIONS:
   1847          return get_extensions();
   1848       case GLX_VENDOR:
   1849 	 return VENDOR;
   1850       case GLX_VERSION:
   1851 	 return version;
   1852       default:
   1853          return NULL;
   1854    }
   1855 }
   1856 
   1857 
   1858 
   1859 /* GLX 1.1 and later */
   1860 static const char *
   1861 Fake_glXGetClientString( Display *dpy, int name )
   1862 {
   1863    static char version[1000];
   1864    sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
   1865 	   CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
   1866 
   1867    (void) dpy;
   1868 
   1869    switch (name) {
   1870       case GLX_EXTENSIONS:
   1871          return get_extensions();
   1872       case GLX_VENDOR:
   1873 	 return VENDOR;
   1874       case GLX_VERSION:
   1875 	 return version;
   1876       default:
   1877          return NULL;
   1878    }
   1879 }
   1880 
   1881 
   1882 
   1883 /*
   1884  * GLX 1.3 and later
   1885  */
   1886 
   1887 
   1888 static int
   1889 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
   1890                            int attribute, int *value )
   1891 {
   1892    XMesaVisual v = (XMesaVisual) config;
   1893    (void) dpy;
   1894    (void) config;
   1895 
   1896    if (!dpy || !config || !value)
   1897       return -1;
   1898 
   1899    return get_config(v, attribute, value, GL_TRUE);
   1900 }
   1901 
   1902 
   1903 static GLXFBConfig *
   1904 Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
   1905 {
   1906    XVisualInfo *visuals, visTemplate;
   1907    const long visMask = VisualScreenMask;
   1908    int i;
   1909 
   1910    /* Get list of all X visuals */
   1911    visTemplate.screen = screen;
   1912    visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
   1913    if (*nelements > 0) {
   1914       XMesaVisual *results;
   1915       results = malloc(*nelements * sizeof(XMesaVisual));
   1916       if (!results) {
   1917          *nelements = 0;
   1918          return NULL;
   1919       }
   1920       for (i = 0; i < *nelements; i++) {
   1921          results[i] = create_glx_visual(dpy, visuals + i);
   1922       }
   1923       free(visuals);
   1924       return (GLXFBConfig *) results;
   1925    }
   1926    return NULL;
   1927 }
   1928 
   1929 
   1930 static GLXFBConfig *
   1931 Fake_glXChooseFBConfig( Display *dpy, int screen,
   1932                         const int *attribList, int *nitems )
   1933 {
   1934    XMesaVisual xmvis;
   1935 
   1936    /* register ourselves as an extension on this display */
   1937    register_with_display(dpy);
   1938 
   1939    if (!attribList || !attribList[0]) {
   1940       /* return list of all configs (per GLX_SGIX_fbconfig spec) */
   1941       return Fake_glXGetFBConfigs(dpy, screen, nitems);
   1942    }
   1943 
   1944    xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
   1945    if (xmvis) {
   1946       GLXFBConfig *config = malloc(sizeof(XMesaVisual));
   1947       if (!config) {
   1948          *nitems = 0;
   1949          return NULL;
   1950       }
   1951       *nitems = 1;
   1952       config[0] = (GLXFBConfig) xmvis;
   1953       return (GLXFBConfig *) config;
   1954    }
   1955    else {
   1956       *nitems = 0;
   1957       return NULL;
   1958    }
   1959 }
   1960 
   1961 
   1962 static XVisualInfo *
   1963 Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
   1964 {
   1965    if (dpy && config) {
   1966       XMesaVisual xmvis = (XMesaVisual) config;
   1967       XVisualInfo* visinfo = malloc(sizeof(XVisualInfo));
   1968       if (visinfo) {
   1969          memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo));
   1970       }
   1971       return visinfo;
   1972    }
   1973    else {
   1974       return NULL;
   1975    }
   1976 }
   1977 
   1978 
   1979 static GLXWindow
   1980 Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
   1981                       const int *attribList )
   1982 {
   1983    XMesaVisual xmvis = (XMesaVisual) config;
   1984    XMesaBuffer xmbuf;
   1985    if (!xmvis)
   1986       return 0;
   1987 
   1988    xmbuf = XMesaCreateWindowBuffer(xmvis, win);
   1989    if (!xmbuf)
   1990       return 0;
   1991 
   1992    (void) dpy;
   1993    (void) attribList;  /* Ignored in GLX 1.3 */
   1994 
   1995    return win;  /* A hack for now */
   1996 }
   1997 
   1998 
   1999 static void
   2000 Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
   2001 {
   2002    XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window);
   2003    if (b)
   2004       XMesaDestroyBuffer(b);
   2005    /* don't destroy X window */
   2006 }
   2007 
   2008 
   2009 /* XXX untested */
   2010 static GLXPixmap
   2011 Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
   2012                       const int *attribList )
   2013 {
   2014    XMesaVisual v = (XMesaVisual) config;
   2015    XMesaBuffer b;
   2016    const int *attr;
   2017    int target = 0, format = 0, mipmap = 0;
   2018    int value;
   2019 
   2020    if (!dpy || !config || !pixmap)
   2021       return 0;
   2022 
   2023    for (attr = attribList; attr && *attr; attr++) {
   2024       switch (*attr) {
   2025       case GLX_TEXTURE_FORMAT_EXT:
   2026          attr++;
   2027          switch (*attr) {
   2028          case GLX_TEXTURE_FORMAT_NONE_EXT:
   2029          case GLX_TEXTURE_FORMAT_RGB_EXT:
   2030          case GLX_TEXTURE_FORMAT_RGBA_EXT:
   2031             format = *attr;
   2032             break;
   2033          default:
   2034             /* error */
   2035             return 0;
   2036          }
   2037          break;
   2038       case GLX_TEXTURE_TARGET_EXT:
   2039          attr++;
   2040          switch (*attr) {
   2041          case GLX_TEXTURE_1D_EXT:
   2042          case GLX_TEXTURE_2D_EXT:
   2043          case GLX_TEXTURE_RECTANGLE_EXT:
   2044             target = *attr;
   2045             break;
   2046          default:
   2047             /* error */
   2048             return 0;
   2049          }
   2050          break;
   2051       case GLX_MIPMAP_TEXTURE_EXT:
   2052          attr++;
   2053          if (*attr)
   2054             mipmap = 1;
   2055          break;
   2056       default:
   2057          /* error */
   2058          return 0;
   2059       }
   2060    }
   2061 
   2062    if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
   2063       if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
   2064                      &value, GL_TRUE) != Success
   2065           || !value) {
   2066          return 0; /* error! */
   2067       }
   2068    }
   2069    else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
   2070       if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
   2071                      &value, GL_TRUE) != Success
   2072           || !value) {
   2073          return 0; /* error! */
   2074       }
   2075    }
   2076    if (mipmap) {
   2077       if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
   2078                      &value, GL_TRUE) != Success
   2079           || !value) {
   2080          return 0; /* error! */
   2081       }
   2082    }
   2083    if (target == GLX_TEXTURE_1D_EXT) {
   2084       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
   2085                      &value, GL_TRUE) != Success
   2086           || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
   2087          return 0; /* error! */
   2088       }
   2089    }
   2090    else if (target == GLX_TEXTURE_2D_EXT) {
   2091       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
   2092                      &value, GL_TRUE) != Success
   2093           || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
   2094          return 0; /* error! */
   2095       }
   2096    }
   2097    if (target == GLX_TEXTURE_RECTANGLE_EXT) {
   2098       if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
   2099                      &value, GL_TRUE) != Success
   2100           || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
   2101          return 0; /* error! */
   2102       }
   2103    }
   2104 
   2105    if (format || target || mipmap) {
   2106       /* texture from pixmap */
   2107       b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
   2108    }
   2109    else {
   2110       b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
   2111    }
   2112    if (!b) {
   2113       return 0;
   2114    }
   2115 
   2116    return pixmap;
   2117 }
   2118 
   2119 
   2120 static void
   2121 Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
   2122 {
   2123    XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap);
   2124    if (b)
   2125       XMesaDestroyBuffer(b);
   2126    /* don't destroy X pixmap */
   2127 }
   2128 
   2129 
   2130 static GLXPbuffer
   2131 Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
   2132                        const int *attribList )
   2133 {
   2134    XMesaVisual xmvis = (XMesaVisual) config;
   2135    XMesaBuffer xmbuf;
   2136    const int *attrib;
   2137    int width = 0, height = 0;
   2138    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
   2139 
   2140    (void) dpy;
   2141 
   2142    for (attrib = attribList; *attrib; attrib++) {
   2143       switch (*attrib) {
   2144          case GLX_PBUFFER_WIDTH:
   2145             attrib++;
   2146             width = *attrib;
   2147             break;
   2148          case GLX_PBUFFER_HEIGHT:
   2149             attrib++;
   2150             height = *attrib;
   2151             break;
   2152          case GLX_PRESERVED_CONTENTS:
   2153             attrib++;
   2154             preserveContents = *attrib;
   2155             break;
   2156          case GLX_LARGEST_PBUFFER:
   2157             attrib++;
   2158             useLargest = *attrib;
   2159             break;
   2160          default:
   2161             return 0;
   2162       }
   2163    }
   2164 
   2165    if (width == 0 || height == 0)
   2166       return 0;
   2167 
   2168    if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
   2169       /* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
   2170        * allocate the largest possible buffer.
   2171        */
   2172       if (useLargest) {
   2173          width = SWRAST_MAX_WIDTH;
   2174          height = SWRAST_MAX_HEIGHT;
   2175       }
   2176    }
   2177 
   2178    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
   2179    /* A GLXPbuffer handle must be an X Drawable because that's what
   2180     * glXMakeCurrent takes.
   2181     */
   2182    if (xmbuf) {
   2183       xmbuf->largestPbuffer = useLargest;
   2184       xmbuf->preservedContents = preserveContents;
   2185       return (GLXPbuffer) xmbuf->frontxrb->pixmap;
   2186    }
   2187    else {
   2188       return 0;
   2189    }
   2190 }
   2191 
   2192 
   2193 static void
   2194 Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
   2195 {
   2196    XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
   2197    if (b) {
   2198       XMesaDestroyBuffer(b);
   2199    }
   2200 }
   2201 
   2202 
   2203 static void
   2204 Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
   2205                        unsigned int *value )
   2206 {
   2207    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
   2208    if (!xmbuf)
   2209       return;
   2210 
   2211    /* make sure buffer's dimensions are up to date */
   2212    xmesa_check_and_update_buffer_size(NULL, xmbuf);
   2213 
   2214    switch (attribute) {
   2215       case GLX_WIDTH:
   2216          *value = xmbuf->mesa_buffer.Width;
   2217          break;
   2218       case GLX_HEIGHT:
   2219          *value = xmbuf->mesa_buffer.Height;
   2220          break;
   2221       case GLX_PRESERVED_CONTENTS:
   2222          *value = xmbuf->preservedContents;
   2223          break;
   2224       case GLX_LARGEST_PBUFFER:
   2225          *value = xmbuf->largestPbuffer;
   2226          break;
   2227       case GLX_FBCONFIG_ID:
   2228          *value = xmbuf->xm_visual->visinfo->visualid;
   2229          return;
   2230 #ifdef GLX_EXT_texture_from_pixmap
   2231       case GLX_TEXTURE_FORMAT_EXT:
   2232          *value = xmbuf->TextureFormat;
   2233          break;
   2234       case GLX_TEXTURE_TARGET_EXT:
   2235          *value = xmbuf->TextureTarget;
   2236          break;
   2237       case GLX_MIPMAP_TEXTURE_EXT:
   2238          *value = xmbuf->TextureMipmap;
   2239          break;
   2240 #endif
   2241 
   2242       default:
   2243          return; /* raise BadValue error */
   2244    }
   2245 }
   2246 
   2247 
   2248 static GLXContext
   2249 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
   2250                           int renderType, GLXContext shareList, Bool direct )
   2251 {
   2252    XMesaContext xmCtx;
   2253    XMesaVisual xmvis = (XMesaVisual) config;
   2254 
   2255    if (!dpy || !config ||
   2256        (renderType != GLX_RGBA_TYPE &&
   2257         renderType != GLX_COLOR_INDEX_TYPE &&
   2258         renderType != GLX_RGBA_FLOAT_TYPE_ARB &&
   2259         renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT))
   2260       return 0;
   2261 
   2262    /* deallocate unused windows/buffers */
   2263    XMesaGarbageCollect(dpy);
   2264 
   2265    xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList);
   2266 
   2267    return (GLXContext) xmCtx;
   2268 }
   2269 
   2270 
   2271 static int
   2272 Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
   2273 {
   2274    XMesaContext xmctx = (XMesaContext) ctx;
   2275    (void) dpy;
   2276    (void) ctx;
   2277 
   2278    switch (attribute) {
   2279    case GLX_FBCONFIG_ID:
   2280       *value = xmctx->xm_visual->visinfo->visualid;
   2281       break;
   2282    case GLX_RENDER_TYPE:
   2283       *value = GLX_RGBA_TYPE;
   2284       break;
   2285    case GLX_SCREEN:
   2286       *value = 0;
   2287       return Success;
   2288    default:
   2289       return GLX_BAD_ATTRIBUTE;
   2290    }
   2291    return 0;
   2292 }
   2293 
   2294 
   2295 static void
   2296 Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
   2297 {
   2298    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   2299    if (xmbuf)
   2300       xmbuf->selectedEvents = mask;
   2301 }
   2302 
   2303 
   2304 static void
   2305 Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
   2306                           unsigned long *mask )
   2307 {
   2308    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   2309    if (xmbuf)
   2310       *mask = xmbuf->selectedEvents;
   2311    else
   2312       *mask = 0;
   2313 }
   2314 
   2315 
   2316 
   2317 /*** GLX_SGI_swap_control ***/
   2318 
   2319 static int
   2320 Fake_glXSwapIntervalSGI(int interval)
   2321 {
   2322    (void) interval;
   2323    return 0;
   2324 }
   2325 
   2326 
   2327 
   2328 /*** GLX_SGI_video_sync ***/
   2329 
   2330 static unsigned int FrameCounter = 0;
   2331 
   2332 static int
   2333 Fake_glXGetVideoSyncSGI(unsigned int *count)
   2334 {
   2335    /* this is a bogus implementation */
   2336    *count = FrameCounter++;
   2337    return 0;
   2338 }
   2339 
   2340 static int
   2341 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
   2342 {
   2343    if (divisor <= 0 || remainder < 0)
   2344       return GLX_BAD_VALUE;
   2345    /* this is a bogus implementation */
   2346    FrameCounter++;
   2347    while (FrameCounter % divisor != remainder)
   2348       FrameCounter++;
   2349    *count = FrameCounter;
   2350    return 0;
   2351 }
   2352 
   2353 
   2354 
   2355 /*** GLX_SGI_make_current_read ***/
   2356 
   2357 static Bool
   2358 Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
   2359 {
   2360    return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
   2361 }
   2362 
   2363 /* not used
   2364 static GLXDrawable
   2365 Fake_glXGetCurrentReadDrawableSGI(void)
   2366 {
   2367    return 0;
   2368 }
   2369 */
   2370 
   2371 
   2372 /*** GLX_SGIX_video_source ***/
   2373 #if defined(_VL_H)
   2374 
   2375 static GLXVideoSourceSGIX
   2376 Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
   2377 {
   2378    (void) dpy;
   2379    (void) screen;
   2380    (void) server;
   2381    (void) path;
   2382    (void) nodeClass;
   2383    (void) drainNode;
   2384    return 0;
   2385 }
   2386 
   2387 static void
   2388 Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
   2389 {
   2390    (void) dpy;
   2391    (void) src;
   2392 }
   2393 
   2394 #endif
   2395 
   2396 
   2397 /*** GLX_EXT_import_context ***/
   2398 
   2399 static void
   2400 Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
   2401 {
   2402    (void) dpy;
   2403    (void) context;
   2404 }
   2405 
   2406 static GLXContextID
   2407 Fake_glXGetContextIDEXT(const GLXContext context)
   2408 {
   2409    (void) context;
   2410    return 0;
   2411 }
   2412 
   2413 static GLXContext
   2414 Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
   2415 {
   2416    (void) dpy;
   2417    (void) contextID;
   2418    return 0;
   2419 }
   2420 
   2421 static int
   2422 Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
   2423 {
   2424    (void) dpy;
   2425    (void) context;
   2426    (void) attribute;
   2427    (void) value;
   2428    return 0;
   2429 }
   2430 
   2431 
   2432 
   2433 /*** GLX_SGIX_fbconfig ***/
   2434 
   2435 static int
   2436 Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
   2437 {
   2438    return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value);
   2439 }
   2440 
   2441 static GLXFBConfigSGIX *
   2442 Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
   2443 {
   2444    return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements);
   2445 }
   2446 
   2447 
   2448 static GLXPixmap
   2449 Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
   2450 {
   2451    XMesaVisual xmvis = (XMesaVisual) config;
   2452    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
   2453    return xmbuf->frontxrb->pixmap; /* need to return an X ID */
   2454 }
   2455 
   2456 
   2457 static GLXContext
   2458 Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
   2459 {
   2460    XMesaContext xmCtx;
   2461    XMesaVisual xmvis = (XMesaVisual) config;
   2462 
   2463    /* deallocate unused windows/buffers */
   2464    XMesaGarbageCollect(dpy);
   2465 
   2466    xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list);
   2467 
   2468    return (GLXContext) xmCtx;
   2469 }
   2470 
   2471 
   2472 static XVisualInfo *
   2473 Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
   2474 {
   2475    return Fake_glXGetVisualFromFBConfig(dpy, config);
   2476 }
   2477 
   2478 
   2479 static GLXFBConfigSGIX
   2480 Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
   2481 {
   2482    XMesaVisual xmvis = find_glx_visual(dpy, vis);
   2483    if (!xmvis) {
   2484       /* This visual wasn't found with glXChooseVisual() */
   2485       xmvis = create_glx_visual(dpy, vis);
   2486    }
   2487 
   2488    return (GLXFBConfigSGIX) xmvis;
   2489 }
   2490 
   2491 
   2492 
   2493 /*** GLX_SGIX_pbuffer ***/
   2494 
   2495 static GLXPbufferSGIX
   2496 Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
   2497                              unsigned int width, unsigned int height,
   2498                              int *attribList)
   2499 {
   2500    XMesaVisual xmvis = (XMesaVisual) config;
   2501    XMesaBuffer xmbuf;
   2502    const int *attrib;
   2503    GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;
   2504 
   2505    (void) dpy;
   2506 
   2507    for (attrib = attribList; attrib && *attrib; attrib++) {
   2508       switch (*attrib) {
   2509          case GLX_PRESERVED_CONTENTS_SGIX:
   2510             attrib++;
   2511             preserveContents = *attrib; /* ignored */
   2512             break;
   2513          case GLX_LARGEST_PBUFFER_SGIX:
   2514             attrib++;
   2515             useLargest = *attrib; /* ignored */
   2516             break;
   2517          default:
   2518             return 0;
   2519       }
   2520    }
   2521 
   2522    /* not used at this time */
   2523    (void) useLargest;
   2524    (void) preserveContents;
   2525 
   2526    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
   2527    /* A GLXPbuffer handle must be an X Drawable because that's what
   2528     * glXMakeCurrent takes.
   2529     */
   2530    return (GLXPbuffer) xmbuf->frontxrb->pixmap;
   2531 }
   2532 
   2533 
   2534 static void
   2535 Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
   2536 {
   2537    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
   2538    if (xmbuf) {
   2539       XMesaDestroyBuffer(xmbuf);
   2540    }
   2541 }
   2542 
   2543 
   2544 static int
   2545 Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
   2546 {
   2547    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
   2548 
   2549    if (!xmbuf) {
   2550       /* Generate GLXBadPbufferSGIX for bad pbuffer */
   2551       return 0;
   2552    }
   2553 
   2554    switch (attribute) {
   2555       case GLX_PRESERVED_CONTENTS_SGIX:
   2556          *value = xmbuf->preservedContents;
   2557          break;
   2558       case GLX_LARGEST_PBUFFER_SGIX:
   2559          *value = xmbuf->largestPbuffer;
   2560          break;
   2561       case GLX_WIDTH_SGIX:
   2562          *value = xmbuf->mesa_buffer.Width;
   2563          break;
   2564       case GLX_HEIGHT_SGIX:
   2565          *value = xmbuf->mesa_buffer.Height;
   2566          break;
   2567       case GLX_EVENT_MASK_SGIX:
   2568          *value = 0;  /* XXX might be wrong */
   2569          break;
   2570       default:
   2571          *value = 0;
   2572    }
   2573    return 0;
   2574 }
   2575 
   2576 
   2577 static void
   2578 Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
   2579 {
   2580    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   2581    if (xmbuf) {
   2582       /* Note: we'll never generate clobber events */
   2583       xmbuf->selectedEvents = mask;
   2584    }
   2585 }
   2586 
   2587 
   2588 static void
   2589 Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
   2590 {
   2591    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   2592    if (xmbuf) {
   2593       *mask = xmbuf->selectedEvents;
   2594    }
   2595    else {
   2596       *mask = 0;
   2597    }
   2598 }
   2599 
   2600 
   2601 
   2602 /*** GLX_SGI_cushion ***/
   2603 
   2604 static void
   2605 Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
   2606 {
   2607    (void) dpy;
   2608    (void) win;
   2609    (void) cushion;
   2610 }
   2611 
   2612 
   2613 
   2614 /*** GLX_SGIX_video_resize ***/
   2615 
   2616 static int
   2617 Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
   2618 {
   2619    (void) dpy;
   2620    (void) screen;
   2621    (void) channel;
   2622    (void) window;
   2623    return 0;
   2624 }
   2625 
   2626 static int
   2627 Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
   2628 {
   2629    (void) dpy;
   2630    (void) screen;
   2631    (void) channel;
   2632    (void) x;
   2633    (void) y;
   2634    (void) w;
   2635    (void) h;
   2636    return 0;
   2637 }
   2638 
   2639 static int
   2640 Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
   2641 {
   2642    (void) dpy;
   2643    (void) screen;
   2644    (void) channel;
   2645    (void) x;
   2646    (void) y;
   2647    (void) w;
   2648    (void) h;
   2649    return 0;
   2650 }
   2651 
   2652 static int
   2653 Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
   2654 {
   2655    (void) dpy;
   2656    (void) screen;
   2657    (void) channel;
   2658    (void) dx;
   2659    (void) dy;
   2660    (void) dw;
   2661    (void) dh;
   2662    return 0;
   2663 }
   2664 
   2665 static int
   2666 Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
   2667 {
   2668    (void) dpy;
   2669    (void) screen;
   2670    (void) channel;
   2671    (void) synctype;
   2672    return 0;
   2673 }
   2674 
   2675 
   2676 
   2677 /*** GLX_SGIX_dmbuffer **/
   2678 
   2679 #if defined(_DM_BUFFER_H_)
   2680 static Bool
   2681 Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
   2682 {
   2683    (void) dpy;
   2684    (void) pbuffer;
   2685    (void) params;
   2686    (void) dmbuffer;
   2687    return False;
   2688 }
   2689 #endif
   2690 
   2691 
   2692 /*** GLX_SGIX_swap_group ***/
   2693 
   2694 static void
   2695 Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
   2696 {
   2697    (void) dpy;
   2698    (void) drawable;
   2699    (void) member;
   2700 }
   2701 
   2702 
   2703 
   2704 /*** GLX_SGIX_swap_barrier ***/
   2705 
   2706 static void
   2707 Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
   2708 {
   2709    (void) dpy;
   2710    (void) drawable;
   2711    (void) barrier;
   2712 }
   2713 
   2714 static Bool
   2715 Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
   2716 {
   2717    (void) dpy;
   2718    (void) screen;
   2719    (void) max;
   2720    return False;
   2721 }
   2722 
   2723 
   2724 
   2725 /*** GLX_SUN_get_transparent_index ***/
   2726 
   2727 static Status
   2728 Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
   2729 {
   2730    (void) dpy;
   2731    (void) overlay;
   2732    (void) underlay;
   2733    (void) pTransparent;
   2734    return 0;
   2735 }
   2736 
   2737 
   2738 
   2739 /*** GLX_MESA_release_buffers ***/
   2740 
   2741 /*
   2742  * Release the depth, stencil, accum buffers attached to a GLXDrawable
   2743  * (a window or pixmap) prior to destroying the GLXDrawable.
   2744  */
   2745 static Bool
   2746 Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
   2747 {
   2748    XMesaBuffer b = XMesaFindBuffer(dpy, d);
   2749    if (b) {
   2750       XMesaDestroyBuffer(b);
   2751       return True;
   2752    }
   2753    return False;
   2754 }
   2755 
   2756 
   2757 
   2758 /*** GLX_MESA_set_3dfx_mode ***/
   2759 
   2760 static Bool
   2761 Fake_glXSet3DfxModeMESA( int mode )
   2762 {
   2763    return XMesaSetFXmode( mode );
   2764 }
   2765 
   2766 
   2767 
   2768 /*** GLX_NV_vertex_array range ***/
   2769 static void *
   2770 Fake_glXAllocateMemoryNV( GLsizei size,
   2771                           GLfloat readFrequency,
   2772                           GLfloat writeFrequency,
   2773                           GLfloat priority )
   2774 {
   2775    (void) size;
   2776    (void) readFrequency;
   2777    (void) writeFrequency;
   2778    (void) priority;
   2779    return NULL;
   2780 }
   2781 
   2782 
   2783 static void
   2784 Fake_glXFreeMemoryNV( GLvoid *pointer )
   2785 {
   2786    (void) pointer;
   2787 }
   2788 
   2789 
   2790 /*** GLX_MESA_agp_offset ***/
   2791 
   2792 static GLuint
   2793 Fake_glXGetAGPOffsetMESA( const GLvoid *pointer )
   2794 {
   2795    (void) pointer;
   2796    return ~0;
   2797 }
   2798 
   2799 
   2800 /*** GLX_EXT_texture_from_pixmap ***/
   2801 
   2802 static void
   2803 Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
   2804                         const int *attrib_list)
   2805 {
   2806    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
   2807    if (b)
   2808       XMesaBindTexImage(dpy, b, buffer, attrib_list);
   2809 }
   2810 
   2811 static void
   2812 Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
   2813 {
   2814    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
   2815    if (b)
   2816       XMesaReleaseTexImage(dpy, b, buffer);
   2817 }
   2818 
   2819 
   2820 static GLXContext
   2821 Fake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config,
   2822                              GLXContext share_context, Bool direct,
   2823                              const int *attrib_list)
   2824 {
   2825    XMesaContext xmCtx;
   2826    XMesaVisual xmvis = (XMesaVisual) config;
   2827    int i;
   2828    int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0;
   2829 
   2830    for (i = 0; attrib_list[i]; i += 2) {
   2831       switch (attrib_list[i]) {
   2832       case GLX_CONTEXT_MAJOR_VERSION_ARB:
   2833          major = attrib_list[i + 1];
   2834          break;
   2835       case GLX_CONTEXT_MINOR_VERSION_ARB:
   2836          minor = attrib_list[i + 1];
   2837          break;
   2838       case GLX_CONTEXT_FLAGS_ARB:
   2839          ctxFlags = attrib_list[i + 1];
   2840          break;
   2841       case GLX_CONTEXT_PROFILE_MASK_ARB:
   2842          profileFlags = attrib_list[i + 1];
   2843          break;
   2844       default:
   2845          fprintf(stderr, "Bad attribute in glXCreateContextAttribs()\n");
   2846          return 0;
   2847       }
   2848    }
   2849 
   2850    if (major * 10 + minor > 21) {
   2851       /* swrast only supports GL 2.1 and earlier */
   2852       return 0;
   2853    }
   2854 
   2855    /* These are ignored for now.  We'd have to enhance XMesaCreateContext
   2856     * to take these flags and the version, at least.
   2857     */
   2858    (void) ctxFlags;
   2859    (void) profileFlags;
   2860 
   2861    /* deallocate unused windows/buffers */
   2862    XMesaGarbageCollect(dpy);
   2863 
   2864    xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context);
   2865 
   2866    return (GLXContext) xmCtx;
   2867 }
   2868 
   2869 
   2870 /* silence warning */
   2871 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
   2872 
   2873 
   2874 /**
   2875  * Create a new GLX API dispatch table with its function pointers
   2876  * initialized to point to Mesa's "fake" GLX API functions.
   2877  * Note: there's a similar function (_real_GetGLXDispatchTable) that
   2878  * returns a new dispatch table with all pointers initalized to point
   2879  * to "real" GLX functions (which understand GLX wire protocol, etc).
   2880  */
   2881 struct _glxapi_table *
   2882 _mesa_GetGLXDispatchTable(void)
   2883 {
   2884    static struct _glxapi_table glx;
   2885 
   2886    /* be sure our dispatch table size <= libGL's table */
   2887    {
   2888       GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
   2889       (void) size;
   2890       assert(_glxapi_get_dispatch_table_size() >= size);
   2891    }
   2892 
   2893    /* initialize the whole table to no-ops */
   2894    _glxapi_set_no_op_table(&glx);
   2895 
   2896    /* now initialize the table with the functions I implement */
   2897    glx.ChooseVisual = Fake_glXChooseVisual;
   2898    glx.CopyContext = Fake_glXCopyContext;
   2899    glx.CreateContext = Fake_glXCreateContext;
   2900    glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
   2901    glx.DestroyContext = Fake_glXDestroyContext;
   2902    glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
   2903    glx.GetConfig = Fake_glXGetConfig;
   2904    glx.GetCurrentContext = Fake_glXGetCurrentContext;
   2905    /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
   2906    glx.IsDirect = Fake_glXIsDirect;
   2907    glx.MakeCurrent = Fake_glXMakeCurrent;
   2908    glx.QueryExtension = Fake_glXQueryExtension;
   2909    glx.QueryVersion = Fake_glXQueryVersion;
   2910    glx.SwapBuffers = Fake_glXSwapBuffers;
   2911    glx.UseXFont = Fake_glXUseXFont;
   2912    glx.WaitGL = Fake_glXWaitGL;
   2913    glx.WaitX = Fake_glXWaitX;
   2914 
   2915    /*** GLX_VERSION_1_1 ***/
   2916    glx.GetClientString = Fake_glXGetClientString;
   2917    glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
   2918    glx.QueryServerString = Fake_glXQueryServerString;
   2919 
   2920    /*** GLX_VERSION_1_2 ***/
   2921    /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
   2922 
   2923    /*** GLX_VERSION_1_3 ***/
   2924    glx.ChooseFBConfig = Fake_glXChooseFBConfig;
   2925    glx.CreateNewContext = Fake_glXCreateNewContext;
   2926    glx.CreatePbuffer = Fake_glXCreatePbuffer;
   2927    glx.CreatePixmap = Fake_glXCreatePixmap;
   2928    glx.CreateWindow = Fake_glXCreateWindow;
   2929    glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
   2930    glx.DestroyPixmap = Fake_glXDestroyPixmap;
   2931    glx.DestroyWindow = Fake_glXDestroyWindow;
   2932    /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
   2933    glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
   2934    glx.GetFBConfigs = Fake_glXGetFBConfigs;
   2935    glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
   2936    glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
   2937    glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
   2938    glx.QueryContext = Fake_glXQueryContext;
   2939    glx.QueryDrawable = Fake_glXQueryDrawable;
   2940    glx.SelectEvent = Fake_glXSelectEvent;
   2941 
   2942    /*** GLX_SGI_swap_control ***/
   2943    glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
   2944 
   2945    /*** GLX_SGI_video_sync ***/
   2946    glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
   2947    glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
   2948 
   2949    /*** GLX_SGI_make_current_read ***/
   2950    glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
   2951    /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/
   2952 
   2953 /*** GLX_SGIX_video_source ***/
   2954 #if defined(_VL_H)
   2955    glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
   2956    glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
   2957 #endif
   2958 
   2959    /*** GLX_EXT_import_context ***/
   2960    glx.FreeContextEXT = Fake_glXFreeContextEXT;
   2961    glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
   2962    /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
   2963    glx.ImportContextEXT = Fake_glXImportContextEXT;
   2964    glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
   2965 
   2966    /*** GLX_SGIX_fbconfig ***/
   2967    glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
   2968    glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
   2969    glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
   2970    glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
   2971    glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
   2972    glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
   2973 
   2974    /*** GLX_SGIX_pbuffer ***/
   2975    glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
   2976    glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
   2977    glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
   2978    glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
   2979    glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
   2980 
   2981    /*** GLX_SGI_cushion ***/
   2982    glx.CushionSGI = Fake_glXCushionSGI;
   2983 
   2984    /*** GLX_SGIX_video_resize ***/
   2985    glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
   2986    glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
   2987    glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
   2988    glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
   2989    glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
   2990 
   2991    /*** GLX_SGIX_dmbuffer **/
   2992 #if defined(_DM_BUFFER_H_)
   2993    glx.AssociateDMPbufferSGIX = NULL;
   2994 #endif
   2995 
   2996    /*** GLX_SGIX_swap_group ***/
   2997    glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
   2998 
   2999    /*** GLX_SGIX_swap_barrier ***/
   3000    glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
   3001    glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
   3002 
   3003    /*** GLX_SUN_get_transparent_index ***/
   3004    glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
   3005 
   3006    /*** GLX_MESA_copy_sub_buffer ***/
   3007    glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
   3008 
   3009    /*** GLX_MESA_release_buffers ***/
   3010    glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
   3011 
   3012    /*** GLX_MESA_pixmap_colormap ***/
   3013    glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
   3014 
   3015    /*** GLX_MESA_set_3dfx_mode ***/
   3016    glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;
   3017 
   3018    /*** GLX_NV_vertex_array_range ***/
   3019    glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV;
   3020    glx.FreeMemoryNV = Fake_glXFreeMemoryNV;
   3021 
   3022    /*** GLX_MESA_agp_offset ***/
   3023    glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA;
   3024 
   3025    /*** GLX_EXT_texture_from_pixmap ***/
   3026    glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
   3027    glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
   3028 
   3029    glx.CreateContextAttribs = Fake_glXCreateContextAttribs;
   3030    return &glx;
   3031 }
   3032