Merge branch 'lp-offset-twoside'
[mesa.git] / src / mesa / drivers / x11 / fakeglx.c
index 82830b4717278b06844abd9ef0a95d132311515e..577e27d4da3fc8f808a440dd73724e84e4ce80a7 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  7.5
  *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ * 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"),
 
 #include "glxheader.h"
 #include "glxapi.h"
-#include "GL/xmesa.h"
-#include "context.h"
-#include "config.h"
-#include "macros.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "version.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"
 
+#ifdef __VMS
+#define sprintf sprintf
+#endif
 
 /* This indicates the client-side GLX API and GLX encoder version. */
 #define CLIENT_MAJOR_VERSION 1
    "GLX_MESA_pixmap_colormap " \
    "GLX_MESA_release_buffers " \
    "GLX_ARB_get_proc_address " \
+   "GLX_EXT_texture_from_pixmap " \
    "GLX_EXT_visual_info " \
    "GLX_EXT_visual_rating " \
-   "GLX_SGI_video_sync " \
+   /*"GLX_SGI_video_sync "*/ \
    "GLX_SGIX_fbconfig " \
    "GLX_SGIX_pbuffer "
 
@@ -105,8 +109,7 @@ struct fake_glx_context {
 #define DONT_CARE -1
 
 
-#define MAX_VISUALS 100
-static XMesaVisual VisualTable[MAX_VISUALS];
+static XMesaVisual *VisualTable = NULL;
 static int NumVisuals = 0;
 
 
@@ -149,13 +152,8 @@ is_usable_visual( XVisualInfo *vinfo )
          return GL_TRUE;
       case StaticColor:
       case PseudoColor:
-        /* Any StaticColor/PseudoColor visual of at least 4 bits */
-        if (vinfo->depth>=4) {
-           return GL_TRUE;
-        }
-        else {
-           return GL_FALSE;
-        }
+        /* Color-index rendering is not supported. */
+        return GL_FALSE;
       case TrueColor:
       case DirectColor:
         /* Any depth of TrueColor or DirectColor works in RGB mode */
@@ -265,7 +263,7 @@ level_of_visual( Display *dpy, XVisualInfo *vinfo )
  */
 static XMesaVisual
 save_glx_visual( Display *dpy, XVisualInfo *vinfo,
-                 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
+                 GLboolean alphaFlag, GLboolean dbFlag,
                  GLboolean stereoFlag,
                  GLint depth_size, GLint stencil_size,
                  GLint accumRedSize, GLint accumGreenSize,
@@ -293,6 +291,11 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
       }
    }
 
+   if (stereoFlag) {
+      /* stereo not supported */
+      return NULL;
+   }
+
    /* Comparing IDs uses less memory but sometimes fails. */
    /* XXX revisit this after 3.0 is finished. */
    if (_mesa_getenv("MESA_GLX_VISUAL_HACK"))
@@ -301,7 +304,7 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
       comparePointers = GL_FALSE;
 
    /* Force the visual to have an alpha channel */
-   if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA"))
+   if (_mesa_getenv("MESA_GLX_FORCE_ALPHA"))
       alphaFlag = GL_TRUE;
 
    /* First check if a matching visual is already in the list */
@@ -311,7 +314,6 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
           && v->mesa_visual.level == level
           && v->mesa_visual.numAuxBuffers == numAuxBuffers
           && v->ximage_flag == ximageFlag
-          && v->mesa_visual.rgbMode == rgbFlag
           && v->mesa_visual.doubleBufferMode == dbFlag
           && v->mesa_visual.stereoMode == stereoFlag
           && (v->mesa_visual.alphaBits > 0) == alphaFlag
@@ -331,12 +333,7 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
 
    /* Create a new visual and add it to the list. */
 
-   if (NumVisuals >= MAX_VISUALS) {
-      _mesa_problem(NULL, "GLX Error: maximum number of visuals exceeded");
-      return NULL;
-   }
-
-   xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
+   xmvis = XMesaCreateVisual( dpy, vinfo, GL_TRUE, alphaFlag, dbFlag,
                               stereoFlag, ximageFlag,
                               depth_size, stencil_size,
                               accumRedSize, accumBlueSize,
@@ -347,6 +344,10 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo,
        * if we need to search for it in find_glx_visual().
        */
       xmvis->vishandle = vinfo;
+      /* Allocate more space for additional visual */
+      VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, 
+                                   sizeof(XMesaVisual) * NumVisuals, 
+                                   sizeof(XMesaVisual) * (NumVisuals + 1));
       /* add xmvis to the list */
       VisualTable[NumVisuals] = xmvis;
       NumVisuals++;
@@ -371,12 +372,30 @@ default_depth_bits(void)
    int zBits;
    const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
    if (zEnv)
-      zBits = _mesa_atoi(zEnv);
+      zBits = atoi(zEnv);
    else
       zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
    return zBits;
 }
 
+static GLint
+default_alpha_bits(void)
+{
+   int aBits;
+   const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
+   if (aEnv)
+      aBits = atoi(aEnv);
+   else
+      aBits = 0;
+   return aBits;
+}
+
+static GLint
+default_accum_bits(void)
+{
+   return 16;
+}
+
 
 
 /*
@@ -392,59 +411,31 @@ 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) {
-      /* Configure this visual as a CI, single-buffered overlay */
-      return save_glx_visual( dpy, visinfo,
-                              GL_FALSE,  /* rgb */
-                              GL_FALSE,  /* alpha */
-                              GL_FALSE,  /* double */
-                              GL_FALSE,  /* stereo */
-                              0,         /* depth bits */
-                              0,         /* stencil bits */
-                              0,0,0,0,   /* accum bits */
-                              vislevel,  /* level */
-                              0          /* numAux */
-                            );
+      /* Color-index rendering to overlays is not supported. */
+      return NULL;
    }
    else if (is_usable_visual( visinfo )) {
-      if (_mesa_getenv("MESA_GLX_FORCE_CI")) {
-         /* Configure this visual as a COLOR INDEX visual. */
-         return save_glx_visual( dpy, visinfo,
-                                 GL_FALSE,   /* rgb */
-                                 GL_FALSE,  /* alpha */
-                                 GL_TRUE,   /* double */
-                                 GL_FALSE,  /* stereo */
-                                 zBits,
-                                 8 * sizeof(GLstencil),
-                                 0 * sizeof(GLaccum), /* r */
-                                 0 * sizeof(GLaccum), /* g */
-                                 0 * sizeof(GLaccum), /* b */
-                                 0 * sizeof(GLaccum), /* a */
-                                 0,         /* level */
-                                 0          /* numAux */
-                               );
-      }
-      else {
-         /* 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,
-                                 GL_TRUE,   /* rgb */
-                                 GL_FALSE,  /* alpha */
-                                 GL_TRUE,   /* double */
-                                 GL_FALSE,  /* stereo */
-                                 zBits,
-                                 8 * sizeof(GLstencil),
-                                 8 * sizeof(GLaccum), /* r */
-                                 8 * sizeof(GLaccum), /* g */
-                                 8 * sizeof(GLaccum), /* b */
-                                 8 * sizeof(GLaccum), /* a */
-                                 0,         /* level */
-                                 0          /* numAux */
-                               );
-      }
+      /* 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,
+                             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");
@@ -592,17 +583,15 @@ get_env_visual(Display *dpy, int scr, const char *varname)
       return NULL;
    }
 
-   _mesa_strncpy( value, _mesa_getenv(varname), 100 );
+   strncpy( value, _mesa_getenv(varname), 100 );
    value[99] = 0;
 
    sscanf( value, "%s %d", type, &depth );
 
-   if (_mesa_strcmp(type,"TrueColor")==0)          xclass = TrueColor;
-   else if (_mesa_strcmp(type,"DirectColor")==0)   xclass = DirectColor;
-   else if (_mesa_strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
-   else if (_mesa_strcmp(type,"StaticColor")==0)   xclass = StaticColor;
-   else if (_mesa_strcmp(type,"GrayScale")==0)     xclass = GrayScale;
-   else if (_mesa_strcmp(type,"StaticGray")==0)    xclass = StaticGray;
+   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 );
@@ -622,160 +611,79 @@ get_env_visual(Display *dpy, int scr, const char *varname)
 /*
  * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
  * Input:  dpy, screen - X display and screen number
- *         rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
  *         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, GLboolean rgba, int min_depth,
-                 int preferred_class )
+choose_x_visual(Display *dpy, int screen, int min_depth, int preferred_class)
 {
    XVisualInfo *vis;
    int xclass, visclass = 0;
    int depth;
 
-   if (rgba) {
-      Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
-      /* 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<6;xclass++) {
-            switch (xclass) {
-               case 0:  visclass = TrueColor;    break;
-               case 1:  visclass = DirectColor;  break;
-               case 2:  visclass = PseudoColor;  break;
-               case 3:  visclass = StaticColor;  break;
-               case 4:  visclass = GrayScale;    break;
-               case 5:  visclass = StaticGray;   break;
-            }
-            if (min_depth==0) {
-               /* start with shallowest */
-               for (depth=0;depth<=32;depth++) {
-                  if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
-                     /* Special case:  try to get 8-bit PseudoColor before */
-                     /* 8-bit TrueColor */
-                     vis = get_visual( dpy, screen, 8, PseudoColor );
-                     if (vis) {
-                        return vis;
-                     }
-                  }
-                  vis = get_visual( dpy, screen, depth, visclass );
-                  if (vis) {
-                     return vis;
-                  }
-               }
-            }
-            else {
-               /* start with deepest */
-               for (depth=32;depth>=min_depth;depth--) {
-                  if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
-                     /* Special case:  try to get 8-bit PseudoColor before */
-                     /* 8-bit TrueColor */
-                     vis = get_visual( dpy, screen, 8, PseudoColor );
-                     if (vis) {
-                        return vis;
-                     }
-                  }
-                  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_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
-            case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
-            case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
-            case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
-            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;
-               }
-            }
-         }
+   /* 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 {
-      /* First see if the MESA_CI_VISUAL env var is defined */
-      vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
-      if (vis) {
-        return vis;
+      /* 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;
       }
-      /* Otherwise, search for a suitable visual, starting with shallowest */
-      if (preferred_class==DONT_CARE) {
-         for (xclass=0;xclass<4;xclass++) {
-            switch (xclass) {
-               case 0:  visclass = PseudoColor;  break;
-               case 1:  visclass = StaticColor;  break;
-               case 2:  visclass = GrayScale;    break;
-               case 3:  visclass = StaticGray;   break;
-            }
-            /* try 8-bit up through 16-bit */
-            for (depth=8;depth<=16;depth++) {
-               vis = get_visual( dpy, screen, depth, visclass );
-               if (vis) {
-                  return vis;
-               }
-            }
-            /* try min_depth up to 8-bit */
-            for (depth=min_depth;depth<8;depth++) {
-               vis = get_visual( dpy, screen, depth, visclass );
-               if (vis) {
-                  return vis;
-               }
-            }
-         }
+      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 {
-         /* 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_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
-            case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
-            case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
-            case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
-            default:   return NULL;
-         }
-         /* try 8-bit up through 16-bit */
-         for (depth=8;depth<=16;depth++) {
-            vis = get_visual( dpy, screen, depth, visclass );
-            if (vis) {
-               return vis;
-            }
-         }
-         /* try min_depth up to 8-bit */
-         for (depth=min_depth;depth<8;depth++) {
-            vis = get_visual( dpy, screen, depth, visclass );
-            if (vis) {
-               return vis;
-            }
-         }
+        /* start with deepest */
+        for (depth=32;depth>=min_depth;depth--) {
+           vis = get_visual( dpy, screen, depth, visclass );
+           if (vis) {
+              return vis;
+           }
+        }
       }
    }
 
@@ -798,7 +706,7 @@ choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth,
  * Return:  pointer to an XVisualInfo or NULL.
  */
 static XVisualInfo *
-choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag,
+choose_x_overlay_visual( Display *dpy, int scr,
                          int level, int trans_type, int trans_value,
                          int min_depth, int preferred_class )
 {
@@ -865,14 +773,8 @@ choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag,
          continue;
       }
 
-      /* if RGB was requested, make sure we have True/DirectColor */
-      if (rgbFlag && vislist->CLASS != TrueColor
-          && vislist->CLASS != DirectColor)
-         continue;
-
-      /* if CI was requested, make sure we have a color indexed visual */
-      if (!rgbFlag
-          && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor))
+      /* Color-index rendering is not supported.  Make sure we have True/DirectColor */
+      if (vislist->CLASS != TrueColor && vislist->CLASS != DirectColor)
          continue;
 
       if (deepvis==NULL || vislist->depth > deepest) {
@@ -897,11 +799,93 @@ choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag,
 }
 
 
+/**********************************************************************/
+/***             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;
+         free(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 = _mesa_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 )
 {
@@ -979,7 +963,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             else {
                stereo_flag = GL_TRUE;
             }
-            return NULL; /* stereo not supported */
+            break;
         case GLX_AUX_BUFFERS:
            parselist++;
             numAux = *parselist++;
@@ -1002,7 +986,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
            parselist++;
             {
                GLint size = *parselist++;
-               alpha_flag = size>0 ? 1 : 0;
+               alpha_flag = size ? GL_TRUE : GL_FALSE;
             }
            break;
         case GLX_DEPTH_SIZE:
@@ -1078,21 +1062,24 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
           * GLX_ARB_multisample
           */
          case GLX_SAMPLE_BUFFERS_ARB:
-            /* ms not supported */
-            return NULL;
          case GLX_SAMPLES_ARB:
-            /* ms not supported */
-            return NULL;
+           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) {
+            if (*parselist & GLX_RGBA_BIT) {
                rgb_flag = GL_TRUE;
             }
-            else if (*parselist == GLX_COLOR_INDEX_BIT) {
+            else if (*parselist & GLX_COLOR_INDEX_BIT) {
                rgb_flag = GL_FALSE;
             }
             else if (*parselist == 0) {
@@ -1101,6 +1088,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             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 */
@@ -1108,10 +1097,42 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             parselist++;
             break;
          case GLX_FBCONFIG_ID:
+            if (!fbConfig)
+               return NULL;
             parselist++;
-            desiredVisualID = *parselist;
+            desiredVisualID = *parselist++;
+            break;
+         case GLX_X_RENDERABLE:
+            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;
@@ -1124,6 +1145,9 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
       }
    }
 
+   if (!rgb_flag)
+      return NULL;
+
    (void) caveat;
 
    /*
@@ -1143,46 +1167,27 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
       if (vis) {
          /* give the visual some useful GLX attributes */
          double_flag = GL_TRUE;
-         if (vis->depth > 8)
-            rgb_flag = GL_TRUE;
+         if (vis->depth <= 8)
+           return NULL;
          depth_size = default_depth_bits();
          stencil_size = STENCIL_BITS;
          /* XXX accum??? */
       }
    }
-   else if (level==0) {
-      /* normal color planes */
-      if (rgb_flag) {
-         /* Get an 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;
-         }
-         vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
-      }
-      else {
-         /* Get a color index visual */
-         vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
-         accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0;
-      }
-   }
    else {
-      /* over/underlay planes */
-      if (rgb_flag) {
-         /* rgba overlay */
-         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;
-         }
-         vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
-                              trans_type, trans_value, min_rgb, visual_type );
+      /* 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 {
-         /* color index overlay */
-         vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level,
-                              trans_type, trans_value, min_ci, visual_type );
+        vis = choose_x_overlay_visual(dpy, screen, level,
+                                      trans_type, trans_value, min_rgb, visual_type);
       }
    }
 
@@ -1193,25 +1198,29 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
        * return 16 to maintain performance with earlier versions of Mesa.
        */
       if (depth_size > 24)
-         depth_size = 31;   /* 32 causes int overflow problems */
+         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 = STENCIL_BITS;
       if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 ||
           accumAlphaSize > 0) {
-         accumRedSize = ACCUM_BITS;
-         accumGreenSize = ACCUM_BITS;
-         accumBlueSize = ACCUM_BITS;
-         accumAlphaSize = alpha_flag ? ACCUM_BITS : 0;
+         accumRedSize = 
+         accumGreenSize = 
+         accumBlueSize = default_accum_bits();
+         accumAlphaSize = alpha_flag ? accumRedSize : 0;
       }
 
-      xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
+      xmvis = save_glx_visual( dpy, vis, alpha_flag, double_flag,
                                stereo_flag, depth_size, stencil_size,
                                accumRedSize, accumGreenSize,
                                accumBlueSize, accumAlphaSize, level, numAux );
@@ -1224,15 +1233,20 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
 static XVisualInfo *
 Fake_glXChooseVisual( Display *dpy, int screen, int *list )
 {
-   XMesaVisual xmvis = choose_visual(dpy, screen, list, GL_FALSE);
+   XMesaVisual xmvis;
+
+   /* register ourselves as an extension on this display */
+   register_with_display(dpy);
+
+   xmvis = choose_visual(dpy, screen, list, GL_FALSE);
    if (xmvis) {
 #if 0
       return xmvis->vishandle;
 #else
       /* create a new vishandle - the cached one may be stale */
-      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+      xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
       if (xmvis->vishandle) {
-         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+         memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
       }
       return xmvis->vishandle;
 #endif
@@ -1242,6 +1256,25 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list )
 }
 
 
+/**
+ * Init basic fields of a new fake_glx_context.
+ */
+static void
+init_glx_context(struct fake_glx_context *glxCtx, Display *dpy)
+{
+   /* Always return True.  See if anyone's confused... */
+   GLboolean direct = GL_TRUE;
+
+   glxCtx->xmesaContext->direct = direct;
+   glxCtx->glxContext.isDirect = direct;
+   glxCtx->glxContext.currentDpy = dpy;
+   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
+
+   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+}
+
+
+
 static GLXContext
 Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
                        GLXContext share_list, Bool direct )
@@ -1258,7 +1291,9 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
       return 0;
 
    /* deallocate unused windows/buffers */
+#if 0
    XMesaGarbageCollect();
+#endif
 
    xmvis = find_glx_visual( dpy, visinfo );
    if (!xmvis) {
@@ -1266,7 +1301,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
       xmvis = create_glx_visual( dpy, visinfo );
       if (!xmvis) {
          /* unusable visual */
-         FREE(glxCtx);
+         free(glxCtx);
          return NULL;
       }
    }
@@ -1274,16 +1309,11 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
    glxCtx->xmesaContext = XMesaCreateContext(xmvis,
                                    shareCtx ? shareCtx->xmesaContext : NULL);
    if (!glxCtx->xmesaContext) {
-      FREE(glxCtx);
+      free(glxCtx);
       return NULL;
    }
 
-   glxCtx->xmesaContext->direct = GL_FALSE;
-   glxCtx->glxContext.isDirect = GL_FALSE;
-   glxCtx->glxContext.currentDpy = dpy;
-   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
-
-   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+   init_glx_context(glxCtx, dpy);
 
    return (GLXContext) glxCtx;
 }
@@ -1318,11 +1348,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       }
       if (!drawBuffer) {
          /* drawable must be a new window! */
-         drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx);
+         drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw );
          if (!drawBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
          }
+#ifdef FX
+         FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer );
+#endif
       }
 
       /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */
@@ -1335,12 +1368,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       }
       if (!readBuffer) {
          /* drawable must be a new window! */
-         readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual,
-                                               read, xmctx);
+         readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read );
          if (!readBuffer) {
             /* Out of memory, or context/drawable depth mismatch */
             return False;
          }
+#ifdef FX
+         FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer );
+#endif
       }
 
       MakeCurrent_PrevContext = ctx;
@@ -1353,11 +1388,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
          ((__GLXcontext *) ctx)->currentDpy = dpy;
          ((__GLXcontext *) ctx)->currentDrawable = draw;
-#ifndef GLX_BUILT_IN_XMESA
          ((__GLXcontext *) ctx)->currentReadable = read;
-#else
-         __glXSetCurrentContext(ctx);
-#endif
          return True;
       }
       else {
@@ -1372,9 +1403,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
       MakeCurrent_PrevReadable = 0;
       MakeCurrent_PrevDrawBuffer = 0;
       MakeCurrent_PrevReadBuffer = 0;
-#ifdef GLX_BUILT_IN_XMESA
-      /* XXX bind dummy context with __glXSetCurrentContext(ctx); */
-#endif
       return True;
    }
    else {
@@ -1412,7 +1440,7 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
    if (!b) {
       return 0;
    }
-   return b->frontbuffer;
+   return b->frontxrb->pixmap;
 }
 
 
@@ -1438,7 +1466,7 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
    if (!b) {
       return 0;
    }
-   return b->frontbuffer;
+   return b->frontxrb->pixmap;
 }
 
 
@@ -1464,18 +1492,25 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
    XMesaContext xm_src = fakeSrc->xmesaContext;
    XMesaContext xm_dst = fakeDst->xmesaContext;
    (void) dpy;
+   if (MakeCurrent_PrevContext == src) {
+      _mesa_Flush();
+   }
    _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask );
 }
 
 
 static Bool
-Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
+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. */
-   (void) dpy;
-   (void) errorb;
-   (void) event;
-   return True;
+   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 */
 }
 
 
@@ -1499,6 +1534,7 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
    MakeCurrent_PrevReadBuffer = 0;
    XMesaDestroyContext( glxCtx->xmesaContext );
    XMesaGarbageCollect();
+   free(glxCtx);
 }
 
 
@@ -1521,7 +1557,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
       XMesaSwapBuffers(buffer);
    }
    else if (_mesa_getenv("MESA_DEBUG")) {
-      _mesa_warning(NULL, "Mesa: glXSwapBuffers: invalid drawable\n");
+      _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n",
+                    (int) drawable);
    }
 }
 
@@ -1753,6 +1790,27 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
          *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;
    }
@@ -1765,7 +1823,7 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
                    int attrib, int *value )
 {
    XMesaVisual xmvis;
-
+   int k;
    if (!dpy || !visinfo)
       return GLX_BAD_ATTRIBUTE;
 
@@ -1785,7 +1843,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
       }
    }
 
-   return get_config(xmvis, attrib, value, GL_FALSE);
+   k = get_config(xmvis, attrib, value, GL_FALSE);
+   return k;
 }
 
 
@@ -1836,8 +1895,8 @@ static const char *
 Fake_glXQueryServerString( Display *dpy, int screen, int name )
 {
    static char version[1000];
-   _mesa_sprintf(version, "%d.%d %s",
-                 SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
+   sprintf(version, "%d.%d %s",
+          SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
 
    (void) dpy;
    (void) screen;
@@ -1861,8 +1920,8 @@ static const char *
 Fake_glXGetClientString( Display *dpy, int name )
 {
    static char version[1000];
-   _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
-                 CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
+   sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
+          CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
 
    (void) dpy;
 
@@ -1885,28 +1944,6 @@ Fake_glXGetClientString( Display *dpy, int name )
  */
 
 
-static GLXFBConfig *
-Fake_glXChooseFBConfig( Display *dpy, int screen,
-                        const int *attribList, int *nitems )
-{
-   XMesaVisual xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
-   if (xmvis) {
-      GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual));
-      if (!config) {
-         *nitems = 0;
-         return NULL;
-      }
-      *nitems = 1;
-      config[0] = (GLXFBConfig) xmvis;
-      return (GLXFBConfig *) config;
-   }
-   else {
-      *nitems = 0;
-      return NULL;
-   }
-}
-
-
 static int
 Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
                            int attribute, int *value )
@@ -1934,7 +1971,7 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
    visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
    if (*nelements > 0) {
       XMesaVisual *results;
-      results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual));
+      results = (XMesaVisual *) malloc(*nelements * sizeof(XMesaVisual));
       if (!results) {
          *nelements = 0;
          return NULL;
@@ -1948,6 +1985,35 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
 }
 
 
+static GLXFBConfig *
+Fake_glXChooseFBConfig( Display *dpy, int screen,
+                        const int *attribList, int *nitems )
+{
+   XMesaVisual xmvis;
+
+   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 = (GLXFBConfig *) 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 )
 {
@@ -1957,9 +2023,9 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
       return xmvis->vishandle;
 #else
       /* create a new vishandle - the cached one may be stale */
-      xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+      xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
       if (xmvis->vishandle) {
-         _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+         memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
       }
       return xmvis->vishandle;
 #endif
@@ -1979,10 +2045,15 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
    if (!xmvis)
       return 0;
 
-   xmbuf = XMesaCreateWindowBuffer2(xmvis, win, NULL);
+   xmbuf = XMesaCreateWindowBuffer(xmvis, win);
    if (!xmbuf)
       return 0;
 
+#ifdef FX
+   /* XXX this will segfault if actually called */
+   FXcreateContext(xmvis, win, NULL, xmbuf);
+#endif
+
    (void) dpy;
    (void) attribList;  /* Ignored in GLX 1.3 */
 
@@ -2007,16 +2078,102 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
 {
    XMesaVisual v = (XMesaVisual) config;
    XMesaBuffer b;
-
-   (void) dpy;
-   (void) config;
-   (void) pixmap;
-   (void) attribList;  /* Ignored in GLX 1.3 */
+   const int *attr;
+   int target = 0, format = 0, mipmap = 0;
+   int value;
 
    if (!dpy || !config || !pixmap)
       return 0;
 
-   b = XMesaCreatePixmapBuffer( v, pixmap, 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;
    }
@@ -2059,29 +2216,42 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
             break;
          case GLX_PRESERVED_CONTENTS:
             attrib++;
-            preserveContents = *attrib; /* ignored */
+            preserveContents = *attrib;
             break;
          case GLX_LARGEST_PBUFFER:
             attrib++;
-            useLargest = *attrib; /* ignored */
+            useLargest = *attrib;
             break;
          default:
             return 0;
       }
    }
 
-   /* not used at this time */
-   (void) useLargest;
-   (void) preserveContents;
-
    if (width == 0 || height == 0)
       return 0;
 
+   if (width > MAX_WIDTH || height > MAX_HEIGHT) {
+      /* If allocation would have failed and GLX_LARGEST_PBUFFER is set,
+       * allocate the largest possible buffer.
+       */
+      if (useLargest) {
+         width = MAX_WIDTH;
+         height = MAX_HEIGHT;
+      }
+   }
+
    xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height);
    /* A GLXPbuffer handle must be an X Drawable because that's what
     * glXMakeCurrent takes.
     */
-   return (GLXPbuffer) xmbuf->frontbuffer;
+   if (xmbuf) {
+      xmbuf->largestPbuffer = useLargest;
+      xmbuf->preservedContents = preserveContents;
+      return (GLXPbuffer) xmbuf->frontxrb->pixmap;
+   }
+   else {
+      return 0;
+   }
 }
 
 
@@ -2103,6 +2273,9 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
    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;
@@ -2111,16 +2284,28 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
          *value = xmbuf->mesa_buffer.Height;
          break;
       case GLX_PRESERVED_CONTENTS:
-         *value = True;
+         *value = xmbuf->preservedContents;
          break;
       case GLX_LARGEST_PBUFFER:
-         *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height;
+         *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;  /* GLX_BAD_ATTRIBUTE? */
+         return; /* raise BadValue error */
    }
 }
 
@@ -2147,16 +2332,11 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
    glxCtx->xmesaContext = XMesaCreateContext(xmvis,
                                    shareCtx ? shareCtx->xmesaContext : NULL);
    if (!glxCtx->xmesaContext) {
-      FREE(glxCtx);
+      free(glxCtx);
       return NULL;
    }
 
-   glxCtx->xmesaContext->direct = GL_FALSE;
-   glxCtx->glxContext.isDirect = GL_FALSE;
-   glxCtx->glxContext.currentDpy = dpy;
-   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
-
-   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+   init_glx_context(glxCtx, dpy);
 
    return (GLXContext) glxCtx;
 }
@@ -2176,10 +2356,7 @@ Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
       *value = xmctx->xm_visual->visinfo->visualid;
       break;
    case GLX_RENDER_TYPE:
-      if (xmctx->xm_visual->mesa_visual.rgbMode)
-         *value = GLX_RGBA_BIT;
-      else
-         *value = GLX_COLOR_INDEX_BIT;
+      *value = GLX_RGBA_TYPE;
       break;
    case GLX_SCREEN:
       *value = 0;
@@ -2226,19 +2403,26 @@ Fake_glXSwapIntervalSGI(int interval)
 
 /*** GLX_SGI_video_sync ***/
 
+static unsigned int FrameCounter = 0;
+
 static int
 Fake_glXGetVideoSyncSGI(unsigned int *count)
 {
-   (void) count;
+   /* this is a bogus implementation */
+   *count = FrameCounter++;
    return 0;
 }
 
 static int
 Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
-   (void) divisor;
-   (void) remainder;
-   (void) 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;
 }
 
@@ -2342,7 +2526,7 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
-   return xmbuf->frontbuffer; /* need to return an X ID */
+   return xmbuf->frontxrb->pixmap; /* need to return an X ID */
 }
 
 
@@ -2363,16 +2547,11 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re
    glxCtx->xmesaContext = XMesaCreateContext(xmvis,
                                    shareCtx ? shareCtx->xmesaContext : NULL);
    if (!glxCtx->xmesaContext) {
-      FREE(glxCtx);
+      free(glxCtx);
       return NULL;
    }
 
-   glxCtx->xmesaContext->direct = GL_FALSE;
-   glxCtx->glxContext.isDirect = GL_FALSE;
-   glxCtx->glxContext.currentDpy = dpy;
-   glxCtx->glxContext.xid = (XID) glxCtx;  /* self pointer */
-
-   assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+   init_glx_context(glxCtx, dpy);
 
    return (GLXContext) glxCtx;
 }
@@ -2436,7 +2615,7 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
    /* A GLXPbuffer handle must be an X Drawable because that's what
     * glXMakeCurrent takes.
     */
-   return (GLXPbuffer) xmbuf->frontbuffer;
+   return (GLXPbuffer) xmbuf->frontxrb->pixmap;
 }
 
 
@@ -2462,10 +2641,10 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un
 
    switch (attribute) {
       case GLX_PRESERVED_CONTENTS_SGIX:
-         *value = True;
+         *value = xmbuf->preservedContents;
          break;
       case GLX_LARGEST_PBUFFER_SGIX:
-         *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height;
+         *value = xmbuf->largestPbuffer;
          break;
       case GLX_WIDTH_SGIX:
          *value = xmbuf->mesa_buffer.Width;
@@ -2706,6 +2885,26 @@ Fake_glXGetAGPOffsetMESA( const GLvoid *pointer )
 }
 
 
+/*** 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);
+}
+
+
 /* silence warning */
 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
 
@@ -2861,5 +3060,9 @@ _mesa_GetGLXDispatchTable(void)
    /*** GLX_MESA_agp_offset ***/
    glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA;
 
+   /*** GLX_EXT_texture_from_pixmap ***/
+   glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
+   glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
+
    return &glx;
 }