/*
 * Mesa 3-D graphics library
 *
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
 * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */


/*
 * This is an emulation of the GLX API which allows Mesa/GLX-based programs
 * to run on X servers which do not have the real GLX extension.
 *
 * Thanks to the contributors:
 *
 * Initial version:  Philip Brown (phil@bolthole.com)
 * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
 * Further visual-handling refinements: Wolfram Gloger
 *    (wmglo@Dent.MED.Uni-Muenchen.DE).
 *
 * Notes:
 *   Don't be fooled, stereo isn't supported yet.
 */


#include <string.h>
#include <stdio.h>
#include "glxheader.h"
#include "glxapi.h"
#include "main/context.h"
#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/mtypes.h"
#include "main/version.h"
#include "xfonts.h"
#include "xmesaP.h"

/* This indicates the client-side GLX API and GLX encoder version. */
#define CLIENT_MAJOR_VERSION 1
#define CLIENT_MINOR_VERSION 4  /* but don't have 1.3's pbuffers, etc yet */

/* This indicates the server-side GLX decoder version.
 * GLX 1.4 indicates OpenGL 1.3 support
 */
#define SERVER_MAJOR_VERSION 1
#define SERVER_MINOR_VERSION 4

/* This is appended onto the glXGetClient/ServerString version strings. */
#define MESA_GLX_VERSION "Mesa " PACKAGE_VERSION

/* Who implemented this GLX? */
#define VENDOR "Brian Paul"

#define EXTENSIONS \
   "GLX_MESA_set_3dfx_mode " \
   "GLX_MESA_copy_sub_buffer " \
   "GLX_MESA_pixmap_colormap " \
   "GLX_MESA_release_buffers " \
   "GLX_ARB_create_context " \
   "GLX_ARB_get_proc_address " \
   "GLX_EXT_texture_from_pixmap " \
   "GLX_EXT_visual_info " \
   "GLX_EXT_visual_rating " \
   /*"GLX_SGI_video_sync "*/ \
   "GLX_SGIX_fbconfig " \
   "GLX_SGIX_pbuffer "



/**********************************************************************/
/***                       GLX Visual Code                          ***/
/**********************************************************************/

#define DONT_CARE -1


static XMesaVisual *VisualTable = NULL;
static int NumVisuals = 0;


/*
 * This struct and some code fragments borrowed
 * from Mark Kilgard's GLUT library.
 */
typedef struct _OverlayInfo {
  /* Avoid 64-bit portability problems by being careful to use
     longs due to the way XGetWindowProperty is specified. Note
     that these parameters are passed as CARD32s over X
     protocol. */
  unsigned long overlay_visual;
  long transparent_type;
  long value;
  long layer;
} OverlayInfo;



/* Macro to handle c_class vs class field name in XVisualInfo struct */
#if defined(__cplusplus) || defined(c_plusplus)
#define CLASS c_class
#else
#define CLASS class
#endif



/*
 * Test if the given XVisualInfo is usable for Mesa rendering.
 */
static GLboolean
is_usable_visual( XVisualInfo *vinfo )
{
   switch (vinfo->CLASS) {
      case StaticGray:
      case GrayScale:
         /* Any StaticGray/GrayScale visual works in RGB or CI mode */
         return GL_TRUE;
      case StaticColor:
      case PseudoColor:
	 /* Color-index rendering is not supported. */
	 return GL_FALSE;
      case TrueColor:
      case DirectColor:
	 /* Any depth of TrueColor or DirectColor works in RGB mode */
	 return GL_TRUE;
      default:
	 /* This should never happen */
	 return GL_FALSE;
   }
}



/**
 * Get an array OverlayInfo records for specified screen.
 * \param dpy  the display
 * \param screen  screen number
 * \param numOverlays  returns numver of OverlayInfo records
 * \return  pointer to OverlayInfo array, free with XFree()
 */
static OverlayInfo *
GetOverlayInfo(Display *dpy, int screen, int *numOverlays)
{
   Atom overlayVisualsAtom;
   Atom actualType;
   Status status;
   unsigned char *ovInfo;
   unsigned long sizeData, bytesLeft;
   int actualFormat;

   /*
    * The SERVER_OVERLAY_VISUALS property on the root window contains
    * a list of overlay visuals.  Get that list now.
    */
   overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
   if (overlayVisualsAtom == None) {
      return 0;
   }

   status = XGetWindowProperty(dpy, RootWindow(dpy, screen),
                               overlayVisualsAtom, 0L, (long) 10000, False,
                               overlayVisualsAtom, &actualType, &actualFormat,
                               &sizeData, &bytesLeft,
                               &ovInfo);

   if (status != Success || actualType != overlayVisualsAtom ||
       actualFormat != 32 || sizeData < 4) {
      /* something went wrong */
      free((void *) ovInfo);
      *numOverlays = 0;
      return NULL;
   }

   *numOverlays = sizeData / 4;
   return (OverlayInfo *) ovInfo;
}



/**
 * Return the level (overlay, normal, underlay) of a given XVisualInfo.
 * Input:  dpy - the X display
 *         vinfo - the XVisualInfo to test
 * Return:  level of the visual:
 *             0 = normal planes
 *            >0 = overlay planes
 *            <0 = underlay planes
 */
static int
level_of_visual( Display *dpy, XVisualInfo *vinfo )
{
   OverlayInfo *overlay_info;
   int numOverlaysPerScreen, i;

   overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen);
   if (!overlay_info) {
      return 0;
   }

   /* search the overlay visual list for the visual ID of interest */
   for (i = 0; i < numOverlaysPerScreen; i++) {
      const OverlayInfo *ov = overlay_info + i;
      if (ov->overlay_visual == vinfo->visualid) {
         /* found the visual */
         if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
            int level = ov->layer;
            free((void *) overlay_info);
            return level;
         }
         else {
            free((void *) overlay_info);
            return 0;
         }
      }
   }

   /* The visual ID was not found in the overlay list. */
   free((void *) overlay_info);
   return 0;
}




/*
 * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
 * configuration in our list of GLX visuals.
 */
static XMesaVisual
save_glx_visual( Display *dpy, XVisualInfo *vinfo,
                 GLboolean alphaFlag, GLboolean dbFlag,
                 GLboolean stereoFlag,
                 GLint depth_size, GLint stencil_size,
                 GLint accumRedSize, GLint accumGreenSize,
                 GLint accumBlueSize, GLint accumAlphaSize,
                 GLint level, GLint numAuxBuffers )
{
   GLboolean ximageFlag = GL_TRUE;
   XMesaVisual xmvis;
   GLint i;

   if (dbFlag) {
      /* Check if the MESA_BACK_BUFFER env var is set */
      char *backbuffer = getenv("MESA_BACK_BUFFER");
      if (backbuffer) {
         if (backbuffer[0]=='p' || backbuffer[0]=='P') {
            ximageFlag = GL_FALSE;
         }
         else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
            ximageFlag = GL_TRUE;
         }
         else {
            _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage.");
         }
      }
   }

   if (stereoFlag) {
      /* stereo not supported */
      return NULL;
   }


   /* Force the visual to have an alpha channel */
   if (getenv("MESA_GLX_FORCE_ALPHA"))
      alphaFlag = GL_TRUE;

   /* First check if a matching visual is already in the list */
   for (i=0; i<NumVisuals; i++) {
      XMesaVisual v = VisualTable[i];
      if (v->display == dpy
          && v->mesa_visual.level == level
          && v->mesa_visual.numAuxBuffers == numAuxBuffers
          && v->ximage_flag == ximageFlag
          && v->mesa_visual.doubleBufferMode == dbFlag
          && v->mesa_visual.stereoMode == stereoFlag
          && (v->mesa_visual.alphaBits > 0) == alphaFlag
          && (v->mesa_visual.depthBits >= depth_size || depth_size == 0)
          && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0)
          && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0)
          && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0)
          && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0)
          && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) {
         /* now compare visual IDs */
         if (v->visinfo->visualid == vinfo->visualid) {
            return v;
         }
      }
   }

   /* Create a new visual and add it to the list. */

   xmvis = XMesaCreateVisual( dpy, vinfo, GL_TRUE, alphaFlag, dbFlag,
                              stereoFlag, ximageFlag,
                              depth_size, stencil_size,
                              accumRedSize, accumBlueSize,
                              accumBlueSize, accumAlphaSize, 0, level,
                              GLX_NONE_EXT );
   if (xmvis) {
      /* Allocate more space for additional visual */
      VisualTable = realloc(VisualTable, sizeof(XMesaVisual) * (NumVisuals + 1));
      /* add xmvis to the list */
      VisualTable[NumVisuals] = xmvis;
      NumVisuals++;
      /* XXX minor hack, because XMesaCreateVisual doesn't support an
       * aux buffers parameter.
       */
      xmvis->mesa_visual.numAuxBuffers = numAuxBuffers;
   }
   return xmvis;
}


/**
 * Return the default number of bits for the Z buffer.
 * If defined, use the MESA_GLX_DEPTH_BITS env var value.
 * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant.
 * XXX probably do the same thing for stencil, accum, etc.
 */
static GLint
default_depth_bits(void)
{
   int zBits;
   const char *zEnv = getenv("MESA_GLX_DEPTH_BITS");
   if (zEnv)
      zBits = atoi(zEnv);
   else
      zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
   return zBits;
}

static GLint
default_alpha_bits(void)
{
   int aBits;
   const char *aEnv = getenv("MESA_GLX_ALPHA_BITS");
   if (aEnv)
      aBits = atoi(aEnv);
   else
      aBits = 0;
   return aBits;
}

static GLint
default_accum_bits(void)
{
   return 16;
}



/*
 * Create a GLX visual from a regular XVisualInfo.
 * This is called when Fake GLX is given an XVisualInfo which wasn't
 * returned by glXChooseVisual.  Since this is the first time we're
 * considering this visual we'll take a guess at reasonable values
 * for depth buffer size, stencil size, accum size, etc.
 * This is the best we can do with a client-side emulation of GLX.
 */
static XMesaVisual
create_glx_visual( Display *dpy, XVisualInfo *visinfo )
{
   int vislevel;
   GLint zBits = default_depth_bits();
   GLint accBits = default_accum_bits();
   GLboolean alphaFlag = default_alpha_bits() > 0;

   vislevel = level_of_visual( dpy, visinfo );
   if (vislevel) {
      /* Color-index rendering to overlays is not supported. */
      return NULL;
   }
   else if (is_usable_visual( visinfo )) {
      /* Configure this visual as RGB, double-buffered, depth-buffered. */
      /* This is surely wrong for some people's needs but what else */
      /* can be done?  They should use glXChooseVisual(). */
      return save_glx_visual( dpy, visinfo,
			      alphaFlag, /* alpha */
			      GL_TRUE,   /* double */
			      GL_FALSE,  /* stereo */
			      zBits,
			      8,       /* stencil bits */
			      accBits, /* r */
			      accBits, /* g */
			      accBits, /* b */
			      accBits, /* a */
			      0,         /* level */
			      0          /* numAux */
			      );
   }
   else {
      _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n");
      return NULL;
   }
}



/*
 * Find the GLX visual associated with an XVisualInfo.
 */
static XMesaVisual
find_glx_visual( Display *dpy, XVisualInfo *vinfo )
{
   int i;

   /* try to match visual id */
   for (i=0;i<NumVisuals;i++) {
      if (VisualTable[i]->display==dpy
          && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
         return VisualTable[i];
      }
   }

   return NULL;
}



/**
 * Return the transparent pixel value for a GLX visual.
 * Input:  glxvis - the glx_visual
 * Return:  a pixel value or -1 if no transparent pixel
 */
static int
transparent_pixel( XMesaVisual glxvis )
{
   Display *dpy = glxvis->display;
   XVisualInfo *vinfo = glxvis->visinfo;
   OverlayInfo *overlay_info;
   int numOverlaysPerScreen, i;

   overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen);
   if (!overlay_info) {
      return -1;
   }

   for (i = 0; i < numOverlaysPerScreen; i++) {
      const OverlayInfo *ov = overlay_info + i;
      if (ov->overlay_visual == vinfo->visualid) {
         /* found it! */
         if (ov->transparent_type == 0) {
            /* type 0 indicates no transparency */
            free((void *) overlay_info);
            return -1;
         }
         else {
            /* ov->value is the transparent pixel */
            free((void *) overlay_info);
            return ov->value;
         }
      }
   }

   /* The visual ID was not found in the overlay list. */
   free((void *) overlay_info);
   return -1;
}



/**
 * Try to get an X visual which matches the given arguments.
 */
static XVisualInfo *
get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
{
   XVisualInfo temp, *vis;
   long mask;
   int n;
   unsigned int default_depth;
   int default_class;

   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
   temp.screen = scr;
   temp.depth = depth;
   temp.CLASS = xclass;

   default_depth = DefaultDepth(dpy,scr);
   default_class = DefaultVisual(dpy,scr)->CLASS;

   if (depth==default_depth && xclass==default_class) {
      /* try to get root window's visual */
      temp.visualid = DefaultVisual(dpy,scr)->visualid;
      mask |= VisualIDMask;
   }

   vis = XGetVisualInfo( dpy, mask, &temp, &n );

   /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
    * An SGI Infinite Reality system, for example, can have 30bpp pixels:
    * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
    */
   if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
      if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
          _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
          _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
         return vis;
      }
      else {
         free((void *) vis);
         return NULL;
      }
   }

   return vis;
}



/*
 * Retrieve the value of the given environment variable and find
 * the X visual which matches it.
 * Input:  dpy - the display
 *         screen - the screen number
 *         varname - the name of the environment variable
 * Return:  an XVisualInfo pointer to NULL if error.
 */
static XVisualInfo *
get_env_visual(Display *dpy, int scr, const char *varname)
{
   char value[100], type[100];
   int depth, xclass = -1;
   XVisualInfo *vis;

   if (!getenv( varname )) {
      return NULL;
   }

   strncpy( value, getenv(varname), 100 );
   value[99] = 0;

   sscanf( value, "%s %d", type, &depth );

   if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
   else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
   else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
   else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;

   if (xclass>-1 && depth>0) {
      vis = get_visual( dpy, scr, depth, xclass );
      if (vis) {
	 return vis;
      }
   }

   _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.",
                 type, depth);

   return NULL;
}



/*
 * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
 * Input:  dpy, screen - X display and screen number
 *         min_depth - minimum visual depth
 *         preferred_class - preferred GLX visual class or DONT_CARE
 * Return:  pointer to an XVisualInfo or NULL.
 */
static XVisualInfo *
choose_x_visual(Display *dpy, int screen, int min_depth, int preferred_class)
{
   XVisualInfo *vis;
   int xclass, visclass = 0;
   int depth;

   /* First see if the MESA_RGB_VISUAL env var is defined */
   vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
   if (vis) {
      return vis;
   }
   /* Otherwise, search for a suitable visual */
   if (preferred_class==DONT_CARE) {
      for (xclass=0;xclass<4;xclass++) {
	 switch (xclass) {
	 case 0:  visclass = TrueColor;    break;
	 case 1:  visclass = DirectColor;  break;
	 case 2:  visclass = GrayScale;    break;
	 case 3:  visclass = StaticGray;   break;
	 }
	 if (min_depth==0) {
	    /* start with shallowest */
	    for (depth=0;depth<=32;depth++) {
	       vis = get_visual( dpy, screen, depth, visclass );
	       if (vis) {
		  return vis;
	       }
	    }
	 }
	 else {
	    /* start with deepest */
	    for (depth=32;depth>=min_depth;depth--) {
	       vis = get_visual( dpy, screen, depth, visclass );
	       if (vis) {
		  return vis;
	       }
	    }
	 }
      }
   }
   else {
      /* search for a specific visual class */
      switch (preferred_class) {
      case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
      case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
      case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
      case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
      case GLX_PSEUDO_COLOR_EXT:
      case GLX_STATIC_COLOR_EXT:
      default:   return NULL;
      }
      if (min_depth==0) {
	 /* start with shallowest */
	 for (depth=0;depth<=32;depth++) {
	    vis = get_visual( dpy, screen, depth, visclass );
	    if (vis) {
	       return vis;
	    }
	 }
      }
      else {
	 /* start with deepest */
	 for (depth=32;depth>=min_depth;depth--) {
	    vis = get_visual( dpy, screen, depth, visclass );
	    if (vis) {
	       return vis;
	    }
	 }
      }
   }

   /* didn't find a visual */
   return NULL;
}



/*
 * Find the deepest X over/underlay visual of at least min_depth.
 * Input:  dpy, screen - X display and screen number
 *         level - the over/underlay level
 *         trans_type - transparent pixel type: GLX_NONE_EXT,
 *                      GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
 *                      or DONT_CARE
 *         trans_value - transparent pixel value or DONT_CARE
 *         min_depth - minimum visual depth
 *         preferred_class - preferred GLX visual class or DONT_CARE
 * Return:  pointer to an XVisualInfo or NULL.
 */
static XVisualInfo *
choose_x_overlay_visual( Display *dpy, int scr,
                         int level, int trans_type, int trans_value,
                         int min_depth, int preferred_class )
{
   OverlayInfo *overlay_info;
   int numOverlaysPerScreen;
   int i;
   XVisualInfo *deepvis;
   int deepest;

   /*DEBUG int tt, tv; */

   switch (preferred_class) {
      case GLX_TRUE_COLOR_EXT:    preferred_class = TrueColor;    break;
      case GLX_DIRECT_COLOR_EXT:  preferred_class = DirectColor;  break;
      case GLX_PSEUDO_COLOR_EXT:  preferred_class = PseudoColor;  break;
      case GLX_STATIC_COLOR_EXT:  preferred_class = StaticColor;  break;
      case GLX_GRAY_SCALE_EXT:    preferred_class = GrayScale;    break;
      case GLX_STATIC_GRAY_EXT:   preferred_class = StaticGray;   break;
      default:                    preferred_class = DONT_CARE;
   }

   overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen);
   if (!overlay_info) {
      return NULL;
   }

   /* Search for the deepest overlay which satisifies all criteria. */
   deepest = min_depth;
   deepvis = NULL;

   for (i = 0; i < numOverlaysPerScreen; i++) {
      const OverlayInfo *ov = overlay_info + i;
      XVisualInfo *vislist, vistemplate;
      int count;

      if (ov->layer!=level) {
         /* failed overlay level criteria */
         continue;
      }
      if (!(trans_type==DONT_CARE
            || (trans_type==GLX_TRANSPARENT_INDEX_EXT
                && ov->transparent_type>0)
            || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
         /* failed transparent pixel type criteria */
         continue;
      }
      if (trans_value!=DONT_CARE && trans_value!=ov->value) {
         /* failed transparent pixel value criteria */
         continue;
      }

      /* get XVisualInfo and check the depth */
      vistemplate.visualid = ov->overlay_visual;
      vistemplate.screen = scr;
      vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
                                &vistemplate, &count );

      if (!vislist) {
         /* no matches */
         continue;
      }

      if (count!=1) {
         /* something went wrong */
         free(vislist);
         continue;
      }
      if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
         /* wrong visual class */
         free(vislist);
         continue;
      }

      /* Color-index rendering is not supported.  Make sure we have True/DirectColor */
      if (vislist->CLASS != TrueColor && vislist->CLASS != DirectColor) {
         free(vislist);
         continue;
      }

      if (deepvis!=NULL && vislist->depth <= deepest) {
         free(vislist);
         continue;
      }

      /* YES!  found a satisfactory visual */
      free(deepvis);
      deepest = vislist->depth;
      deepvis = vislist;
      /* DEBUG  tt = ov->transparent_type;*/
      /* DEBUG  tv = ov->value; */
   }

/*DEBUG
   if (deepvis) {
      printf("chose 0x%x:  layer=%d depth=%d trans_type=%d trans_value=%d\n",
             deepvis->visualid, level, deepvis->depth, tt, tv );
   }
*/
   return deepvis;
}


/**********************************************************************/
/***             Display-related functions                          ***/
/**********************************************************************/


/**
 * Free all XMesaVisuals which are associated with the given display.
 */
static void
destroy_visuals_on_display(Display *dpy)
{
   int i;
   for (i = 0; i < NumVisuals; i++) {
      if (VisualTable[i]->display == dpy) {
         /* remove this visual */
         int j;
         XMesaDestroyVisual(VisualTable[i]);
         for (j = i; j < NumVisuals - 1; j++)
            VisualTable[j] = VisualTable[j + 1];
         NumVisuals--;
      }
   }
}


/**
 * Called from XCloseDisplay() to let us free our display-related data.
 */
static int
close_display_callback(Display *dpy, XExtCodes *codes)
{
   destroy_visuals_on_display(dpy);
   xmesa_destroy_buffers_on_display(dpy);
   return 0;
}


/**
 * Look for the named extension on given display and return a pointer
 * to the _XExtension data, or NULL if extension not found.
 */
static _XExtension *
lookup_extension(Display *dpy, const char *extName)
{
   _XExtension *ext;
   for (ext = dpy->ext_procs; ext; ext = ext->next) {
      if (ext->name && strcmp(ext->name, extName) == 0) {
         return ext;
      }
   }
   return NULL;
}


/**
 * Whenever we're given a new Display pointer, call this function to
 * register our close_display_callback function.
 */
static void
register_with_display(Display *dpy)
{
   const char *extName = "MesaGLX";
   _XExtension *ext;

   ext = lookup_extension(dpy, extName);
   if (!ext) {
      XExtCodes *c = XAddExtension(dpy);
      ext = dpy->ext_procs;  /* new extension is at head of list */
      assert(c->extension == ext->codes.extension);
      (void) c; /* silence warning */
      ext->name = strdup(extName);
      ext->close_display = close_display_callback;
   }
}


/**********************************************************************/
/***                  Begin Fake GLX API Functions                  ***/
/**********************************************************************/


/**
 * Helper used by glXChooseVisual and glXChooseFBConfig.
 * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for
 * the later.
 * In either case, the attribute list is terminated with the value 'None'.
 */
static XMesaVisual
choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
{
   const GLboolean rgbModeDefault = fbConfig;
   const int *parselist;
   XVisualInfo *vis;
   int min_ci = 0;
   int min_red=0, min_green=0, min_blue=0;
   GLboolean rgb_flag = rgbModeDefault;
   GLboolean alpha_flag = GL_FALSE;
   GLboolean double_flag = GL_FALSE;
   GLboolean stereo_flag = GL_FALSE;
   GLint depth_size = 0;
   GLint stencil_size = 0;
   GLint accumRedSize = 0;
   GLint accumGreenSize = 0;
   GLint accumBlueSize = 0;
   GLint accumAlphaSize = 0;
   int level = 0;
   int visual_type = DONT_CARE;
   int trans_type = DONT_CARE;
   int trans_value = DONT_CARE;
   GLint caveat = DONT_CARE;
   XMesaVisual xmvis = NULL;
   int desiredVisualID = -1;
   int numAux = 0;

   parselist = list;

   while (*parselist) {

      if (fbConfig &&
          parselist[1] == GLX_DONT_CARE &&
          parselist[0] != GLX_LEVEL) {
         /* For glXChooseFBConfig(), skip attributes whose value is
          * GLX_DONT_CARE (-1), unless it's GLX_LEVEL (which can legitimately be
          * a negative value).
          *
          * From page 17 (23 of the pdf) of the GLX 1.4 spec:
          * GLX DONT CARE may be specified for all attributes except GLX LEVEL.
          */
         parselist += 2;
         continue;
      }

      switch (*parselist) {
	 case GLX_USE_GL:
            if (fbConfig) {
               /* invalid token */
               return NULL;
            }
            else {
               /* skip */
               parselist++;
            }
	    break;
	 case GLX_BUFFER_SIZE:
	    parselist++;
	    min_ci = *parselist++;
	    break;
	 case GLX_LEVEL:
	    parselist++;
            level = *parselist++;
	    break;
	 case GLX_RGBA:
            if (fbConfig) {
               /* invalid token */
               return NULL;
            }
            else {
               rgb_flag = GL_TRUE;
               parselist++;
            }
	    break;
	 case GLX_DOUBLEBUFFER:
            parselist++;
            if (fbConfig) {
               double_flag = *parselist++;
            }
            else {
               double_flag = GL_TRUE;
            }
	    break;
	 case GLX_STEREO:
            parselist++;
            if (fbConfig) {
               stereo_flag = *parselist++;
            }
            else {
               stereo_flag = GL_TRUE;
            }
            break;
	 case GLX_AUX_BUFFERS:
	    parselist++;
            numAux = *parselist++;
            if (numAux > MAX_AUX_BUFFERS)
               return NULL;
	    break;
	 case GLX_RED_SIZE:
	    parselist++;
	    min_red = *parselist++;
	    break;
	 case GLX_GREEN_SIZE:
	    parselist++;
	    min_green = *parselist++;
	    break;
	 case GLX_BLUE_SIZE:
	    parselist++;
	    min_blue = *parselist++;
	    break;
	 case GLX_ALPHA_SIZE:
	    parselist++;
            {
               GLint size = *parselist++;
               alpha_flag = size ? GL_TRUE : GL_FALSE;
            }
	    break;
	 case GLX_DEPTH_SIZE:
	    parselist++;
	    depth_size = *parselist++;
	    break;
	 case GLX_STENCIL_SIZE:
	    parselist++;
	    stencil_size = *parselist++;
	    break;
	 case GLX_ACCUM_RED_SIZE:
	    parselist++;
            {
               GLint size = *parselist++;
               accumRedSize = MAX2( accumRedSize, size );
            }
            break;
	 case GLX_ACCUM_GREEN_SIZE:
	    parselist++;
            {
               GLint size = *parselist++;
               accumGreenSize = MAX2( accumGreenSize, size );
            }
            break;
	 case GLX_ACCUM_BLUE_SIZE:
	    parselist++;
            {
               GLint size = *parselist++;
               accumBlueSize = MAX2( accumBlueSize, size );
            }
            break;
	 case GLX_ACCUM_ALPHA_SIZE:
	    parselist++;
            {
               GLint size = *parselist++;
               accumAlphaSize = MAX2( accumAlphaSize, size );
            }
	    break;

         /*
          * GLX_EXT_visual_info extension
          */
         case GLX_X_VISUAL_TYPE_EXT:
            parselist++;
            visual_type = *parselist++;
            break;
         case GLX_TRANSPARENT_TYPE_EXT:
            parselist++;
            trans_type = *parselist++;
            break;
         case GLX_TRANSPARENT_INDEX_VALUE_EXT:
            parselist++;
            trans_value = *parselist++;
            break;
         case GLX_TRANSPARENT_RED_VALUE_EXT:
         case GLX_TRANSPARENT_GREEN_VALUE_EXT:
         case GLX_TRANSPARENT_BLUE_VALUE_EXT:
         case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
	    /* ignore */
	    parselist++;
	    parselist++;
	    break;

         /*
          * GLX_EXT_visual_info extension
          */
         case GLX_VISUAL_CAVEAT_EXT:
            parselist++;
            caveat = *parselist++; /* ignored for now */
            break;

         /*
          * GLX_ARB_multisample
          */
         case GLX_SAMPLE_BUFFERS_ARB:
         case GLX_SAMPLES_ARB:
	    parselist++;
	    if (*parselist++ != 0)
	       /* ms not supported */
	       return NULL;
	    break;

         /*
          * FBConfig attribs.
          */
         case GLX_RENDER_TYPE:
            if (!fbConfig)
               return NULL;
            parselist++;
            if (*parselist & GLX_RGBA_BIT) {
               rgb_flag = GL_TRUE;
            }
            else if (*parselist & GLX_COLOR_INDEX_BIT) {
               rgb_flag = GL_FALSE;
            }
            else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) {
               rgb_flag = GL_TRUE;
            }
            else if (*parselist == 0) {
               rgb_flag = GL_TRUE;
            }
            parselist++;
            break;
         case GLX_DRAWABLE_TYPE:
            if (!fbConfig)
               return NULL;
            parselist++;
            if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) {
               return NULL; /* bad bit */
            }
            parselist++;
            break;
         case GLX_FBCONFIG_ID:
         case GLX_VISUAL_ID:
            if (!fbConfig)
               return NULL;
            parselist++;
            desiredVisualID = *parselist++;
            break;
         case GLX_X_RENDERABLE:
         case GLX_MAX_PBUFFER_WIDTH:
         case GLX_MAX_PBUFFER_HEIGHT:
         case GLX_MAX_PBUFFER_PIXELS:
            if (!fbConfig)
               return NULL;
            parselist += 2;
            /* ignore */
            break;

#ifdef GLX_EXT_texture_from_pixmap
         case GLX_BIND_TO_TEXTURE_RGB_EXT:
            parselist++; /*skip*/
            break;
         case GLX_BIND_TO_TEXTURE_RGBA_EXT:
            parselist++; /*skip*/
            break;
         case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
            parselist++; /*skip*/
            break;
         case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
            parselist++;
            if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT |
                               GLX_TEXTURE_2D_BIT_EXT |
                               GLX_TEXTURE_RECTANGLE_BIT_EXT)) {
               /* invalid bit */
               return NULL;
            }
            break;
         case GLX_Y_INVERTED_EXT:
            parselist++; /*skip*/
            break;
#endif

	 case None:
            /* end of list */
	    break;

	 default:
	    /* undefined attribute */
            _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()",
                          *parselist);
	    return NULL;
      }
   }

   if (!rgb_flag)
      return NULL;

   (void) caveat;
   (void) min_ci;

   /*
    * Since we're only simulating the GLX extension this function will never
    * find any real GL visuals.  Instead, all we can do is try to find an RGB
    * or CI visual of appropriate depth.  Other requested attributes such as
    * double buffering, depth buffer, etc. will be associated with the X
    * visual and stored in the VisualTable[].
    */
   if (desiredVisualID != -1) {
      /* try to get a specific visual, by visualID */
      XVisualInfo temp;
      int n;
      temp.visualid = desiredVisualID;
      temp.screen = screen;
      vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n);
      if (vis) {
         /* give the visual some useful GLX attributes */
         double_flag = GL_TRUE;
         if (vis->depth <= 8)
	    return NULL;
         depth_size = default_depth_bits();
         stencil_size = 8;
         /* XXX accum??? */
      }
   }
   else {
      /* RGB visual */
      int min_rgb = min_red + min_green + min_blue;
      if (min_rgb>1 && min_rgb<8) {
	 /* a special case to be sure we can get a monochrome visual */
	 min_rgb = 1;
      }

      if (level==0) {
	 vis = choose_x_visual(dpy, screen, min_rgb, visual_type);
      }
      else {
	 vis = choose_x_overlay_visual(dpy, screen, level,
				       trans_type, trans_value, min_rgb, visual_type);
      }
   }

   if (vis) {
      /* Note: we're not exactly obeying the glXChooseVisual rules here.
       * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the
       * largest depth buffer size, which is 32bits/value.  Instead, we
       * return 16 to maintain performance with earlier versions of Mesa.
       */
      if (depth_size > 24)
         depth_size = 32;
      else if (depth_size > 16)
         depth_size = 24;
      else if (depth_size > 0) {
         depth_size = default_depth_bits();
      }

      if (!alpha_flag) {
         alpha_flag = default_alpha_bits() > 0;
      }

      /* we only support one size of stencil and accum buffers. */
      if (stencil_size > 0)
         stencil_size = 8;
      if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
          accumAlphaSize > 0) {
         accumRedSize = 
         accumGreenSize = 
         accumBlueSize = default_accum_bits();
         accumAlphaSize = alpha_flag ? accumRedSize : 0;
      }

      xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag,
                               stereo_flag, depth_size, stencil_size,
                               accumRedSize, accumGreenSize,
                               accumBlueSize, accumAlphaSize, level, numAux );
      free(vis);
   }

   return xmvis;
}


static XVisualInfo *
Fake_glXChooseVisual( Display *dpy, int screen, int *list )
{
   XMesaVisual xmvis;

   /* register ourselves as an extension on this display */
   register_with_display(dpy);

   xmvis = choose_visual(dpy, screen, list, GL_FALSE);
   if (xmvis) {
      XVisualInfo* visinfo = malloc(sizeof(XVisualInfo));
      if (visinfo) {
         memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo));
      }
      return visinfo;
   }
   else
      return NULL;
}


static GLXContext
Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
                       GLXContext share_list, Bool direct )
{
   XMesaVisual xmvis;
   XMesaContext xmesaCtx;

   if (!dpy || !visinfo)
      return 0;

   /* deallocate unused windows/buffers */
#if 0
   XMesaGarbageCollect(dpy);
#endif

   xmvis = find_glx_visual( dpy, visinfo );
   if (!xmvis) {
      /* This visual wasn't found with glXChooseVisual() */
      xmvis = create_glx_visual( dpy, visinfo );
      if (!xmvis) {
         return NULL;
      }
   }

   xmesaCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list);

   return (GLXContext) xmesaCtx;
}


/* XXX these may have to be removed due to thread-safety issues. */
static GLXContext MakeCurrent_PrevContext = 0;
static GLXDrawable MakeCurrent_PrevDrawable = 0;
static GLXDrawable MakeCurrent_PrevReadable = 0;
static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0;
static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;


/* GLX 1.3 and later */
static Bool
Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
                            GLXDrawable read, GLXContext ctx )
{
   if (ctx && draw && read) {
      XMesaBuffer drawBuffer, readBuffer;
      XMesaContext xmctx = (XMesaContext) ctx;

      /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */
      if (ctx == MakeCurrent_PrevContext
          && draw == MakeCurrent_PrevDrawable) {
         drawBuffer = MakeCurrent_PrevDrawBuffer;
      }
      else {
         drawBuffer = XMesaFindBuffer( dpy, draw );
      }
      if (!drawBuffer) {
         /* drawable must be a new window! */
         drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
         if (!drawBuffer) {
            /* Out of memory, or context/drawable depth mismatch */
            return False;
         }
      }

      /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
      if (ctx == MakeCurrent_PrevContext
          && read == MakeCurrent_PrevReadable) {
         readBuffer = MakeCurrent_PrevReadBuffer;
      }
      else {
         readBuffer = XMesaFindBuffer( dpy, read );
      }
      if (!readBuffer) {
         /* drawable must be a new window! */
         readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
         if (!readBuffer) {
            /* Out of memory, or context/drawable depth mismatch */
            return False;
         }
      }

      MakeCurrent_PrevContext = ctx;
      MakeCurrent_PrevDrawable = draw;
      MakeCurrent_PrevReadable = read;
      MakeCurrent_PrevDrawBuffer = drawBuffer;
      MakeCurrent_PrevReadBuffer = readBuffer;

      /* Now make current! */
      return XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer);
   }
   else if (!ctx && !draw && !read) {
      /* release current context w/out assigning new one. */
      XMesaMakeCurrent( NULL, NULL );
      MakeCurrent_PrevContext = 0;
      MakeCurrent_PrevDrawable = 0;
      MakeCurrent_PrevReadable = 0;
      MakeCurrent_PrevDrawBuffer = 0;
      MakeCurrent_PrevReadBuffer = 0;
      return True;
   }
   else {
      /* The args must either all be non-zero or all zero.
       * This is an error.
       */
      return False;
   }
}


static Bool
Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
{
   return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
}


static GLXPixmap
Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
{
   XMesaVisual v;
   XMesaBuffer b;

   v = find_glx_visual( dpy, visinfo );
   if (!v) {
      v = create_glx_visual( dpy, visinfo );
      if (!v) {
         /* unusable visual */
         return 0;
      }
   }

   b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
   if (!b) {
      return 0;
   }
   return b->frontxrb->pixmap;
}


/*** GLX_MESA_pixmap_colormap ***/

static GLXPixmap
Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
                             Pixmap pixmap, Colormap cmap )
{
   XMesaVisual v;
   XMesaBuffer b;

   v = find_glx_visual( dpy, visinfo );
   if (!v) {
      v = create_glx_visual( dpy, visinfo );
      if (!v) {
         /* unusable visual */
         return 0;
      }
   }

   b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
   if (!b) {
      return 0;
   }
   return b->frontxrb->pixmap;
}


static void
Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
{
   XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
   if (b) {
      XMesaDestroyBuffer(b);
   }
   else if (getenv("MESA_DEBUG")) {
      _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
   }
}


static void
Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
                     unsigned long mask )
{
   XMesaContext xmSrc = (XMesaContext) src;
   XMesaContext xmDst = (XMesaContext) dst;
   (void) dpy;
   if (MakeCurrent_PrevContext == src) {
      _mesa_Flush();
   }
   _mesa_copy_context( &xmSrc->mesa, &xmDst->mesa, (GLuint) mask );
}


static Bool
Fake_glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
{
   int op, ev, err;
   /* Mesa's GLX isn't really an X extension but we try to act like one. */
   if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &op, &ev, &err))
      ev = err = 0;
   if (errorBase)
      *errorBase = err;
   if (eventBase)
      *eventBase = ev;
   return True; /* we're faking GLX so always return success */
}


extern void _kw_ungrab_all( Display *dpy );
void _kw_ungrab_all( Display *dpy )
{
   XUngrabPointer( dpy, CurrentTime );
   XUngrabKeyboard( dpy, CurrentTime );
}


static void
Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
{
   if (ctx) {
      (void) dpy;
      MakeCurrent_PrevContext = 0;
      MakeCurrent_PrevDrawable = 0;
      MakeCurrent_PrevReadable = 0;
      MakeCurrent_PrevDrawBuffer = 0;
      MakeCurrent_PrevReadBuffer = 0;
      XMesaDestroyContext((XMesaContext) ctx);
      XMesaGarbageCollect(dpy);
   }
}


static Bool
Fake_glXIsDirect( Display *dpy, GLXContext ctx )
{
   XMesaContext xmCtx = (XMesaContext) ctx;
   return xmCtx ? xmCtx->direct : False;
}



static void
Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
{
   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );

   if (buffer) {
      XMesaSwapBuffers(buffer);
   }
   else if (getenv("MESA_DEBUG")) {
      _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
                    (int) drawable);
   }
}



/*** GLX_MESA_copy_sub_buffer ***/

static void
Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
                           int x, int y, int width, int height )
{
   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
   if (buffer) {
      XMesaCopySubBuffer(buffer, x, y, width, height);
   }
   else if (getenv("MESA_DEBUG")) {
      _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n");
   }
}


static Bool
Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
{
   (void) dpy;
   /* Return GLX version, not Mesa version */
   assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION);
   *maj = CLIENT_MAJOR_VERSION;
   *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION );
   return True;
}


/*
 * Query the GLX attributes of the given XVisualInfo.
 */
static int
get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
{
   assert(xmvis);
   switch(attrib) {
      case GLX_USE_GL:
         if (fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = (int) True;
	 return 0;
      case GLX_BUFFER_SIZE:
	 *value = xmvis->visinfo->depth;
	 return 0;
      case GLX_LEVEL:
	 *value = xmvis->mesa_visual.level;
	 return 0;
      case GLX_RGBA:
         if (fbconfig)
            return GLX_BAD_ATTRIBUTE;
	 if (xmvis->mesa_visual.rgbMode) {
	    *value = True;
	 }
	 else {
	    *value = False;
	 }
	 return 0;
      case GLX_DOUBLEBUFFER:
	 *value = (int) xmvis->mesa_visual.doubleBufferMode;
	 return 0;
      case GLX_STEREO:
	 *value = (int) xmvis->mesa_visual.stereoMode;
	 return 0;
      case GLX_AUX_BUFFERS:
	 *value = xmvis->mesa_visual.numAuxBuffers;
	 return 0;
      case GLX_RED_SIZE:
         *value = xmvis->mesa_visual.redBits;
	 return 0;
      case GLX_GREEN_SIZE:
         *value = xmvis->mesa_visual.greenBits;
	 return 0;
      case GLX_BLUE_SIZE:
         *value = xmvis->mesa_visual.blueBits;
	 return 0;
      case GLX_ALPHA_SIZE:
         *value = xmvis->mesa_visual.alphaBits;
	 return 0;
      case GLX_DEPTH_SIZE:
         *value = xmvis->mesa_visual.depthBits;
	 return 0;
      case GLX_STENCIL_SIZE:
	 *value = xmvis->mesa_visual.stencilBits;
	 return 0;
      case GLX_ACCUM_RED_SIZE:
	 *value = xmvis->mesa_visual.accumRedBits;
	 return 0;
      case GLX_ACCUM_GREEN_SIZE:
	 *value = xmvis->mesa_visual.accumGreenBits;
	 return 0;
      case GLX_ACCUM_BLUE_SIZE:
	 *value = xmvis->mesa_visual.accumBlueBits;
	 return 0;
      case GLX_ACCUM_ALPHA_SIZE:
         *value = xmvis->mesa_visual.accumAlphaBits;
	 return 0;

      /*
       * GLX_EXT_visual_info extension
       */
      case GLX_X_VISUAL_TYPE_EXT:
         switch (xmvis->visinfo->CLASS) {
            case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
            case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
            case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
            case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
            case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
            case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
         }
         return 0;
      case GLX_TRANSPARENT_TYPE_EXT:
         if (xmvis->mesa_visual.level==0) {
            /* normal planes */
            *value = GLX_NONE_EXT;
         }
         else if (xmvis->mesa_visual.level>0) {
            /* overlay */
            if (xmvis->mesa_visual.rgbMode) {
               *value = GLX_TRANSPARENT_RGB_EXT;
            }
            else {
               *value = GLX_TRANSPARENT_INDEX_EXT;
            }
         }
         else if (xmvis->mesa_visual.level<0) {
            /* underlay */
            *value = GLX_NONE_EXT;
         }
         return 0;
      case GLX_TRANSPARENT_INDEX_VALUE_EXT:
         {
            int pixel = transparent_pixel( xmvis );
            if (pixel>=0) {
               *value = pixel;
            }
            /* else undefined */
         }
         return 0;
      case GLX_TRANSPARENT_RED_VALUE_EXT:
         /* undefined */
         return 0;
      case GLX_TRANSPARENT_GREEN_VALUE_EXT:
         /* undefined */
         return 0;
      case GLX_TRANSPARENT_BLUE_VALUE_EXT:
         /* undefined */
         return 0;
      case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
         /* undefined */
         return 0;

      /*
       * GLX_EXT_visual_info extension
       */
      case GLX_VISUAL_CAVEAT_EXT:
         /* test for zero, just in case */
         if (xmvis->mesa_visual.visualRating > 0)
            *value = xmvis->mesa_visual.visualRating;
         else
            *value = GLX_NONE_EXT;
         return 0;

      /*
       * GLX_ARB_multisample
       */
      case GLX_SAMPLE_BUFFERS_ARB:
         *value = 0;
         return 0;
      case GLX_SAMPLES_ARB:
         *value = 0;
         return 0;

      /*
       * For FBConfigs:
       */
      case GLX_SCREEN_EXT:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = xmvis->visinfo->screen;
         break;
      case GLX_DRAWABLE_TYPE: /*SGIX too */
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
         break;
      case GLX_RENDER_TYPE_SGIX:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         if (xmvis->mesa_visual.floatMode)
            *value = GLX_RGBA_FLOAT_BIT_ARB;
         else if (xmvis->mesa_visual.rgbMode)
            *value = GLX_RGBA_BIT;
         else
            *value = GLX_COLOR_INDEX_BIT;
         break;
      case GLX_X_RENDERABLE_SGIX:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = True; /* XXX really? */
         break;
      case GLX_FBCONFIG_ID_SGIX:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = xmvis->visinfo->visualid;
         break;
      case GLX_MAX_PBUFFER_WIDTH:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         /* XXX should be same as ctx->Const.MaxRenderbufferSize */
         *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen);
         break;
      case GLX_MAX_PBUFFER_HEIGHT:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen);
         break;
      case GLX_MAX_PBUFFER_PIXELS:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) *
                  DisplayHeight(xmvis->display, xmvis->visinfo->screen);
         break;
      case GLX_VISUAL_ID:
         if (!fbconfig)
            return GLX_BAD_ATTRIBUTE;
         *value = xmvis->visinfo->visualid;
         break;

#ifdef GLX_EXT_texture_from_pixmap
      case GLX_BIND_TO_TEXTURE_RGB_EXT:
         *value = True; /*XXX*/
         break;
      case GLX_BIND_TO_TEXTURE_RGBA_EXT:
         /* XXX review */
         *value = xmvis->mesa_visual.alphaBits > 0 ? True : False;
         break;
      case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
         *value = True; /*XXX*/
         break;
      case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
         *value = (GLX_TEXTURE_1D_BIT_EXT |
                   GLX_TEXTURE_2D_BIT_EXT |
                   GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/
         break;
      case GLX_Y_INVERTED_EXT:
         *value = True; /*XXX*/
         break;
#endif

      default:
	 return GLX_BAD_ATTRIBUTE;
   }
   return Success;
}


static int
Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
                   int attrib, int *value )
{
   XMesaVisual xmvis;
   int k;
   if (!dpy || !visinfo)
      return GLX_BAD_ATTRIBUTE;

   xmvis = find_glx_visual( dpy, visinfo );
   if (!xmvis) {
      /* this visual wasn't obtained with glXChooseVisual */
      xmvis = create_glx_visual( dpy, visinfo );
      if (!xmvis) {
	 /* this visual can't be used for GL rendering */
	 if (attrib==GLX_USE_GL) {
	    *value = (int) False;
	    return 0;
	 }
	 else {
	    return GLX_BAD_VISUAL;
	 }
      }
   }

   k = get_config(xmvis, attrib, value, GL_FALSE);
   return k;
}


static GLXContext
Fake_glXGetCurrentContext(void)
{
   XMesaContext xmesa = XMesaGetCurrentContext();
   return (GLXContext) xmesa;
}

static void
Fake_glXWaitGL( void )
{
   XMesaContext xmesa = XMesaGetCurrentContext();
   XMesaFlush( xmesa );
}



static void
Fake_glXWaitX( void )
{
   XMesaContext xmesa = XMesaGetCurrentContext();
   XMesaFlush( xmesa );
}


static const char *
get_extensions( void )
{
   return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */
}



/* GLX 1.1 and later */
static const char *
Fake_glXQueryExtensionsString( Display *dpy, int screen )
{
   (void) dpy;
   (void) screen;
   return get_extensions();
}



/* GLX 1.1 and later */
static const char *
Fake_glXQueryServerString( Display *dpy, int screen, int name )
{
   static char version[1000];
   sprintf(version, "%d.%d %s",
	   SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);

   (void) dpy;
   (void) screen;

   switch (name) {
      case GLX_EXTENSIONS:
         return get_extensions();
      case GLX_VENDOR:
	 return VENDOR;
      case GLX_VERSION:
	 return version;
      default:
         return NULL;
   }
}



/* GLX 1.1 and later */
static const char *
Fake_glXGetClientString( Display *dpy, int name )
{
   static char version[1000];
   sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
	   CLIENT_MINOR_VERSION, MESA_GLX_VERSION);

   (void) dpy;

   switch (name) {
      case GLX_EXTENSIONS:
         return get_extensions();
      case GLX_VENDOR:
	 return VENDOR;
      case GLX_VERSION:
	 return version;
      default:
         return NULL;
   }
}



/*
 * GLX 1.3 and later
 */


static int
Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
                           int attribute, int *value )
{
   XMesaVisual v = (XMesaVisual) config;
   (void) dpy;
   (void) config;

   if (!dpy || !config || !value)
      return -1;

   return get_config(v, attribute, value, GL_TRUE);
}


static GLXFBConfig *
Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
{
   XVisualInfo *visuals, visTemplate;
   const long visMask = VisualScreenMask;
   int i;

   /* Get list of all X visuals */
   visTemplate.screen = screen;
   visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
   if (*nelements > 0) {
      XMesaVisual *results;
      results = malloc(*nelements * sizeof(XMesaVisual));
      if (!results) {
         *nelements = 0;
         return NULL;
      }
      for (i = 0; i < *nelements; i++) {
         results[i] = create_glx_visual(dpy, visuals + i);
      }
      free(visuals);
      return (GLXFBConfig *) results;
   }
   return NULL;
}


static GLXFBConfig *
Fake_glXChooseFBConfig( Display *dpy, int screen,
                        const int *attribList, int *nitems )
{
   XMesaVisual xmvis;

   /* register ourselves as an extension on this display */
   register_with_display(dpy);

   if (!attribList || !attribList[0]) {
      /* return list of all configs (per GLX_SGIX_fbconfig spec) */
      return Fake_glXGetFBConfigs(dpy, screen, nitems);
   }

   xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
   if (xmvis) {
      GLXFBConfig *config = malloc(sizeof(XMesaVisual));
      if (!config) {
         *nitems = 0;
         return NULL;
      }
      *nitems = 1;
      config[0] = (GLXFBConfig) xmvis;
      return (GLXFBConfig *) config;
   }
   else {
      *nitems = 0;
      return NULL;
   }
}


static XVisualInfo *
Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
{
   if (dpy && config) {
      XMesaVisual xmvis = (XMesaVisual) config;
      XVisualInfo* visinfo = malloc(sizeof(XVisualInfo));
      if (visinfo) {
         memcpy(visinfo, xmvis->visinfo, sizeof(XVisualInfo));
      }
      return visinfo;
   }
   else {
      return NULL;
   }
}


static GLXWindow
Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
                      const int *attribList )
{
   XMesaVisual xmvis = (XMesaVisual) config;
   XMesaBuffer xmbuf;
   if (!xmvis)
      return 0;

   xmbuf = XMesaCreateWindowBuffer(xmvis, win);
   if (!xmbuf)
      return 0;

   (void) dpy;
   (void) attribList;  /* Ignored in GLX 1.3 */

   return win;  /* A hack for now */
}


static void
Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
{
   XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window);
   if (b)
      XMesaDestroyBuffer(b);
   /* don't destroy X window */
}


/* XXX untested */
static GLXPixmap
Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
                      const int *attribList )
{
   XMesaVisual v = (XMesaVisual) config;
   XMesaBuffer b;
   const int *attr;
   int target = 0, format = 0, mipmap = 0;
   int value;

   if (!dpy || !config || !pixmap)
      return 0;

   for (attr = attribList; attr && *attr; attr++) {
      switch (*attr) {
      case GLX_TEXTURE_FORMAT_EXT:
         attr++;
         switch (*attr) {
         case GLX_TEXTURE_FORMAT_NONE_EXT:
         case GLX_TEXTURE_FORMAT_RGB_EXT:
         case GLX_TEXTURE_FORMAT_RGBA_EXT:
            format = *attr;
            break;
         default:
            /* error */
            return 0;
         }
         break;
      case GLX_TEXTURE_TARGET_EXT:
         attr++;
         switch (*attr) {
         case GLX_TEXTURE_1D_EXT:
         case GLX_TEXTURE_2D_EXT:
         case GLX_TEXTURE_RECTANGLE_EXT:
            target = *attr;
            break;
         default:
            /* error */
            return 0;
         }
         break;
      case GLX_MIPMAP_TEXTURE_EXT:
         attr++;
         if (*attr)
            mipmap = 1;
         break;
      default:
         /* error */
         return 0;
      }
   }

   if (format == GLX_TEXTURE_FORMAT_RGB_EXT) {
      if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT,
                     &value, GL_TRUE) != Success
          || !value) {
         return 0; /* error! */
      }
   }
   else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) {
      if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT,
                     &value, GL_TRUE) != Success
          || !value) {
         return 0; /* error! */
      }
   }
   if (mipmap) {
      if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
                     &value, GL_TRUE) != Success
          || !value) {
         return 0; /* error! */
      }
   }
   if (target == GLX_TEXTURE_1D_EXT) {
      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
                     &value, GL_TRUE) != Success
          || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) {
         return 0; /* error! */
      }
   }
   else if (target == GLX_TEXTURE_2D_EXT) {
      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
                     &value, GL_TRUE) != Success
          || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) {
         return 0; /* error! */
      }
   }
   if (target == GLX_TEXTURE_RECTANGLE_EXT) {
      if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT,
                     &value, GL_TRUE) != Success
          || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) {
         return 0; /* error! */
      }
   }

   if (format || target || mipmap) {
      /* texture from pixmap */
      b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap);
   }
   else {
      b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
   }
   if (!b) {
      return 0;
   }

   return pixmap;
}


static void
Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
{
   XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap);
   if (b)
      XMesaDestroyBuffer(b);
   /* don't destroy X pixmap */
}


static GLXPbuffer
Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
                       const int *attribList )
{
   XMesaVisual xmvis = (XMesaVisual) config;
   XMesaBuffer xmbuf;
   const int *attrib;
   int width = 0, height = 0;
   GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;

   (void) dpy;

   for (attrib = attribList; *attrib; attrib++) {
      switch (*attrib) {
         case GLX_PBUFFER_WIDTH:
            attrib++;
            width = *attrib;
            break;
         case GLX_PBUFFER_HEIGHT:
            attrib++;
            height = *attrib;
            break;
         case GLX_PRESERVED_CONTENTS:
            attrib++;
            preserveContents = *attrib;
            break;
         case GLX_LARGEST_PBUFFER:
            attrib++;
            useLargest = *attrib;
            break;
         default:
            return 0;
      }
   }

   if (width == 0 || height == 0)
      return 0;

   if (width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
      /* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
       * allocate the largest possible buffer.
       */
      if (useLargest) {
         width = SWRAST_MAX_WIDTH;
         height = SWRAST_MAX_HEIGHT;
      }
   }

   xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
   /* A GLXPbuffer handle must be an X Drawable because that's what
    * glXMakeCurrent takes.
    */
   if (xmbuf) {
      xmbuf->largestPbuffer = useLargest;
      xmbuf->preservedContents = preserveContents;
      return (GLXPbuffer) xmbuf->frontxrb->pixmap;
   }
   else {
      return 0;
   }
}


static void
Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
{
   XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
   if (b) {
      XMesaDestroyBuffer(b);
   }
}


static void
Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
                       unsigned int *value )
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
   if (!xmbuf)
      return;

   /* make sure buffer's dimensions are up to date */
   xmesa_check_and_update_buffer_size(NULL, xmbuf);

   switch (attribute) {
      case GLX_WIDTH:
         *value = xmbuf->mesa_buffer.Width;
         break;
      case GLX_HEIGHT:
         *value = xmbuf->mesa_buffer.Height;
         break;
      case GLX_PRESERVED_CONTENTS:
         *value = xmbuf->preservedContents;
         break;
      case GLX_LARGEST_PBUFFER:
         *value = xmbuf->largestPbuffer;
         break;
      case GLX_FBCONFIG_ID:
         *value = xmbuf->xm_visual->visinfo->visualid;
         return;
#ifdef GLX_EXT_texture_from_pixmap
      case GLX_TEXTURE_FORMAT_EXT:
         *value = xmbuf->TextureFormat;
         break;
      case GLX_TEXTURE_TARGET_EXT:
         *value = xmbuf->TextureTarget;
         break;
      case GLX_MIPMAP_TEXTURE_EXT:
         *value = xmbuf->TextureMipmap;
         break;
#endif

      default:
         return; /* raise BadValue error */
   }
}


static GLXContext
Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
                          int renderType, GLXContext shareList, Bool direct )
{
   XMesaContext xmCtx;
   XMesaVisual xmvis = (XMesaVisual) config;

   if (!dpy || !config ||
       (renderType != GLX_RGBA_TYPE &&
        renderType != GLX_COLOR_INDEX_TYPE &&
        renderType != GLX_RGBA_FLOAT_TYPE_ARB &&
        renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT))
      return 0;

   /* deallocate unused windows/buffers */
   XMesaGarbageCollect(dpy);

   xmCtx = XMesaCreateContext(xmvis, (XMesaContext) shareList);

   return (GLXContext) xmCtx;
}


static int
Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
{
   XMesaContext xmctx = (XMesaContext) ctx;
   (void) dpy;
   (void) ctx;

   switch (attribute) {
   case GLX_FBCONFIG_ID:
      *value = xmctx->xm_visual->visinfo->visualid;
      break;
   case GLX_RENDER_TYPE:
      *value = GLX_RGBA_TYPE;
      break;
   case GLX_SCREEN:
      *value = 0;
      return Success;
   default:
      return GLX_BAD_ATTRIBUTE;
   }
   return 0;
}


static void
Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   if (xmbuf)
      xmbuf->selectedEvents = mask;
}


static void
Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
                          unsigned long *mask )
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   if (xmbuf)
      *mask = xmbuf->selectedEvents;
   else
      *mask = 0;
}



/*** GLX_SGI_swap_control ***/

static int
Fake_glXSwapIntervalSGI(int interval)
{
   (void) interval;
   return 0;
}



/*** GLX_SGI_video_sync ***/

static unsigned int FrameCounter = 0;

static int
Fake_glXGetVideoSyncSGI(unsigned int *count)
{
   /* this is a bogus implementation */
   *count = FrameCounter++;
   return 0;
}

static int
Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
   if (divisor <= 0 || remainder < 0)
      return GLX_BAD_VALUE;
   /* this is a bogus implementation */
   FrameCounter++;
   while (FrameCounter % divisor != remainder)
      FrameCounter++;
   *count = FrameCounter;
   return 0;
}



/*** GLX_SGI_make_current_read ***/

static Bool
Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
{
   return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
}

/* not used
static GLXDrawable
Fake_glXGetCurrentReadDrawableSGI(void)
{
   return 0;
}
*/


/*** GLX_SGIX_video_source ***/
#if defined(_VL_H)

static GLXVideoSourceSGIX
Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
{
   (void) dpy;
   (void) screen;
   (void) server;
   (void) path;
   (void) nodeClass;
   (void) drainNode;
   return 0;
}

static void
Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
{
   (void) dpy;
   (void) src;
}

#endif


/*** GLX_EXT_import_context ***/

static void
Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
{
   (void) dpy;
   (void) context;
}

static GLXContextID
Fake_glXGetContextIDEXT(const GLXContext context)
{
   (void) context;
   return 0;
}

static GLXContext
Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
{
   (void) dpy;
   (void) contextID;
   return 0;
}

static int
Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
{
   (void) dpy;
   (void) context;
   (void) attribute;
   (void) value;
   return 0;
}



/*** GLX_SGIX_fbconfig ***/

static int
Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
   return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value);
}

static GLXFBConfigSGIX *
Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
   return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}


static GLXPixmap
Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
{
   XMesaVisual xmvis = (XMesaVisual) config;
   XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
   return xmbuf->frontxrb->pixmap; /* need to return an X ID */
}


static GLXContext
Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
{
   XMesaContext xmCtx;
   XMesaVisual xmvis = (XMesaVisual) config;

   /* deallocate unused windows/buffers */
   XMesaGarbageCollect(dpy);

   xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_list);

   return (GLXContext) xmCtx;
}


static XVisualInfo *
Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
{
   return Fake_glXGetVisualFromFBConfig(dpy, config);
}


static GLXFBConfigSGIX
Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
{
   XMesaVisual xmvis = find_glx_visual(dpy, vis);
   if (!xmvis) {
      /* This visual wasn't found with glXChooseVisual() */
      xmvis = create_glx_visual(dpy, vis);
   }

   return (GLXFBConfigSGIX) xmvis;
}



/*** GLX_SGIX_pbuffer ***/

static GLXPbufferSGIX
Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
                             unsigned int width, unsigned int height,
                             int *attribList)
{
   XMesaVisual xmvis = (XMesaVisual) config;
   XMesaBuffer xmbuf;
   const int *attrib;
   GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE;

   (void) dpy;

   for (attrib = attribList; attrib && *attrib; attrib++) {
      switch (*attrib) {
         case GLX_PRESERVED_CONTENTS_SGIX:
            attrib++;
            preserveContents = *attrib; /* ignored */
            break;
         case GLX_LARGEST_PBUFFER_SGIX:
            attrib++;
            useLargest = *attrib; /* ignored */
            break;
         default:
            return 0;
      }
   }

   /* not used at this time */
   (void) useLargest;
   (void) preserveContents;

   xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
   /* A GLXPbuffer handle must be an X Drawable because that's what
    * glXMakeCurrent takes.
    */
   return (GLXPbuffer) xmbuf->frontxrb->pixmap;
}


static void
Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
   if (xmbuf) {
      XMesaDestroyBuffer(xmbuf);
   }
}


static int
Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
{
   const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);

   if (!xmbuf) {
      /* Generate GLXBadPbufferSGIX for bad pbuffer */
      return 0;
   }

   switch (attribute) {
      case GLX_PRESERVED_CONTENTS_SGIX:
         *value = xmbuf->preservedContents;
         break;
      case GLX_LARGEST_PBUFFER_SGIX:
         *value = xmbuf->largestPbuffer;
         break;
      case GLX_WIDTH_SGIX:
         *value = xmbuf->mesa_buffer.Width;
         break;
      case GLX_HEIGHT_SGIX:
         *value = xmbuf->mesa_buffer.Height;
         break;
      case GLX_EVENT_MASK_SGIX:
         *value = 0;  /* XXX might be wrong */
         break;
      default:
         *value = 0;
   }
   return 0;
}


static void
Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   if (xmbuf) {
      /* Note: we'll never generate clobber events */
      xmbuf->selectedEvents = mask;
   }
}


static void
Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
{
   XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
   if (xmbuf) {
      *mask = xmbuf->selectedEvents;
   }
   else {
      *mask = 0;
   }
}



/*** GLX_SGI_cushion ***/

static void
Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
{
   (void) dpy;
   (void) win;
   (void) cushion;
}



/*** GLX_SGIX_video_resize ***/

static int
Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
{
   (void) dpy;
   (void) screen;
   (void) channel;
   (void) window;
   return 0;
}

static int
Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
{
   (void) dpy;
   (void) screen;
   (void) channel;
   (void) x;
   (void) y;
   (void) w;
   (void) h;
   return 0;
}

static int
Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
{
   (void) dpy;
   (void) screen;
   (void) channel;
   (void) x;
   (void) y;
   (void) w;
   (void) h;
   return 0;
}

static int
Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
{
   (void) dpy;
   (void) screen;
   (void) channel;
   (void) dx;
   (void) dy;
   (void) dw;
   (void) dh;
   return 0;
}

static int
Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
{
   (void) dpy;
   (void) screen;
   (void) channel;
   (void) synctype;
   return 0;
}



/*** GLX_SGIX_dmbuffer **/

#if defined(_DM_BUFFER_H_)
static Bool
Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
{
   (void) dpy;
   (void) pbuffer;
   (void) params;
   (void) dmbuffer;
   return False;
}
#endif


/*** GLX_SGIX_swap_group ***/

static void
Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
{
   (void) dpy;
   (void) drawable;
   (void) member;
}



/*** GLX_SGIX_swap_barrier ***/

static void
Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
{
   (void) dpy;
   (void) drawable;
   (void) barrier;
}

static Bool
Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
{
   (void) dpy;
   (void) screen;
   (void) max;
   return False;
}



/*** GLX_SUN_get_transparent_index ***/

static Status
Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
{
   (void) dpy;
   (void) overlay;
   (void) underlay;
   (void) pTransparent;
   return 0;
}



/*** GLX_MESA_release_buffers ***/

/*
 * Release the depth, stencil, accum buffers attached to a GLXDrawable
 * (a window or pixmap) prior to destroying the GLXDrawable.
 */
static Bool
Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
{
   XMesaBuffer b = XMesaFindBuffer(dpy, d);
   if (b) {
      XMesaDestroyBuffer(b);
      return True;
   }
   return False;
}



/*** GLX_MESA_set_3dfx_mode ***/

static Bool
Fake_glXSet3DfxModeMESA( int mode )
{
   return XMesaSetFXmode( mode );
}



/*** GLX_NV_vertex_array range ***/
static void *
Fake_glXAllocateMemoryNV( GLsizei size,
                          GLfloat readFrequency,
                          GLfloat writeFrequency,
                          GLfloat priority )
{
   (void) size;
   (void) readFrequency;
   (void) writeFrequency;
   (void) priority;
   return NULL;
}


static void 
Fake_glXFreeMemoryNV( GLvoid *pointer )
{
   (void) pointer;
}


/*** GLX_MESA_agp_offset ***/

static GLuint
Fake_glXGetAGPOffsetMESA( const GLvoid *pointer )
{
   (void) pointer;
   return ~0;
}


/*** GLX_EXT_texture_from_pixmap ***/

static void
Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
                        const int *attrib_list)
{
   XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
   if (b)
      XMesaBindTexImage(dpy, b, buffer, attrib_list);
}

static void
Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
{
   XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
   if (b)
      XMesaReleaseTexImage(dpy, b, buffer);
}


static GLXContext
Fake_glXCreateContextAttribs(Display *dpy, GLXFBConfig config,
                             GLXContext share_context, Bool direct,
                             const int *attrib_list)
{
   XMesaContext xmCtx;
   XMesaVisual xmvis = (XMesaVisual) config;
   int i;
   int major = 0, minor = 0, ctxFlags = 0, profileFlags = 0;

   for (i = 0; attrib_list[i]; i += 2) {
      switch (attrib_list[i]) {
      case GLX_CONTEXT_MAJOR_VERSION_ARB:
         major = attrib_list[i + 1];
         break;
      case GLX_CONTEXT_MINOR_VERSION_ARB:
         minor = attrib_list[i + 1];
         break;
      case GLX_CONTEXT_FLAGS_ARB:
         ctxFlags = attrib_list[i + 1];
         break;
      case GLX_CONTEXT_PROFILE_MASK_ARB:
         profileFlags = attrib_list[i + 1];
         break;
      default:
         fprintf(stderr, "Bad attribute in glXCreateContextAttribs()\n");
         return 0;
      }
   }

   if (major * 10 + minor > 21) {
      /* swrast only supports GL 2.1 and earlier */
      return 0;
   }

   /* These are ignored for now.  We'd have to enhance XMesaCreateContext
    * to take these flags and the version, at least.
    */
   (void) ctxFlags;
   (void) profileFlags;

   /* deallocate unused windows/buffers */
   XMesaGarbageCollect(dpy);

   xmCtx = XMesaCreateContext(xmvis, (XMesaContext) share_context);

   return (GLXContext) xmCtx;
}


/* silence warning */
extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);


/**
 * Create a new GLX API dispatch table with its function pointers
 * initialized to point to Mesa's "fake" GLX API functions.
 * Note: there's a similar function (_real_GetGLXDispatchTable) that
 * returns a new dispatch table with all pointers initalized to point
 * to "real" GLX functions (which understand GLX wire protocol, etc).
 */
struct _glxapi_table *
_mesa_GetGLXDispatchTable(void)
{
   static struct _glxapi_table glx;

   /* be sure our dispatch table size <= libGL's table */
   {
      GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
      (void) size;
      assert(_glxapi_get_dispatch_table_size() >= size);
   }

   /* initialize the whole table to no-ops */
   _glxapi_set_no_op_table(&glx);

   /* now initialize the table with the functions I implement */
   glx.ChooseVisual = Fake_glXChooseVisual;
   glx.CopyContext = Fake_glXCopyContext;
   glx.CreateContext = Fake_glXCreateContext;
   glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
   glx.DestroyContext = Fake_glXDestroyContext;
   glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
   glx.GetConfig = Fake_glXGetConfig;
   glx.GetCurrentContext = Fake_glXGetCurrentContext;
   /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
   glx.IsDirect = Fake_glXIsDirect;
   glx.MakeCurrent = Fake_glXMakeCurrent;
   glx.QueryExtension = Fake_glXQueryExtension;
   glx.QueryVersion = Fake_glXQueryVersion;
   glx.SwapBuffers = Fake_glXSwapBuffers;
   glx.UseXFont = Fake_glXUseXFont;
   glx.WaitGL = Fake_glXWaitGL;
   glx.WaitX = Fake_glXWaitX;

   /*** GLX_VERSION_1_1 ***/
   glx.GetClientString = Fake_glXGetClientString;
   glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
   glx.QueryServerString = Fake_glXQueryServerString;

   /*** GLX_VERSION_1_2 ***/
   /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/

   /*** GLX_VERSION_1_3 ***/
   glx.ChooseFBConfig = Fake_glXChooseFBConfig;
   glx.CreateNewContext = Fake_glXCreateNewContext;
   glx.CreatePbuffer = Fake_glXCreatePbuffer;
   glx.CreatePixmap = Fake_glXCreatePixmap;
   glx.CreateWindow = Fake_glXCreateWindow;
   glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
   glx.DestroyPixmap = Fake_glXDestroyPixmap;
   glx.DestroyWindow = Fake_glXDestroyWindow;
   /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
   glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
   glx.GetFBConfigs = Fake_glXGetFBConfigs;
   glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
   glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
   glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
   glx.QueryContext = Fake_glXQueryContext;
   glx.QueryDrawable = Fake_glXQueryDrawable;
   glx.SelectEvent = Fake_glXSelectEvent;

   /*** GLX_SGI_swap_control ***/
   glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;

   /*** GLX_SGI_video_sync ***/
   glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
   glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;

   /*** GLX_SGI_make_current_read ***/
   glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
   /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/

/*** GLX_SGIX_video_source ***/
#if defined(_VL_H)
   glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
   glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
#endif

   /*** GLX_EXT_import_context ***/
   glx.FreeContextEXT = Fake_glXFreeContextEXT;
   glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
   /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
   glx.ImportContextEXT = Fake_glXImportContextEXT;
   glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;

   /*** GLX_SGIX_fbconfig ***/
   glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
   glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
   glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
   glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
   glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
   glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;

   /*** GLX_SGIX_pbuffer ***/
   glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
   glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
   glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
   glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
   glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;

   /*** GLX_SGI_cushion ***/
   glx.CushionSGI = Fake_glXCushionSGI;

   /*** GLX_SGIX_video_resize ***/
   glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
   glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
   glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
   glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
   glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;

   /*** GLX_SGIX_dmbuffer **/
#if defined(_DM_BUFFER_H_)
   glx.AssociateDMPbufferSGIX = NULL;
#endif

   /*** GLX_SGIX_swap_group ***/
   glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;

   /*** GLX_SGIX_swap_barrier ***/
   glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
   glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;

   /*** GLX_SUN_get_transparent_index ***/
   glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;

   /*** GLX_MESA_copy_sub_buffer ***/
   glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;

   /*** GLX_MESA_release_buffers ***/
   glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;

   /*** GLX_MESA_pixmap_colormap ***/
   glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;

   /*** GLX_MESA_set_3dfx_mode ***/
   glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA;

   /*** GLX_NV_vertex_array_range ***/
   glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV;
   glx.FreeMemoryNV = Fake_glXFreeMemoryNV;

   /*** GLX_MESA_agp_offset ***/
   glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA;

   /*** GLX_EXT_texture_from_pixmap ***/
   glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
   glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;

   glx.CreateContextAttribs = Fake_glXCreateContextAttribs;
   return &glx;
}
