xmesa: drop glide (FX) backend.
[mesa.git] / src / mesa / drivers / x11 / xm_api.c
index 6ebda0c14f86018d983e7d8040087a48a140c54c..6f671969fec16237a5ea498ce33b06aedde76f4a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.5.2
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  Brian Paul   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"),
  * 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.
  */
-/* $XFree86: xc/extras/Mesa/src/X/xm_api.c,v 1.2 2002/02/26 23:37:31 tsi Exp $ */
 
-/*
- * This file contains the implementations of all the XMesa* functions.
+/**
+ * \file xm_api.c
+ *
+ * All the XMesa* API functions.
  *
  *
  * NOTES:
 #include "xmesaP.h"
 #include "context.h"
 #include "extensions.h"
+#include "framebuffer.h"
 #include "glthread.h"
 #include "imports.h"
-#include "matrix.h"
-#include "mtypes.h"
 #include "macros.h"
-#include "texformat.h"
-#include "texobj.h"
-#include "texstore.h"
+#include "renderbuffer.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 #include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "drivers/common/driverfuncs.h"
 
-#ifndef GLX_NONE_EXT
-#define GLX_NONE_EXT 0x8000
-#endif
-
-
-/*
+/**
  * Global X driver lock
  */
 _glthread_Mutex _xmesa_lock;
 
 
 
-/*
+/**
  * Lookup tables for HPCR pixel format:
  */
 static short hpcr_rgbTbl[3][256] = {
@@ -158,7 +154,7 @@ static short hpcr_rgbTbl[3][256] = {
 /**********************************************************************/
 
 
-/*
+/**
  * Return the host's byte order as LSBFirst or MSBFirst ala X.
  */
 #ifndef XFree86Server
@@ -171,32 +167,15 @@ static int host_byte_order( void )
 #endif
 
 
-/*
- * Error handling.
- */
-#ifndef XFree86Server
-static int mesaXErrorFlag = 0;
-
-static int mesaHandleXError( XMesaDisplay *dpy, XErrorEvent *event )
-{
-   (void) dpy;
-   (void) event;
-   mesaXErrorFlag = 1;
-   return 0;
-}
-#endif
-
-
-/*
+/**
  * Check if the X Shared Memory extension is available.
  * Return:  0 = not available
  *          1 = shared XImage support available
  *          2 = shared Pixmap support available also
  */
-#ifndef XFree86Server
 static int check_for_xshm( XMesaDisplay *display )
 {
-#ifdef USE_XSHM
+#if defined(USE_XSHM) && !defined(XFree86Server)
    int major, minor, ignore;
    Bool pixmaps;
 
@@ -212,40 +191,18 @@ static int check_for_xshm( XMesaDisplay *display )
       return 0;
    }
 #else
-   /* Can't compile XSHM support */
+   /* No  XSHM support */
    return 0;
 #endif
 }
-#endif
-
-
-/*
- * Return the width and height of the given drawable.
- */
-static void get_drawable_size( XMesaDisplay *dpy, XMesaDrawable d,
-                               unsigned int *width, unsigned int *height)
-{
-#ifdef XFree86Server
-    (void) dpy;
-    *width = d->width;
-    *height = d->height;
-#else
-   Window root;
-   int x, y;
-   unsigned int bw, depth;
-
-   _glthread_LOCK_MUTEX(_xmesa_lock);
-   XGetGeometry( dpy, d, &root, &x, &y, width, height, &bw, &depth );
-   _glthread_UNLOCK_MUTEX(_xmesa_lock);
-#endif
-}
 
 
-/*
+/**
  * Apply gamma correction to an intensity value in [0..max].  Return the
  * new intensity value.
  */
-static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
+static GLint
+gamma_adjust( GLfloat gamma, GLint value, GLint max )
 {
    if (gamma == 1.0) {
       return value;
@@ -258,7 +215,7 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
 
 
 
-/*
+/**
  * Return the true number of bits per pixel for XImages.
  * For example, if we request a 24-bit deep visual we may actually need/get
  * 32bpp XImages.  This function returns the appropriate bpp.
@@ -266,24 +223,19 @@ static GLint gamma_adjust( GLfloat gamma, GLint value, GLint max )
  *         visinfo - desribes the visual to be used for XImages
  * Return:  true number of bits per pixel for XImages
  */
-#ifdef XFree86Server
-
-static int bits_per_pixel( XMesaVisual xmv )
+static int
+bits_per_pixel( XMesaVisual xmv )
 {
-   XMesaVisualInfo visinfo = xmv->visinfo;
-   const int depth = visinfo->nplanes;
+#ifdef XFree86Server
+   const int depth = xmv->nplanes;
    int i;
+   assert(depth > 0);
    for (i = 0; i < screenInfo.numPixmapFormats; i++) {
       if (screenInfo.formats[i].depth == depth)
          return screenInfo.formats[i].bitsPerPixel;
    }
    return depth;  /* should never get here, but this should be safe */
-}
-
 #else
-
-static int bits_per_pixel( XMesaVisual xmv )
-{
    XMesaDisplay *dpy = xmv->display;
    XMesaVisualInfo visinfo = xmv->visinfo;
    XMesaImage *img;
@@ -300,12 +252,12 @@ static int bits_per_pixel( XMesaVisual xmv )
    /* grab the bits/pixel value */
    bitsPerPixel = img->bits_per_pixel;
    /* free the XImage */
-   FREE( img->data );
+   _mesa_free( img->data );
    img->data = NULL;
    XMesaDestroyImage( img );
    return bitsPerPixel;
-}
 #endif
+}
 
 
 
@@ -344,32 +296,155 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win )
 
 
 
+/**
+ * Return the size of the window (or pixmap) that corresponds to the
+ * given XMesaBuffer.
+ * \param width  returns width in pixels
+ * \param height  returns height in pixels
+ */
+void
+xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b,
+                      GLuint *width, GLuint *height)
+{
+#ifdef XFree86Server
+   *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH);
+   *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT);
+#else
+   Window root;
+   Status stat;
+   int xpos, ypos;
+   unsigned int w, h, bw, depth;
+
+   _glthread_LOCK_MUTEX(_xmesa_lock);
+   XSync(b->xm_visual->display, 0); /* added for Chromium */
+   stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos,
+                       &w, &h, &bw, &depth);
+   _glthread_UNLOCK_MUTEX(_xmesa_lock);
+
+   if (stat) {
+      *width = w;
+      *height = h;
+   }
+   else {
+      /* probably querying a window that's recently been destroyed */
+      _mesa_warning(NULL, "XGetGeometry failed!\n");
+      *width = *height = 1;
+   }
+#endif
+}
+
+
+
 /**********************************************************************/
 /*****                Linked list of XMesaBuffers                 *****/
 /**********************************************************************/
 
-static XMesaBuffer XMesaBufferList = NULL;
+XMesaBuffer XMesaBufferList = NULL;
 
 
-/* Allocate a new XMesaBuffer, add to linked list */
-static XMesaBuffer alloc_xmesa_buffer(void)
+/**
+ * Allocate a new XMesaBuffer object which corresponds to the given drawable.
+ * Note that XMesaBuffer is derived from GLframebuffer.
+ * The new XMesaBuffer will not have any size (Width=Height=0).
+ *
+ * \param d  the corresponding X drawable (window or pixmap)
+ * \param type  either WINDOW, PIXMAP or PBUFFER, describing d
+ * \param vis  the buffer's visual
+ * \param cmap  the window's colormap, if known.
+ * \return new XMesaBuffer or NULL if any problem
+ */
+static XMesaBuffer
+create_xmesa_buffer(XMesaDrawable d, BufferType type,
+                    XMesaVisual vis, XMesaColormap cmap)
 {
-   XMesaBuffer b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
-   if (b) {
-      b->Next = XMesaBufferList;
-      XMesaBufferList = b;
+   XMesaBuffer b;
+
+   ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
+
+   b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
+   if (!b)
+      return NULL;
+
+   b->display = vis->display;
+   b->xm_visual = vis;
+   b->type = type;
+   b->cmap = cmap;
+
+   _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual);
+   b->mesa_buffer.Delete = xmesa_delete_framebuffer;
+
+   /*
+    * Front renderbuffer
+    */
+   b->frontxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_FALSE);
+   if (!b->frontxrb) {
+      _mesa_free(b);
+      return NULL;
+   }
+   b->frontxrb->Parent = b;
+   b->frontxrb->drawable = d;
+   b->frontxrb->pixmap = (XMesaPixmap) d;
+   _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT,
+                          &b->frontxrb->Base);
+
+   /*
+    * Back renderbuffer
+    */
+   if (vis->mesa_visual.doubleBufferMode) {
+      b->backxrb = xmesa_new_renderbuffer(NULL, 0, &vis->mesa_visual, GL_TRUE);
+      if (!b->backxrb) {
+         /* XXX free front xrb too */
+         _mesa_free(b);
+         return NULL;
+      }
+      b->backxrb->Parent = b;
+      /* determine back buffer implementation */
+      b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP;
+      
+      _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT,
+                             &b->backxrb->Base);
    }
+
+   /*
+    * Software alpha planes
+    */
+   if (vis->mesa_visual.alphaBits > 0
+       && vis->undithered_pf != PF_8A8B8G8R
+       && vis->undithered_pf != PF_8A8R8G8B) {
+      /* Visual has alpha, but pixel format doesn't support it.
+       * We'll use an alpha renderbuffer wrapper.
+       */
+      b->swAlpha = GL_TRUE;
+   }
+   else {
+      b->swAlpha = GL_FALSE;
+   }
+
+   /*
+    * Other renderbuffer (depth, stencil, etc)
+    */
+   _mesa_add_soft_renderbuffers(&b->mesa_buffer,
+                                GL_FALSE,  /* color */
+                                vis->mesa_visual.haveDepthBuffer,
+                                vis->mesa_visual.haveStencilBuffer,
+                                vis->mesa_visual.haveAccumBuffer,
+                                b->swAlpha,
+                                vis->mesa_visual.numAuxBuffers > 0 );
+
+   /* insert buffer into linked list */
+   b->Next = XMesaBufferList;
+   XMesaBufferList = b;
+
    return b;
 }
 
 
-/*
+/**
  * Find an XMesaBuffer by matching X display and colormap but NOT matching
  * the notThis buffer.
  */
-static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
-                                     XMesaColormap cmap,
-                                     XMesaBuffer notThis)
+XMesaBuffer
+xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis)
 {
    XMesaBuffer b;
    for (b=XMesaBufferList; b; b=b->Next) {
@@ -381,38 +456,34 @@ static XMesaBuffer find_xmesa_buffer(XMesaDisplay *dpy,
 }
 
 
-/*
- * Free an XMesaBuffer, remove from linked list, perhaps free X colormap
- * entries.
+/**
+ * Remove buffer from linked list, delete if no longer referenced.
  */
-static void free_xmesa_buffer(int client, XMesaBuffer buffer)
+static void
+xmesa_free_buffer(XMesaBuffer buffer)
 {
    XMesaBuffer prev = NULL, b;
-   (void) client;
-   for (b=XMesaBufferList; b; b=b->Next) {
-      if (b==buffer) {
-         /* unlink bufer from list */
+
+   for (b = XMesaBufferList; b; b = b->Next) {
+      if (b == buffer) {
+         struct gl_framebuffer *fb = &buffer->mesa_buffer;
+
+         /* unlink buffer from list */
          if (prev)
             prev->Next = buffer->Next;
          else
             XMesaBufferList = buffer->Next;
-         /* Check to free X colors */
-         if (buffer->num_alloced>0) {
-            /* If no other buffer uses this X colormap then free the colors. */
-            if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) {
-#ifdef XFree86Server
-               (void)FreeColors(buffer->cmap, client,
-                               buffer->num_alloced, buffer->alloced_colors,
-                               0);
-#else
-               XFreeColors(buffer->display, buffer->cmap,
-                           buffer->alloced_colors, buffer->num_alloced, 0);
-#endif
-            }
-         }
 
-         _mesa_free_framebuffer_data(&buffer->mesa_buffer);
-         FREE(buffer);
+         /* mark as delete pending */
+         fb->DeletePending = GL_TRUE;
+
+         /* Since the X window for the XMesaBuffer is going away, we don't
+          * want to dereference this pointer in the future.
+          */
+         b->frontxrb->drawable = 0;
+
+         /* Unreference.  If count = zero we'll really delete the buffer */
+         _mesa_unreference_framebuffer(&fb);
 
          return;
       }
@@ -420,12 +491,15 @@ static void free_xmesa_buffer(int client, XMesaBuffer buffer)
       prev = b;
    }
    /* buffer not found in XMesaBufferList */
-   _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n");
+   _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n");
 }
 
 
-/* Copy X color table stuff from one XMesaBuffer to another. */
-static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
+/**
+ * Copy X color table stuff from one XMesaBuffer to another.
+ */
+static void
+copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
 {
    MEMCPY(dst->color_table, src->color_table, sizeof(src->color_table));
    MEMCPY(dst->pixel_to_r, src->pixel_to_r, sizeof(src->pixel_to_r));
@@ -443,214 +517,7 @@ static void copy_colortable_info(XMesaBuffer dst, const XMesaBuffer src)
 /**********************************************************************/
 
 
-/*
- * Return number of bits set in n.
- */
-static int bitcount( unsigned long n )
-{
-   int bits;
-   for (bits=0; n>0; n=n>>1) {
-      if (n&1) {
-         bits++;
-      }
-   }
-   return bits;
-}
-
-
-
-/*
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- * Return:  GL_TRUE if success, GL_FALSE if error
- */
-#ifndef XFree86Server
-static GLboolean alloc_shm_back_buffer( XMesaBuffer b )
-{
-#ifdef USE_XSHM
-   /*
-    * We have to do a _lot_ of error checking here to be sure we can
-    * really use the XSHM extension.  It seems different servers trigger
-    * errors at different points if the extension won't work.  Therefore
-    * we have to be very careful...
-    */
-   GC gc;
-   int (*old_handler)( XMesaDisplay *, XErrorEvent * );
-
-   b->backimage = XShmCreateImage( b->xm_visual->display,
-                                   b->xm_visual->visinfo->visual,
-                                   b->xm_visual->visinfo->depth,
-                                  ZPixmap, NULL, &b->shminfo,
-                                  b->width, b->height );
-   if (b->backimage == NULL) {
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (XShmCreateImage), disabling.");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.shmid = shmget( IPC_PRIVATE, b->backimage->bytes_per_line
-                            * b->backimage->height, IPC_CREAT|0777 );
-   if (b->shminfo.shmid < 0) {
-      _mesa_warning(NULL, "shmget failed while allocating back buffer");
-      XDestroyImage( b->backimage );
-      b->backimage = NULL;
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmget), disabling.");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.shmaddr = b->backimage->data
-                      = (char*)shmat( b->shminfo.shmid, 0, 0 );
-   if (b->shminfo.shmaddr == (char *) -1) {
-      _mesa_warning(NULL, "shmat() failed while allocating back buffer");
-      XDestroyImage( b->backimage );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backimage = NULL;
-      _mesa_warning(NULL, "alloc_back_buffer: Shared memory error (shmat), disabling.");
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   b->shminfo.readOnly = False;
-   mesaXErrorFlag = 0;
-   old_handler = XSetErrorHandler( mesaHandleXError );
-   /* This may trigger the X protocol error we're ready to catch: */
-   XShmAttach( b->xm_visual->display, &b->shminfo );
-   XSync( b->xm_visual->display, False );
-
-   if (mesaXErrorFlag) {
-      /* we are on a remote display, this error is normal, don't print it */
-      XFlush( b->xm_visual->display );
-      mesaXErrorFlag = 0;
-      XDestroyImage( b->backimage );
-      shmdt( b->shminfo.shmaddr );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backimage = NULL;
-      b->shm = 0;
-      (void) XSetErrorHandler( old_handler );
-      return GL_FALSE;
-   }
-
-   shmctl( b->shminfo.shmid, IPC_RMID, 0 ); /* nobody else needs it */
-
-   /* Finally, try an XShmPutImage to be really sure the extension works */
-   gc = XCreateGC( b->xm_visual->display, b->frontbuffer, 0, NULL );
-   XShmPutImage( b->xm_visual->display, b->frontbuffer, gc,
-                b->backimage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False );
-   XSync( b->xm_visual->display, False );
-   XFreeGC( b->xm_visual->display, gc );
-   (void) XSetErrorHandler( old_handler );
-   if (mesaXErrorFlag) {
-      XFlush( b->xm_visual->display );
-      mesaXErrorFlag = 0;
-      XDestroyImage( b->backimage );
-      shmdt( b->shminfo.shmaddr );
-      shmctl( b->shminfo.shmid, IPC_RMID, 0 );
-      b->backimage = NULL;
-      b->shm = 0;
-      return GL_FALSE;
-   }
-
-   if (b->backimage) {
-      int height = b->backimage->height;
-      /* Needed by PIXELADDR1 macro */
-      b->ximage_width1 = b->backimage->bytes_per_line;
-      b->ximage_origin1 = (GLubyte *) b->backimage->data
-                        + b->ximage_width1 * (height-1);
-      /* Needed by PIXELADDR2 macro */
-      b->ximage_width2 = b->backimage->bytes_per_line / 2;
-      b->ximage_origin2 = (GLushort *) b->backimage->data
-                        + b->ximage_width2 * (height-1);
-      /* Needed by PIXELADDR3 macro */
-      b->ximage_width3 = b->backimage->bytes_per_line;
-      b->ximage_origin3 = (GLubyte *) b->backimage->data
-                        + b->ximage_width3 * (height-1);
-      /* Needed by PIXELADDR4 macro */
-      b->ximage_width4 = b->backimage->width;
-      b->ximage_origin4 = (GLuint *) b->backimage->data
-                        + b->ximage_width4 * (height-1);
-   }
-
-   return GL_TRUE;
-#else
-   /* Can't compile XSHM support */
-   return GL_FALSE;
-#endif
-}
-#endif
-
-
-
-/*
- * Setup an off-screen pixmap or Ximage to use as the back buffer.
- * Input:  b - the X/Mesa buffer
- */
-void xmesa_alloc_back_buffer( XMesaBuffer b )
-{
-   if (b->db_state==BACK_XIMAGE) {
-      /* Deallocate the old backimage, if any */
-      if (b->backimage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
-        if (b->shm) {
-           XShmDetach( b->xm_visual->display, &b->shminfo );
-           XDestroyImage( b->backimage );
-           shmdt( b->shminfo.shmaddr );
-        }
-        else
-#endif
-          XMesaDestroyImage( b->backimage );
-        b->backimage = NULL;
-      }
-
-      /* Allocate new back buffer */
-#ifdef XFree86Server
-      {
-        /* Allocate a regular XImage for the back buffer. */
-        b->backimage = XMesaCreateImage(b->xm_visual->BitsPerPixel,
-                                        b->width, b->height, NULL);
-#else
-      if (b->shm==0 || alloc_shm_back_buffer(b)==GL_FALSE) {
-        /* Allocate a regular XImage for the back buffer. */
-        b->backimage = XCreateImage( b->xm_visual->display,
-                                      b->xm_visual->visinfo->visual,
-                                      GET_VISUAL_DEPTH(b->xm_visual),
-                                     ZPixmap, 0,   /* format, offset */
-                                     NULL, b->width, b->height,
-                                     8, 0 );  /* pad, bytes_per_line */
-#endif
-        if (!b->backimage) {
-           _mesa_warning(NULL, "alloc_back_buffer: XCreateImage failed.");
-        }
-         b->backimage->data = (char *) MALLOC( b->backimage->height
-                                             * b->backimage->bytes_per_line );
-         if (!b->backimage->data) {
-            _mesa_warning(NULL, "alloc_back_buffer: MALLOC failed.");
-            XMesaDestroyImage( b->backimage );
-            b->backimage = NULL;
-         }
-      }
-      b->backpixmap = None;
-   }
-   else if (b->db_state==BACK_PIXMAP) {
-      XMesaPixmap old_pixmap = b->backpixmap;
-      /* Free the old back pixmap */
-      if (b->backpixmap) {
-        XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
-      }
-      /* Allocate new back pixmap */
-      b->backpixmap = XMesaCreatePixmap( b->xm_visual->display, b->frontbuffer,
-                                        b->width, b->height,
-                                        GET_VISUAL_DEPTH(b->xm_visual) );
-      b->backimage = NULL;
-      /* update other references to backpixmap */
-      if (b->buffer==(XMesaDrawable)old_pixmap) {
-        b->buffer = (XMesaDrawable)b->backpixmap;
-      }
-   }
-}
-
-
-
-/*
+/**
  * A replacement for XAllocColor.  This function should never
  * fail to allocate a color.  When XAllocColor fails, we return
  * the nearest matching color.  If we have to allocate many colors
@@ -693,10 +560,11 @@ noFaultXAllocColor( int client,
    if (AllocColor(cmap,
                  &color->red, &color->green, &color->blue,
                  &color->pixel,
-                 client) == Success) {
+                 client) == Success)
 #else
-   if (XAllocColor(dpy, cmap, color)) {
+   if (XAllocColor(dpy, cmap, color))
 #endif
+   {
       *exact = 1;
       *alloced = 1;
       return;
@@ -718,7 +586,7 @@ noFaultXAllocColor( int client,
        || prevCmapSize != cmapSize || !ctable) {
       /* free previously cached color table */
       if (ctable)
-         FREE(ctable);
+         _mesa_free(ctable);
       /* Get the color table from X */
       ctable = (XMesaColor *) MALLOC(cmapSize * sizeof(XMesaColor));
       assert(ctable);
@@ -774,8 +642,8 @@ noFaultXAllocColor( int client,
       *alloced = 0;
    }
 #ifdef XFree86Server
-   FREE(ppixIn);
-   FREE(ctable);
+   _mesa_free(ppixIn);
+   _mesa_free(ctable);
 #else
    /* don't free table, save it for next time */
 #endif
@@ -786,13 +654,13 @@ noFaultXAllocColor( int client,
 
 
 
-
-/*
+/**
  * Do setup for PF_GRAYSCALE pixel format.
  * Note that buffer may be NULL.
  */
-static GLboolean setup_grayscale( int client, XMesaVisual v,
-                                  XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_grayscale(int client, XMesaVisual v,
+                XMesaBuffer buffer, XMesaColormap cmap)
 {
    if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
       return GL_FALSE;
@@ -805,7 +673,7 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
          return GL_FALSE;
       }
 
-      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
+      prevBuffer = xmesa_find_buffer(v->display, cmap, buffer);
       if (prevBuffer &&
           (buffer->xm_visual->mesa_visual.rgbMode ==
            prevBuffer->xm_visual->mesa_visual.rgbMode)) {
@@ -871,7 +739,7 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
 
 
 
-/*
+/**
  * Setup RGB rendering for a window with a PseudoColor, StaticColor,
  * or 8-bit TrueColor visual visual.  We try to allocate a palette of 225
  * colors (5 red, 9 green, 5 blue) and dither to approximate a 24-bit RGB
@@ -879,8 +747,9 @@ static GLboolean setup_grayscale( int client, XMesaVisual v,
  * visuals, it has also proven to work from 4-bit up to 16-bit visuals.
  * Dithering code contributed by Bob Mercier.
  */
-static GLboolean setup_dithered_color( int client, XMesaVisual v,
-                                       XMesaBuffer buffer, XMesaColormap cmap )
+static GLboolean
+setup_dithered_color(int client, XMesaVisual v,
+                     XMesaBuffer buffer, XMesaColormap cmap)
 {
    if (GET_VISUAL_DEPTH(v)<4 || GET_VISUAL_DEPTH(v)>16) {
       return GL_FALSE;
@@ -893,7 +762,7 @@ static GLboolean setup_dithered_color( int client, XMesaVisual v,
          return GL_FALSE;
       }
 
-      prevBuffer = find_xmesa_buffer(v->display, cmap, buffer);
+      prevBuffer = xmesa_find_buffer(v->display, cmap, buffer);
       if (prevBuffer &&
           (buffer->xm_visual->mesa_visual.rgbMode ==
            prevBuffer->xm_visual->mesa_visual.rgbMode)) {
@@ -950,12 +819,13 @@ static GLboolean setup_dithered_color( int client, XMesaVisual v,
 }
 
 
-/*
+/**
  * Setup for Hewlett Packard Color Recovery 8-bit TrueColor mode.
  * HPCR simulates 24-bit color fidelity with an 8-bit frame buffer.
  * Special dithering tables have to be initialized.
  */
-static void setup_8bit_hpcr( XMesaVisual v )
+static void
+setup_8bit_hpcr(XMesaVisual v)
 {
    /* HP Color Recovery contributed by:  Alex De Bruyn (ad@lms.be)
     * To work properly, the atom _HP_RGB_SMOOTH_MAP_LIST must be defined
@@ -1005,11 +875,11 @@ static void setup_8bit_hpcr( XMesaVisual v )
 }
 
 
-/*
+/**
  * Setup RGB rendering for a window with a True/DirectColor visual.
  */
-static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
-                             XMesaColormap cmap )
+static void
+setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
 {
    unsigned long rmask, gmask, bmask;
    (void) buffer;
@@ -1049,9 +919,9 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
           3*16, 11*16,  1*16,  9*16,
          15*16,  7*16, 13*16,  5*16,
       };
-      GLint rBits = bitcount(rmask);
-      GLint gBits = bitcount(gmask);
-      GLint bBits = bitcount(bmask);
+      GLint rBits = _mesa_bitcount(rmask);
+      GLint gBits = _mesa_bitcount(gmask);
+      GLint bBits = _mesa_bitcount(bmask);
       GLint maxBits;
       GLuint i;
 
@@ -1100,39 +970,33 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
        && GET_BLUEMASK(v) ==0xff0000
        && CHECK_BYTE_ORDER(v)
        && v->BitsPerPixel==32
-       && sizeof(GLuint)==4
        && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
       /* common 32 bpp config used on SGI, Sun */
-      v->undithered_pf = v->dithered_pf = PF_8A8B8G8R;
-   }
-   else if (GET_REDMASK(v)  ==0xff0000
-       &&   GET_GREENMASK(v)==0x00ff00
-       &&   GET_BLUEMASK(v) ==0x0000ff
-       && CHECK_BYTE_ORDER(v)
-       && v->BitsPerPixel==32
-       && sizeof(GLuint)==4
-       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
-      /* common 32 bpp config used on Linux, HP, IBM */
-      v->undithered_pf = v->dithered_pf = PF_8R8G8B;
-   }
-   else if (GET_REDMASK(v)  ==0xff0000
-       &&   GET_GREENMASK(v)==0x00ff00
-       &&   GET_BLUEMASK(v) ==0x0000ff
-       && CHECK_BYTE_ORDER(v)
-       && v->BitsPerPixel==24
-       && sizeof(GLuint)==4
-       && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
-      /* common packed 24 bpp config used on Linux */
-      v->undithered_pf = v->dithered_pf = PF_8R8G8B24;
+      v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; /* ABGR */
+   }
+   else if (GET_REDMASK(v)  == 0xff0000
+         && GET_GREENMASK(v)== 0x00ff00
+         && GET_BLUEMASK(v) == 0x0000ff
+         && CHECK_BYTE_ORDER(v)
+         && v->RedGamma == 1.0 && v->GreenGamma == 1.0 && v->BlueGamma == 1.0){
+      if (v->BitsPerPixel==32) {
+         /* if 32 bpp, and visual indicates 8 bpp alpha channel */
+         if (GET_VISUAL_DEPTH(v) == 32 && v->mesa_visual.alphaBits == 8)
+            v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; /* ARGB */
+         else
+            v->undithered_pf = v->dithered_pf = PF_8R8G8B; /* xRGB */
+      }
+      else if (v->BitsPerPixel == 24) {
+         v->undithered_pf = v->dithered_pf = PF_8R8G8B24; /* RGB */
+      }
    }
    else if (GET_REDMASK(v)  ==0xf800
        &&   GET_GREENMASK(v)==0x07e0
        &&   GET_BLUEMASK(v) ==0x001f
        && CHECK_BYTE_ORDER(v)
        && v->BitsPerPixel==16
-       && sizeof(GLushort)==2
        && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) {
-      /* 5-6-5 color weight on common PC VGA boards */
+      /* 5-6-5 RGB */
       v->undithered_pf = PF_5R6G5B;
       v->dithered_pf = PF_Dither_5R6G5B;
    }
@@ -1140,16 +1004,18 @@ static void setup_truecolor( XMesaVisual v, XMesaBuffer buffer,
        &&   GET_GREENMASK(v)==0x1c
        &&   GET_BLUEMASK(v) ==0x03
        && CHECK_FOR_HPCR(v)) {
+      /* 8-bit HP color recovery */
       setup_8bit_hpcr( v );
    }
 }
 
 
 
-/*
+/**
  * Setup RGB rendering for a window with a monochrome visual.
  */
-static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
+static void
+setup_monochrome( XMesaVisual v, XMesaBuffer b )
 {
    (void) b;
    v->dithered_pf = v->undithered_pf = PF_1Bit;
@@ -1159,72 +1025,62 @@ static void setup_monochrome( XMesaVisual v, XMesaBuffer b )
 
 
 
-/*
- * When a context is "made current" for the first time, we can finally
- * finish initializing the context's visual and buffer information.
- * Input:  v - the XMesaVisual to initialize
- *         b - the XMesaBuffer to initialize (may be NULL)
- *         rgb_flag - TRUE = RGBA mode, FALSE = color index mode
- *         window - the window/pixmap we're rendering into
- *         cmap - the colormap associated with the window/pixmap
- * Return:  GL_TRUE=success, GL_FALSE=failure
+/**
+ * When a context is bound for the first time, we can finally finish
+ * initializing the context's visual and buffer information.
+ * \param v  the XMesaVisual to initialize
+ * \param b  the XMesaBuffer to initialize (may be NULL)
+ * \param rgb_flag  TRUE = RGBA mode, FALSE = color index mode
+ * \param window  the window/pixmap we're rendering into
+ * \param cmap  the colormap associated with the window/pixmap
+ * \return GL_TRUE=success, GL_FALSE=failure
  */
-static GLboolean initialize_visual_and_buffer( int client,
-                                               XMesaVisual v,
-                                               XMesaBuffer b,
-                                               GLboolean rgb_flag,
-                                               XMesaDrawable window,
-                                               XMesaColormap cmap )
+static GLboolean
+initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b,
+                             GLboolean rgb_flag, XMesaDrawable window,
+                             XMesaColormap cmap)
 {
-#ifndef XFree86Server
-   XGCValues gcvalues;
-#endif
-
-   if (b) {
-      assert(b->xm_visual == v);
-   }
+   ASSERT(!b || b->xm_visual == v);
 
    /* Save true bits/pixel */
    v->BitsPerPixel = bits_per_pixel(v);
    assert(v->BitsPerPixel > 0);
 
-
-   if (rgb_flag==GL_FALSE) {
+   if (rgb_flag == GL_FALSE) {
       /* COLOR-INDEXED WINDOW:
        * Even if the visual is TrueColor or DirectColor we treat it as
        * being color indexed.  This is weird but might be useful to someone.
        */
       v->dithered_pf = v->undithered_pf = PF_Index;
-      v->index_bits = GET_VISUAL_DEPTH(v);
+      v->mesa_visual.indexBits = GET_VISUAL_DEPTH(v);
    }
    else {
       /* RGB WINDOW:
        * We support RGB rendering into almost any kind of visual.
        */
-      int xclass;
-      xclass = GET_VISUAL_CLASS(v);
-      if (xclass==TrueColor || xclass==DirectColor) {
+      const int xclass = v->mesa_visual.visualType;
+      if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
         setup_truecolor( v, b, cmap );
       }
-      else if (xclass==StaticGray && GET_VISUAL_DEPTH(v)==1) {
+      else if (xclass == GLX_STATIC_GRAY && GET_VISUAL_DEPTH(v) == 1) {
         setup_monochrome( v, b );
       }
-      else if (xclass==GrayScale || xclass==StaticGray) {
+      else if (xclass == GLX_GRAY_SCALE || xclass == GLX_STATIC_GRAY) {
          if (!setup_grayscale( client, v, b, cmap )) {
             return GL_FALSE;
          }
       }
-      else if ((xclass==PseudoColor || xclass==StaticColor)
+      else if ((xclass == GLX_PSEUDO_COLOR || xclass == GLX_STATIC_COLOR)
                && GET_VISUAL_DEPTH(v)>=4 && GET_VISUAL_DEPTH(v)<=16) {
         if (!setup_dithered_color( client, v, b, cmap )) {
             return GL_FALSE;
          }
       }
       else {
-        _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.");
+        _mesa_warning(NULL, "XMesa: RGB mode rendering not supported in given visual.\n");
         return GL_FALSE;
       }
-      v->index_bits = 0;
+      v->mesa_visual.indexBits = 0;
 
       if (_mesa_getenv("MESA_NO_DITHER")) {
         v->dithered_pf = v->undithered_pf;
@@ -1241,7 +1097,7 @@ static GLboolean initialize_visual_and_buffer( int client,
       _mesa_printf("X/Mesa visual = %p\n", (void *) v);
       _mesa_printf("X/Mesa dithered pf = %u\n", v->dithered_pf);
       _mesa_printf("X/Mesa undithered pf = %u\n", v->undithered_pf);
-      _mesa_printf("X/Mesa level = %d\n", v->level);
+      _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
       _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v));
       _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
    }
@@ -1249,31 +1105,14 @@ static GLboolean initialize_visual_and_buffer( int client,
    if (b && window) {
       /* Do window-specific initializations */
 
-      /* Window dimensions */
-      unsigned int w, h;
-      get_drawable_size( v->display, window, &w, &h );
-      b->width = w;
-      b->height = h;
-
-      b->frontbuffer = window;
+      /* these should have been set in create_xmesa_buffer */
+      ASSERT(b->frontxrb->drawable == window);
+      ASSERT(b->frontxrb->pixmap == (XMesaPixmap) window);
 
       /* Setup for single/double buffering */
       if (v->mesa_visual.doubleBufferMode) {
          /* Double buffered */
-#ifndef XFree86Server
          b->shm = check_for_xshm( v->display );
-#endif
-         xmesa_alloc_back_buffer( b );
-         if (b->db_state==BACK_PIXMAP) {
-            b->buffer = (XMesaDrawable)b->backpixmap;
-         }
-         else {
-            b->buffer = XIMAGE;
-         }
-      }
-      else {
-         /* Single Buffered */
-         b->buffer = b->frontbuffer;
       }
 
       /* X11 graphics contexts */
@@ -1299,14 +1138,17 @@ static GLboolean initialize_visual_and_buffer( int client,
 #ifdef XFree86Server
       b->swapgc = CreateScratchGC(v->display, window->depth);
       {
-         CARD32 v[1];
-         v[0] = FALSE;
-         dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
+         CARD32 v[1];
+         v[0] = FALSE;
+         dixChangeGC(NullClient, b->swapgc, GCGraphicsExposures, v, NULL);
       }
 #else
-      gcvalues.graphics_exposures = False;
-      b->swapgc = XCreateGC( v->display, window,
-                              GCGraphicsExposures, &gcvalues);
+      {
+         XGCValues gcvalues;
+         gcvalues.graphics_exposures = False;
+         b->swapgc = XCreateGC(v->display, window,
+                               GCGraphicsExposures, &gcvalues);
+      }
 #endif
       XMesaSetFunction( v->display, b->swapgc, GXcopy );
       /*
@@ -1315,17 +1157,16 @@ static GLboolean initialize_visual_and_buffer( int client,
        * Initialize whole stuff
        * Patch contributed by Jacques Leroy March 8, 1998.
        */
-      if (v->hpcr_clear_flag && b->buffer!=XIMAGE) {
-       int i;
-       for (i=0; i<16; i++)
-        {
-          XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
-          XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
-        }
-        XMesaPutImage(b->display, (XMesaDrawable)v->hpcr_clear_pixmap,
-                     b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
-       XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
-       XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
+      if (v->hpcr_clear_flag && b->backxrb && b->backxrb->pixmap) {
+         int i;
+         for (i = 0; i < 16; i++) {
+            XMesaPutPixel(v->hpcr_clear_ximage, i, 0, 0);
+            XMesaPutPixel(v->hpcr_clear_ximage, i, 1, 0);
+         }
+         XMesaPutImage(b->display, (XMesaDrawable) v->hpcr_clear_pixmap,
+                       b->cleargc, v->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2);
+         XMesaSetFillStyle( v->display, b->cleargc, FillTiled);
+         XMesaSetTile( v->display, b->cleargc, v->hpcr_clear_pixmap );
       }
 
       /* Initialize the row buffer XImage for use in write_color_span() */
@@ -1342,6 +1183,8 @@ static GLboolean initialize_visual_and_buffer( int client,
                                   32,                   /*bitmap_pad*/
                                   0                     /*bytes_per_line*/ );
 #endif
+      if (!b->rowimage)
+         return GL_FALSE;
    }
 
    return GL_TRUE;
@@ -1353,9 +1196,11 @@ static GLboolean initialize_visual_and_buffer( int client,
  * Convert an RGBA color to a pixel value.
  */
 unsigned long
-xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a,
-                      GLuint pixelFormat)
+xmesa_color_to_pixel(GLcontext *ctx,
+                     GLubyte r, GLubyte g, GLubyte b, GLubyte a,
+                     GLuint pixelFormat)
 {
+   XMesaContext xmesa = XMESA_CONTEXT(ctx);
    switch (pixelFormat) {
       case PF_Index:
          return 0;
@@ -1367,6 +1212,8 @@ xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLuby
          }
       case PF_8A8B8G8R:
          return PACK_8A8B8G8R( r, g, b, a );
+      case PF_8A8R8G8B:
+         return PACK_8A8R8G8B( r, g, b, a );
       case PF_8R8G8B:
          /* fall through */
       case PF_8R8G8B24:
@@ -1399,12 +1246,40 @@ xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLuby
             return p;
          }
       default:
-         _mesa_problem(NULL, "Bad pixel format in xmesa_color_to_pixel");
+         _mesa_problem(ctx, "Bad pixel format in xmesa_color_to_pixel");
    }
    return 0;
 }
 
 
+#define NUM_VISUAL_TYPES   6
+
+/**
+ * Convert an X visual type to a GLX visual type.
+ * 
+ * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
+ *        to be converted.
+ * \return If \c visualType is a valid X visual type, a GLX visual type will
+ *         be returned.  Otherwise \c GLX_NONE will be returned.
+ * 
+ * \note
+ * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the
+ * DRI CVS tree.
+ */
+static GLint
+xmesa_convert_from_x_visual_type( int visualType )
+{
+    static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
+       GLX_STATIC_GRAY,  GLX_GRAY_SCALE,
+       GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+       GLX_TRUE_COLOR,   GLX_DIRECT_COLOR
+    };
+
+    return ( (unsigned) visualType < NUM_VISUAL_TYPES )
+       ? glx_visual_types[ visualType ] : GLX_NONE;
+}
+
+
 /**********************************************************************/
 /*****                       Public Functions                     *****/
 /**********************************************************************/
@@ -1430,9 +1305,10 @@ xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLuby
  *         accum_alpha_size - requested bits/alpha accum values, or zero
  *         num_samples - number of samples/pixel if multisampling, or zero
  *         level - visual level, usually 0
- *         visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
+ *         visualCaveat - ala the GLX extension, usually GLX_NONE
  * Return;  a new XMesaVisual or 0 if error.
  */
+PUBLIC
 XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
                                XMesaVisualInfo visinfo,
                                GLboolean rgb_flag,
@@ -1454,59 +1330,37 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
    XMesaVisual v;
    GLint red_bits, green_bits, blue_bits, alpha_bits;
 
+#ifndef XFree86Server
    /* For debugging only */
    if (_mesa_getenv("MESA_XSYNC")) {
       /* This makes debugging X easier.
        * In your debugger, set a breakpoint on _XError to stop when an
        * X protocol error is generated.
        */
-#ifdef XFree86Server
-      /* NOT_NEEDED */
-#else
       XSynchronize( display, 1 );
-#endif
    }
+#endif
 
    v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual);
    if (!v) {
       return NULL;
    }
 
-   /*
-    * In the X server, NULL is passed in for the display.  It will have
-    * to be set before using this visual.  See XMesaSetVisualDisplay()
-    * below.
-    */
    v->display = display;
 
-   /* Save a copy of the XVisualInfo struct because the user may XFREE()
+   /* Save a copy of the XVisualInfo struct because the user may X_mesa_free()
     * the struct but we may need some of the information contained in it
     * at a later time.
     */
-#ifdef XFree86Server
-   v->visinfo = visinfo;
-#else
+#ifndef XFree86Server
    v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
    if(!v->visinfo) {
-      FREE(v);
+      _mesa_free(v);
       return NULL;
    }
    MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
 #endif
 
-#ifdef XFree86Server
-   /* Initialize the depth of the screen */
-   {
-       PixmapFormatRec *format;
-
-       for (format = screenInfo.formats;
-           format->depth != display->rootDepth;
-           format++)
-          ;
-       v->screen_depth = format->bitsPerPixel;
-   }
-#endif
-
    /* check for MESA_GAMMA environment variable */
    gamma = _mesa_getenv("MESA_GAMMA");
    if (gamma) {
@@ -1521,19 +1375,49 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
    }
 
    v->ximage_flag = ximage_flag;
-   v->level = level;
-   v->VisualCaveat = visualCaveat;
+
+#ifdef XFree86Server
+   /* We could calculate these values by ourselves.  nplanes is either the sum
+    * of the red, green, and blue bits or the number index bits.
+    * ColormapEntries is either (1U << index_bits) or
+    * (1U << max(redBits, greenBits, blueBits)).
+    */
+   assert(visinfo->nplanes > 0);
+   v->nplanes = visinfo->nplanes;
+   v->ColormapEntries = visinfo->ColormapEntries;
+
+   v->mesa_visual.redMask = visinfo->redMask;
+   v->mesa_visual.greenMask = visinfo->greenMask;
+   v->mesa_visual.blueMask = visinfo->blueMask;
+   v->mesa_visual.visualID = visinfo->vid;
+   v->mesa_visual.screen = 0; /* FIXME: What should be done here? */
+#else
+   v->mesa_visual.redMask = visinfo->red_mask;
+   v->mesa_visual.greenMask = visinfo->green_mask;
+   v->mesa_visual.blueMask = visinfo->blue_mask;
+   v->mesa_visual.visualID = visinfo->visualid;
+   v->mesa_visual.screen = visinfo->screen;
+#endif
+
+#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus))
+   v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class);
+#else
+   v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class);
+#endif
+
+   v->mesa_visual.visualRating = visualCaveat;
+
+   if (alpha_flag)
+      v->mesa_visual.alphaBits = 8;
 
    (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 );
 
    {
-      int xclass;
-      xclass = GET_VISUAL_CLASS(v);
-      if (xclass==TrueColor || xclass==DirectColor) {
-         red_bits   = bitcount(GET_REDMASK(v));
-         green_bits = bitcount(GET_GREENMASK(v));
-         blue_bits  = bitcount(GET_BLUEMASK(v));
-         alpha_bits = 0;
+      const int xclass = v->mesa_visual.visualType;
+      if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
+         red_bits   = _mesa_bitcount(GET_REDMASK(v));
+         green_bits = _mesa_bitcount(GET_GREENMASK(v));
+         blue_bits  = _mesa_bitcount(GET_BLUEMASK(v));
       }
       else {
          /* this is an approximation */
@@ -1547,79 +1431,72 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
          alpha_bits = 0;
          assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) );
       }
+      alpha_bits = v->mesa_visual.alphaBits;
    }
 
-   if (alpha_flag && alpha_bits == 0)
-      alpha_bits = 8;
-
    _mesa_initialize_visual( &v->mesa_visual,
                             rgb_flag, db_flag, stereo_flag,
                             red_bits, green_bits,
                             blue_bits, alpha_bits,
-                            v->index_bits,
+                            v->mesa_visual.indexBits,
                             depth_size,
                             stencil_size,
                             accum_red_size, accum_green_size,
                             accum_blue_size, accum_alpha_size,
                             0 );
-   return v;
-}
 
-
-void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v )
-{
-    v->display = dpy;
+   /* XXX minor hack */
+   v->mesa_visual.level = level;
+   return v;
 }
 
 
+PUBLIC
 void XMesaDestroyVisual( XMesaVisual v )
 {
 #ifndef XFree86Server
-   FREE(v->visinfo);
+   _mesa_free(v->visinfo);
 #endif
-   FREE(v);
+   _mesa_free(v);
 }
 
 
 
-/*
+/**
  * Create a new XMesaContext.
- * Input:  v - XMesaVisual
- *         share_list - another XMesaContext with which to share display
- *                      lists or NULL if no sharing is wanted.
- * Return:  an XMesaContext or NULL if error.
+ * \param v  the XMesaVisual
+ * \param share_list  another XMesaContext with which to share display
+ *                    lists or NULL if no sharing is wanted.
+ * \return an XMesaContext or NULL if error.
  */
+PUBLIC
 XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
 {
    static GLboolean firstTime = GL_TRUE;
    XMesaContext c;
-   GLboolean direct = GL_TRUE; /* not really */
    GLcontext *mesaCtx;
+   struct dd_function_table functions;
+   TNLcontext *tnl;
 
    if (firstTime) {
       _glthread_INIT_MUTEX(_xmesa_lock);
       firstTime = GL_FALSE;
    }
 
+   /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
    c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
-   if (!c) {
+   if (!c)
       return NULL;
-   }
 
    mesaCtx = &(c->mesa);
 
-   /* Setup these pointers here since they're using for making the default
-    * and proxy texture objects.  Actually, we don't really need to do
-    * this since we're using the default fallback functions which
-    * _mesa_initialize_context() would plug in if needed.
-    */
-   mesaCtx->Driver.NewTextureObject = _mesa_new_texture_object;
-   mesaCtx->Driver.DeleteTexture = _mesa_delete_texture_object;
-
+   /* initialize with default driver functions, then plug in XMesa funcs */
+   _mesa_init_driver_functions(&functions);
+   xmesa_init_driver_functions(v, &functions);
    if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual,
                       share_list ? &(share_list->mesa) : (GLcontext *) NULL,
-                      (void *) c, direct)) {
-      FREE(c);
+                      &functions, (void *) c)) {
+      _mesa_free(c);
       return NULL;
    }
 
@@ -1627,276 +1504,165 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    _mesa_enable_1_3_extensions(mesaCtx);
    _mesa_enable_1_4_extensions(mesaCtx);
    _mesa_enable_1_5_extensions(mesaCtx);
+   _mesa_enable_2_0_extensions(mesaCtx);
+#if ENABLE_EXT_texure_compression_s3tc
+    if (c->Mesa_DXTn) {
+       _mesa_enable_extension(mesaCtx, "GL_EXT_texture_compression_s3tc");
+       _mesa_enable_extension(mesaCtx, "GL_S3_s3tc");
+    }
+    _mesa_enable_extension(mesaCtx, "GL_3DFX_texture_compression_FXT1");
+#endif
+#if ENABLE_EXT_timer_query
+    _mesa_enable_extension(mesaCtx, "GL_EXT_timer_query");
+#endif
 
-   if (CHECK_BYTE_ORDER(v)) {
-      c->swapbytes = GL_FALSE;
-   }
-   else {
-      c->swapbytes = GL_TRUE;
-   }
+#ifdef XFree86Server
+   /* If we're running in the X server, do bounds checking to prevent
+    * segfaults and server crashes!
+    */
+   mesaCtx->Const.CheckArrayBounds = GL_TRUE;
+#endif
 
+   /* finish up xmesa context initializations */
+   c->swapbytes = CHECK_BYTE_ORDER(v) ? GL_FALSE : GL_TRUE;
    c->xm_visual = v;
-   c->xm_draw_buffer = NULL;   /* set later by XMesaMakeCurrent */
-   c->xm_read_buffer = NULL;   /* set later by XMesaMakeCurrent */
    c->xm_buffer = NULL;   /* set later by XMesaMakeCurrent */
    c->display = v->display;
    c->pixelformat = v->dithered_pf;      /* Dithering is enabled by default */
 
-   mesaCtx->Driver.UpdateState = xmesa_update_state;
-
    /* Initialize the software rasterizer and helper modules.
     */
-   _swrast_CreateContext( mesaCtx );
-   _ac_CreateContext( mesaCtx );
-   _tnl_CreateContext( mesaCtx );
-   _swsetup_CreateContext( mesaCtx );
+   if (!_swrast_CreateContext( mesaCtx ) ||
+       !_vbo_CreateContext( mesaCtx ) ||
+       !_tnl_CreateContext( mesaCtx ) ||
+       !_swsetup_CreateContext( mesaCtx )) {
+      _mesa_free_context_data(&c->mesa);
+      _mesa_free(c);
+      return NULL;
+   }
 
+   /* tnl setup */
+   tnl = TNL_CONTEXT(mesaCtx);
+   tnl->Driver.RunPipeline = _tnl_run_pipeline;
+   /* swrast setup */
    xmesa_register_swrast_functions( mesaCtx );
-
-   /* Set up some constant pointers:
-    */
-   xmesa_init_pointers( mesaCtx );
+   _swsetup_Wakeup(mesaCtx);
 
    return c;
 }
 
 
 
-
+PUBLIC
 void XMesaDestroyContext( XMesaContext c )
 {
    GLcontext *mesaCtx = &c->mesa;
-#ifdef FX
-   if (c->xm_draw_buffer && c->xm_buffer->FXctx)
-      fxMesaDestroyContext(c->xm_draw_buffer->FXctx);
-#endif
    _swsetup_DestroyContext( mesaCtx );
    _swrast_DestroyContext( mesaCtx );
    _tnl_DestroyContext( mesaCtx );
-   _ac_DestroyContext( mesaCtx );
+   _vbo_DestroyContext( mesaCtx );
    _mesa_free_context_data( mesaCtx );
    _mesa_free( c );
 }
 
 
 
-/*
- * XXX this isn't a public function!  It's a hack for the 3Dfx driver.
- * Create a new XMesaBuffer from an X window.
- * Input:  v - the XMesaVisual
- *         w - the window
- *         c - the context
- * Return:  new XMesaBuffer or NULL if error
+/**
+ * Private function for creating an XMesaBuffer which corresponds to an
+ * X window or pixmap.
+ * \param v  the window's XMesaVisual
+ * \param w  the window we're wrapping
+ * \return  new XMesaBuffer or NULL if error
  */
-XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v, XMesaWindow w,
-                                      XMesaContext c )
+PUBLIC XMesaBuffer
+XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w)
 {
 #ifndef XFree86Server
    XWindowAttributes attr;
-#endif
-#ifdef FX
-   char *fxEnvVar;
 #endif
    int client = 0;
+   XMesaBuffer b;
+   XMesaColormap cmap;
 
-   XMesaBuffer b = alloc_xmesa_buffer();
-   if (!b) {
-      return NULL;
-   }
-
-   (void) c;
+   assert(v);
+   assert(w);
 
+   /* Check that window depth matches visual depth */
 #ifdef XFree86Server
    client = CLIENT_ID(((XMesaDrawable)w)->id);
-#endif
 
-   assert(v);
-
-#ifdef XFree86Server
    if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) {
+      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
+                    GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth);
+      return NULL;
+   }
 #else
    XGetWindowAttributes( v->display, w, &attr );
 
    if (GET_VISUAL_DEPTH(v) != attr.depth) {
-#endif
-      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual and window!\n");
+      _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n",
+                    GET_VISUAL_DEPTH(v), attr.depth);
       return NULL;
    }
+#endif
 
-   b->xm_visual = v;
-   b->type = WINDOW;
-   b->display = v->display;
+   /* Find colormap */
 #ifdef XFree86Server
-   b->cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
+   cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP);
 #else
    if (attr.colormap) {
-      b->cmap = attr.colormap;
+      cmap = attr.colormap;
    }
    else {
       _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w);
       /* this is weird, a window w/out a colormap!? */
       /* OK, let's just allocate a new one and hope for the best */
-      b->cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
+      cmap = XCreateColormap(v->display, w, attr.visual, AllocNone);
    }
 #endif
 
-   /* determine back buffer implementation */
-   if (v->mesa_visual.doubleBufferMode) {
-      if (v->ximage_flag) {
-        b->db_state = BACK_XIMAGE;
-      }
-      else {
-        b->db_state = BACK_PIXMAP;
-      }
-   }
-   else {
-      b->db_state = 0;
-   }
-
-   _mesa_initialize_framebuffer(&b->mesa_buffer,
-                                &v->mesa_visual,
-                                v->mesa_visual.depthBits > 0,
-                                v->mesa_visual.stencilBits > 0,
-                                v->mesa_visual.accumRedBits > 0,
-                                v->mesa_visual.alphaBits > 0 );
+   b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap);
+   if (!b)
+      return NULL;
 
    if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode,
-                                      (XMesaDrawable)w, b->cmap )) {
-      free_xmesa_buffer(client, b);
+                                      (XMesaDrawable) w, cmap )) {
+      xmesa_free_buffer(b);
       return NULL;
    }
 
-#ifdef FX
-   fxEnvVar = _mesa_getenv("MESA_GLX_FX");
-   if (fxEnvVar) {
-     if (fxEnvVar[0]!='d') {
-       int attribs[100];
-       int numAttribs = 0;
-       int hw;
-       if (v->mesa_visual.depthBits > 0) {
-        attribs[numAttribs++] = FXMESA_DEPTH_SIZE;
-        attribs[numAttribs++] = v->mesa_visual.depthBits;
-       }
-       if (v->mesa_visual.doubleBufferMode) {
-        attribs[numAttribs++] = FXMESA_DOUBLEBUFFER;
-       }
-       if (v->mesa_visual.accumRedBits > 0) {
-        attribs[numAttribs++] = FXMESA_ACCUM_SIZE;
-        attribs[numAttribs++] = v->mesa_visual.accumRedBits;
-       }
-       if (v->mesa_visual.stencilBits > 0) {
-         attribs[numAttribs++] = FXMESA_STENCIL_SIZE;
-         attribs[numAttribs++] = v->mesa_visual.stencilBits;
-       }
-       if (v->mesa_visual.alphaBits > 0) {
-         attribs[numAttribs++] = FXMESA_ALPHA_SIZE;
-         attribs[numAttribs++] = v->mesa_visual.alphaBits;
-       }
-       if (1) {
-         attribs[numAttribs++] = FXMESA_SHARE_CONTEXT;
-         attribs[numAttribs++] = (int) &(c->mesa);
-       }
-       attribs[numAttribs++] = FXMESA_NONE;
-
-       /* [dBorca] need to revise this ASAP!!! */
-       /*if ((hw = fxQueryHardware())==GR_SSTTYPE_VOODOO) {
-         b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
-         if ((v->undithered_pf!=PF_Index) && (b->backimage)) {
-          b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE;
-          if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
-            b->FXwindowHack = b->FXctx ? GL_TRUE : GL_FALSE;
-          else
-            b->FXwindowHack = GL_FALSE;
-         }
-       }
-       else */{
-         if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')
-          b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE,
-                                         GR_REFRESH_75Hz, attribs);
-         else
-          b->FXctx = fxMesaCreateBestContext(0, b->width, b->height, attribs);
-         b->FXisHackUsable = GL_FALSE;
-         b->FXwindowHack = GL_FALSE;
-       }
-       /*
-       fprintf(stderr,
-               "voodoo %d, wid %d height %d hack: usable %d active %d\n",
-               hw, b->width, b->height, b->FXisHackUsable, b->FXwindowHack);
-       */
-     }
-   }
-   else {
-      _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n");
-      _mesa_warning(NULL, "         you have not defined the MESA_GLX_FX env. var.\n");
-      _mesa_warning(NULL, "         (check the README.3DFX file for more information).\n\n");
-      _mesa_warning(NULL, "         you can disable this message with a 'export MESA_GLX_FX=disable'.\n");
-   }
-#endif
-
    return b;
 }
 
 
-XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w )
-{
-   return XMesaCreateWindowBuffer2( v, w, NULL );
-}
-
-
-/*
+/**
  * Create a new XMesaBuffer from an X pixmap.
- * Input:  v - the XMesaVisual
- *         p - the pixmap
- *         cmap - the colormap, may be 0 if using a TrueColor or DirectColor
- *                visual for the pixmap
- * Return:  new XMesaBuffer or NULL if error
+ *
+ * \param v    the XMesaVisual
+ * \param p    the pixmap
+ * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or
+ *             \c GLX_DIRECT_COLOR visual for the pixmap
+ * \returns new XMesaBuffer or NULL if error
  */
-XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
-                                    XMesaPixmap p, XMesaColormap cmap )
+PUBLIC XMesaBuffer
+XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap)
 {
    int client = 0;
-   XMesaBuffer b = alloc_xmesa_buffer();
-   if (!b) {
-      return NULL;
-   }
+   XMesaBuffer b;
 
+   assert(v);
+
+   b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap);
+   if (!b)
+      return NULL;
 
 #ifdef XFree86Server
    client = CLIENT_ID(((XMesaDrawable)p)->id);
 #endif
 
-   assert(v);
-
-   b->xm_visual = v;
-   b->type = PIXMAP;
-   b->display = v->display;
-   b->cmap = cmap;
-
-   /* determine back buffer implementation */
-   if (v->mesa_visual.doubleBufferMode) {
-      if (v->ximage_flag) {
-        b->db_state = BACK_XIMAGE;
-      }
-      else {
-        b->db_state = BACK_PIXMAP;
-      }
-   }
-   else {
-      b->db_state = 0;
-   }
-
-   _mesa_initialize_framebuffer(&b->mesa_buffer,
-                                &v->mesa_visual,
-                                v->mesa_visual.depthBits > 0,
-                                v->mesa_visual.stencilBits > 0,
-                                v->mesa_visual.accumRedBits +
-                                v->mesa_visual.accumGreenBits +
-                                v->mesa_visual.accumBlueBits > 0,
-                                v->mesa_visual.alphaBits > 0 );
-
    if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
-                                    (XMesaDrawable)p, cmap)) {
-      free_xmesa_buffer(client, b);
+                                    (XMesaDrawable) p, cmap)) {
+      xmesa_free_buffer(b);
       return NULL;
    }
 
@@ -1905,8 +1671,9 @@ XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
 
 
 
-XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
-                                unsigned int width, unsigned int height )
+XMesaBuffer
+XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
+                   unsigned int width, unsigned int height)
 {
 #ifdef XFree86Server
    return 0;
@@ -1914,45 +1681,22 @@ XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
    int client = 0;
    XMesaWindow root;
    XMesaDrawable drawable;  /* X Pixmap Drawable */
-   XMesaBuffer b = alloc_xmesa_buffer();
-   if (!b) {
-      return NULL;
-   }
-
-   b->xm_visual = v;
-   b->type = PBUFFER;
-   b->display = v->display;
-   b->cmap = cmap;
+   XMesaBuffer b;
 
    /* allocate pixmap for front buffer */
    root = RootWindow( v->display, v->visinfo->screen );
-   drawable = XCreatePixmap( v->display, root, width, height, v->visinfo->depth );
-
-   /* determine back buffer implementation */
-   if (v->mesa_visual.doubleBufferMode) {
-      if (v->ximage_flag) {
-        b->db_state = BACK_XIMAGE;
-      }
-      else {
-        b->db_state = BACK_PIXMAP;
-      }
-   }
-   else {
-      b->db_state = 0;
-   }
+   drawable = XCreatePixmap(v->display, root, width, height,
+                            v->visinfo->depth);
+   if (!drawable)
+      return NULL;
 
-   _mesa_initialize_framebuffer(&b->mesa_buffer,
-                                &v->mesa_visual,
-                                v->mesa_visual.depthBits > 0,
-                                v->mesa_visual.stencilBits > 0,
-                                v->mesa_visual.accumRedBits +
-                                v->mesa_visual.accumGreenBits +
-                                v->mesa_visual.accumBlueBits > 0,
-                                v->mesa_visual.alphaBits > 0 );
+   b = create_xmesa_buffer(drawable, PBUFFER, v, cmap);
+   if (!b)
+      return NULL;
 
    if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode,
                                     drawable, cmap)) {
-      free_xmesa_buffer(client, b);
+      xmesa_free_buffer(b);
       return NULL;
    }
 
@@ -1965,49 +1709,37 @@ XMesaBuffer XMesaCreatePBuffer( XMesaVisual v, XMesaColormap cmap,
 /*
  * Deallocate an XMesaBuffer structure and all related info.
  */
-void XMesaDestroyBuffer( XMesaBuffer b )
+PUBLIC void
+XMesaDestroyBuffer(XMesaBuffer b)
 {
-   int client = 0;
-
-#ifdef XFree86Server
-   if (b->frontbuffer)
-       client = CLIENT_ID(b->frontbuffer->id);
-#endif
-
-   if (b->gc)  XMesaFreeGC( b->xm_visual->display, b->gc );
-   if (b->cleargc)  XMesaFreeGC( b->xm_visual->display, b->cleargc );
-   if (b->swapgc)  XMesaFreeGC( b->xm_visual->display, b->swapgc );
+   xmesa_free_buffer(b);
+}
 
-   if (b->backimage) {
-#if defined(USE_XSHM) && !defined(XFree86Server)
-       if (b->shm) {
-          XShmDetach( b->xm_visual->display, &b->shminfo );
-          XDestroyImage( b->backimage );
-          shmdt( b->shminfo.shmaddr );
-       }
-       else
-#endif
-          XMesaDestroyImage( b->backimage );
-   }
-   if (b->backpixmap) {
-      XMesaFreePixmap( b->xm_visual->display, b->backpixmap );
-      if (b->xm_visual->hpcr_clear_flag) {
-       XMesaFreePixmap( b->xm_visual->display,
-                        b->xm_visual->hpcr_clear_pixmap );
-       XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage );
-      }
-   }
-   if (b->rowimage) {
-      FREE( b->rowimage->data );
-      b->rowimage->data = NULL;
-      XMesaDestroyImage( b->rowimage );
-   }
 
-   free_xmesa_buffer(client, b);
+/**
+ * Query the current window size and update the corresponding GLframebuffer
+ * and all attached renderbuffers.
+ * Called when:
+ *  1. the first time a buffer is bound to a context.
+ *  2. from glViewport to poll for window size changes
+ *  3. from the XMesaResizeBuffers() API function.
+ * Note: it's possible (and legal) for xmctx to be NULL.  That can happen
+ * when resizing a buffer when no rendering context is bound.
+ */
+void
+xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+{
+   GLuint width, height;
+   xmesa_get_window_size(drawBuffer->display, drawBuffer, &width, &height);
+   if (drawBuffer->mesa_buffer.Width != width ||
+       drawBuffer->mesa_buffer.Height != height) {
+      GLcontext *ctx = xmctx ? &xmctx->mesa : NULL;
+      _mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height);
+   }
+   drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */
 }
 
 
-
 /*
  * Bind buffer b to context c and make c the current rendering context.
  */
@@ -2020,6 +1752,7 @@ GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b )
 /*
  * Bind buffer b to context c and make c the current rendering context.
  */
+PUBLIC
 GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
                              XMesaBuffer readBuffer )
 {
@@ -2027,60 +1760,49 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
       if (!drawBuffer || !readBuffer)
          return GL_FALSE;  /* must specify buffers! */
 
-#ifdef FX
-      if (drawBuffer->FXctx) {
-         fxMesaMakeCurrent(drawBuffer->FXctx);
-
-         c->xm_draw_buffer = drawBuffer;
-         c->xm_read_buffer = readBuffer;
-         c->xm_buffer = drawBuffer;
-
-         return GL_TRUE;
-      }
-#endif
       if (&(c->mesa) == _mesa_get_current_context()
-          && c->xm_draw_buffer == drawBuffer
-          && c->xm_read_buffer == readBuffer
-          && c->xm_draw_buffer->wasCurrent) {
+          && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer
+          && c->mesa.ReadBuffer == &readBuffer->mesa_buffer
+          && XMESA_BUFFER(c->mesa.DrawBuffer)->wasCurrent) {
          /* same context and buffer, do nothing */
          return GL_TRUE;
       }
 
-      c->xm_draw_buffer = drawBuffer;
-      c->xm_read_buffer = readBuffer;
       c->xm_buffer = drawBuffer;
 
-      _mesa_make_current2(&(c->mesa),
-                          &drawBuffer->mesa_buffer,
-                          &readBuffer->mesa_buffer);
+      /* Call this periodically to detect when the user has begun using
+       * GL rendering from multiple threads.
+       */
+      _glapi_check_multithread();
+
+      xmesa_check_and_update_buffer_size(c, drawBuffer);
+      if (readBuffer != drawBuffer)
+         xmesa_check_and_update_buffer_size(c, readBuffer);
 
-      if (c->mesa.Viewport.Width == 0) {
-        /* initialize viewport to window size */
-        _mesa_Viewport( 0, 0, drawBuffer->width, drawBuffer->height );
-        c->mesa.Scissor.Width = drawBuffer->width;
-        c->mesa.Scissor.Height = drawBuffer->height;
-      }
+      _mesa_make_current(&(c->mesa),
+                         &drawBuffer->mesa_buffer,
+                         &readBuffer->mesa_buffer);
 
       if (c->xm_visual->mesa_visual.rgbMode) {
          /*
           * Must recompute and set these pixel values because colormap
           * can be different for different windows.
           */
-         c->clearpixel = xmesa_color_to_pixel( c,
+         c->clearpixel = xmesa_color_to_pixel( &c->mesa,
                                                c->clearcolor[0],
                                                c->clearcolor[1],
                                                c->clearcolor[2],
                                                c->clearcolor[3],
                                                c->xm_visual->undithered_pf);
-         XMesaSetForeground(c->display, c->xm_draw_buffer->cleargc, c->clearpixel);
+         XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel);
       }
 
       /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
-      c->xm_draw_buffer->wasCurrent = GL_TRUE;
+      drawBuffer->wasCurrent = GL_TRUE;
    }
    else {
       /* Detach */
-      _mesa_make_current2( NULL, NULL, NULL );
+      _mesa_make_current( NULL, NULL, NULL );
    }
    return GL_TRUE;
 }
@@ -2113,8 +1835,8 @@ XMesaBuffer XMesaGetCurrentBuffer( void )
 {
    GET_CURRENT_CONTEXT(ctx);
    if (ctx) {
-      XMesaContext xmesa = XMESA_CONTEXT(ctx);
-      return xmesa->xm_draw_buffer;
+      XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+      return xmbuf;
    }
    else {
       return 0;
@@ -2127,8 +1849,7 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
 {
    GET_CURRENT_CONTEXT(ctx);
    if (ctx) {
-      XMesaContext xmesa = XMESA_CONTEXT(ctx);
-      return xmesa->xm_read_buffer;
+      return XMESA_BUFFER(ctx->ReadBuffer);
    }
    else {
       return 0;
@@ -2136,225 +1857,114 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void )
 }
 
 
+#ifdef XFree86Server
+PUBLIC
 GLboolean XMesaForceCurrent(XMesaContext c)
 {
    if (c) {
+#ifdef XGLServer
+      _glapi_set_dispatch(c->mesa.CurrentDispatch);
+#endif
+
       if (&(c->mesa) != _mesa_get_current_context()) {
-        _mesa_make_current(&(c->mesa), &c->xm_draw_buffer->mesa_buffer);
+        _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer);
       }
    }
    else {
-      _mesa_make_current(NULL, NULL);
+      _mesa_make_current(NULL, NULL, NULL);
    }
    return GL_TRUE;
 }
 
 
+PUBLIC
 GLboolean XMesaLoseCurrent(XMesaContext c)
 {
    (void) c;
-   _mesa_make_current(NULL, NULL);
+   _mesa_make_current(NULL, NULL, NULL);
    return GL_TRUE;
 }
 
 
+PUBLIC
+GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask )
+{
+   _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
+   return GL_TRUE;
+}
+#endif /* XFree86Server */
+
+
 /*
  * Switch 3Dfx support hack between window and full-screen mode.
  */
 GLboolean XMesaSetFXmode( GLint mode )
 {
-#ifdef FX
-   const char *fx = _mesa_getenv("MESA_GLX_FX");
-   if (fx && fx[0] != 'd') {
-      GET_CURRENT_CONTEXT(ctx);
-      GrHwConfiguration hw;
-      if (!FX_grSstQueryHardware(&hw)) {
-         /*fprintf(stderr, "!grSstQueryHardware\n");*/
-         return GL_FALSE;
-      }
-      if (hw.num_sst < 1) {
-         /*fprintf(stderr, "hw.num_sst < 1\n");*/
-         return GL_FALSE;
-      }
-      if (ctx) {
-         XMesaContext xmesa = XMESA_CONTEXT(ctx);
-         if (mode == XMESA_FX_WINDOW) {
-           if (xmesa->xm_draw_buffer->FXisHackUsable) {
-              FX_grSstControl(GR_CONTROL_DEACTIVATE);
-              xmesa->xm_draw_buffer->FXwindowHack = GL_TRUE;
-              return GL_TRUE;
-           }
-        }
-        else if (mode == XMESA_FX_FULLSCREEN) {
-           FX_grSstControl(GR_CONTROL_ACTIVATE);
-           xmesa->xm_draw_buffer->FXwindowHack = GL_FALSE;
-           return GL_TRUE;
-        }
-        else {
-           /* Error: Bad mode value */
-        }
-      }
-   }
-   /*fprintf(stderr, "fallthrough\n");*/
-#else
    (void) mode;
-#endif
    return GL_FALSE;
 }
 
 
 
-#ifdef FX
-/*
- * Read image from VooDoo frame buffer into X/Mesa's back XImage.
- */
-static void FXgetImage( XMesaBuffer b )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   static unsigned short pixbuf[MAX_WIDTH];
-   GLuint x, y;
-   int xpos, ypos;
-   XMesaWindow root;
-   unsigned int bw, depth, width, height;
-   XMesaContext xmesa = XMESA_CONTEXT(ctx);
-
-#ifdef XFree86Server
-   x = b->frontbuffer->x;
-   y = b->frontbuffer->y;
-   width = b->frontbuffer->width;
-   height = b->frontbuffer->height;
-   depth = b->frontbuffer->depth;
-#else
-   XGetGeometry( b->xm_visual->display, b->frontbuffer,
-                 &root, &xpos, &ypos, &width, &height, &bw, &depth);
-#endif
-   if (b->width != width || b->height != height) {
-      b->width = MIN2((int)width, b->FXctx->width);
-      b->height = MIN2((int)height, b->FXctx->height);
-      if (b->width & 1)
-         b->width--;  /* prevent odd width */
-      xmesa_alloc_back_buffer( b );
-   }
-
-   grLfbWriteColorFormat(GR_COLORFORMAT_ARGB);
-   if (b->xm_visual->undithered_pf==PF_5R6G5B) {
-      /* Special case: 16bpp RGB */
-      grLfbReadRegion( GR_BUFFER_FRONTBUFFER,       /* src buffer */
-                       0, b->FXctx->height - b->height,  /*pos*/
-                       b->width, b->height,         /* size */
-                       b->width * sizeof(GLushort), /* stride */
-                       b->backimage->data);         /* dest buffer */
-   }
-   else if (b->xm_visual->dithered_pf==PF_Dither
-           && GET_VISUAL_DEPTH(b->xm_visual)==8) {
-      /* Special case: 8bpp RGB */
-      for (y=0;y<b->height;y++) {
-         GLubyte *ptr = (GLubyte*) b->backimage->data
-                        + b->backimage->bytes_per_line * y;
-         XDITHER_SETUP(y);
-
-         /* read row from 3Dfx frame buffer */
-         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
-                          0, b->FXctx->height-(b->height-y),
-                          b->width, 1,
-                          0,
-                          pixbuf );
-
-         /* write to XImage back buffer */
-         for (x=0;x<b->width;x++) {
-            GLubyte r = (pixbuf[x] & 0xf800) >> 8;
-            GLubyte g = (pixbuf[x] & 0x07e0) >> 3;
-            GLubyte b = (pixbuf[x] & 0x001f) << 3;
-            *ptr++ = XDITHER( x, r, g, b);
-         }
-      }
-   }
-   else {
-      /* General case: slow! */
-      for (y=0;y<b->height;y++) {
-         /* read row from 3Dfx frame buffer */
-         grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
-                          0, b->FXctx->height-(b->height-y),
-                          b->width, 1,
-                          0,
-                          pixbuf );
-
-         /* write to XImage back buffer */
-         for (x=0;x<b->width;x++) {
-            XMesaPutPixel(b->backimage,x,y,
-                         xmesa_color_to_pixel(xmesa,
-                                              (pixbuf[x] & 0xf800) >> 8,
-                                              (pixbuf[x] & 0x07e0) >> 3,
-                                              (pixbuf[x] & 0x001f) << 3,
-                                              0xff,
-                                               b->xm_visual->undithered_pf));
-         }
-      }
-   }
-   grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
-}
-#endif
-
-
 /*
  * Copy the back buffer to the front buffer.  If there's no back buffer
  * this is a no-op.
  */
+PUBLIC
 void XMesaSwapBuffers( XMesaBuffer b )
 {
    GET_CURRENT_CONTEXT(ctx);
 
+   if (!b->backxrb) {
+      /* single buffered */
+      return;
+   }
+
    /* If we're swapping the buffer associated with the current context
     * we have to flush any pending rendering commands first.
     */
    if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
       _mesa_notifySwapBuffers(ctx);
 
-   if (b->db_state) {
-#ifdef FX
-      if (b->FXctx) {
-         fxMesaSwapBuffers();
-
-         if (b->FXwindowHack)
-            FXgetImage(b);
-         else
-            return;
-      }
-#endif
-     if (b->backimage) {
-        /* Copy Ximage from host's memory to server's window */
+   if (b->db_mode) {
+     if (b->backxrb->ximage) {
+        /* Copy Ximage (back buf) from client memory to server window */
 #if defined(USE_XSHM) && !defined(XFree86Server)
         if (b->shm) {
             /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
-           XShmPutImage( b->xm_visual->display, b->frontbuffer,
+           XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
                          b->swapgc,
-                         b->backimage, 0, 0,
-                         0, 0, b->width, b->height, False );
+                         b->backxrb->ximage, 0, 0,
+                         0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
+                          False );
             /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
         }
         else
 #endif
          {
             /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
-            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
+            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
                           b->swapgc,
-                          b->backimage, 0, 0,
-                          0, 0, b->width, b->height );
+                          b->backxrb->ximage, 0, 0,
+                          0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height );
             /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
          }
       }
-      else {
-        /* Copy pixmap to window on server */
+      else if (b->backxrb->pixmap) {
+        /* Copy pixmap (back buf) to window (front buf) on server */
          /*_glthread_LOCK_MUTEX(_xmesa_lock);*/
         XMesaCopyArea( b->xm_visual->display,
-                       b->backpixmap,   /* source drawable */
-                       b->frontbuffer,  /* dest. drawable */
+                       b->backxrb->pixmap,   /* source drawable */
+                       b->frontxrb->drawable,  /* dest. drawable */
                        b->swapgc,
-                       0, 0, b->width, b->height,  /* source region */
+                       0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height,
                        0, 0                 /* dest region */
                      );
          /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/
       }
+
+      if (b->swAlpha)
+         _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer);
    }
 #if !defined(XFree86Server)
    XSync( b->xm_visual->display, False );
@@ -2376,25 +1986,21 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
    if (ctx && ctx->DrawBuffer == &(b->mesa_buffer))
       _mesa_notifySwapBuffers(ctx);
 
-   if (b->db_state) {
-      int yTop = b->height - y - height;
-#ifdef FX
-      if (b->FXctx) {
-         fxMesaSwapBuffers();
-         if (b->FXwindowHack)
-            FXgetImage(b);
-         else
-            return;
-      }
-#endif
-      if (b->backimage) {
+   if (!b->backxrb) {
+      /* single buffered */
+      return; 
+   }
+
+   if (b->db_mode) {
+      int yTop = b->mesa_buffer.Height - y - height;
+      if (b->backxrb->ximage) {
          /* Copy Ximage from host's memory to server's window */
 #if defined(USE_XSHM) && !defined(XFree86Server)
          if (b->shm) {
             /* XXX assuming width and height aren't too large! */
-            XShmPutImage( b->xm_visual->display, b->frontbuffer,
+            XShmPutImage( b->xm_visual->display, b->frontxrb->drawable,
                           b->swapgc,
-                          b->backimage, x, yTop,
+                          b->backxrb->ximage, x, yTop,
                           x, yTop, width, height, False );
             /* wait for finished event??? */
          }
@@ -2402,17 +2008,17 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
 #endif
          {
             /* XXX assuming width and height aren't too large! */
-            XMesaPutImage( b->xm_visual->display, b->frontbuffer,
+            XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable,
                           b->swapgc,
-                          b->backimage, x, yTop,
+                          b->backxrb->ximage, x, yTop,
                           x, yTop, width, height );
          }
       }
       else {
          /* Copy pixmap to window on server */
          XMesaCopyArea( b->xm_visual->display,
-                       b->backpixmap,           /* source drawable */
-                       b->frontbuffer,          /* dest. drawable */
+                       b->backxrb->pixmap,           /* source drawable */
+                       b->frontxrb->drawable,        /* dest. drawable */
                        b->swapgc,
                        x, yTop, width, height,  /* source region */
                        x, yTop                  /* dest region */
@@ -2431,13 +2037,16 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
  * Return:  GL_TRUE = context is double buffered
  *          GL_FALSE = context is single buffered
  */
+#ifndef XFree86Server
 GLboolean XMesaGetBackBuffer( XMesaBuffer b,
                               XMesaPixmap *pixmap,
                               XMesaImage **ximage )
 {
-   if (b->db_state) {
-      if (pixmap)  *pixmap = b->backpixmap;
-      if (ximage)  *ximage = b->backimage;
+   if (b->db_mode) {
+      if (pixmap)
+         *pixmap = b->backxrb->pixmap;
+      if (ximage)
+         *ximage = b->backxrb->ximage;
       return GL_TRUE;
    }
    else {
@@ -2446,6 +2055,7 @@ GLboolean XMesaGetBackBuffer( XMesaBuffer b,
       return GL_FALSE;
    }
 }
+#endif /* XFree86Server */
 
 
 /*
@@ -2459,7 +2069,9 @@ GLboolean XMesaGetBackBuffer( XMesaBuffer b,
 GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
                                GLint *bytesPerValue, void **buffer )
 {
-   if (!b->mesa_buffer.DepthBuffer) {
+   struct gl_renderbuffer *rb
+      = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer;
+   if (!rb || !rb->Data) {
       *width = 0;
       *height = 0;
       *bytesPerValue = 0;
@@ -2469,8 +2081,9 @@ GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height,
    else {
       *width = b->mesa_buffer.Width;
       *height = b->mesa_buffer.Height;
-      *bytesPerValue = sizeof(GLdepth);
-      *buffer = b->mesa_buffer.DepthBuffer;
+      *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16
+         ? sizeof(GLushort) : sizeof(GLuint);
+      *buffer = rb->Data;
       return GL_TRUE;
    }
 }
@@ -2509,7 +2122,7 @@ XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
 {
    XMesaBuffer b;
    for (b=XMesaBufferList; b; b=b->Next) {
-      if (b->frontbuffer==d && b->display==dpy) {
+      if (b->frontxrb->drawable == d && b->display == dpy) {
          return b;
       }
    }
@@ -2517,6 +2130,20 @@ XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d )
 }
 
 
+/**
+ * Free/destroy all XMesaBuffers associated with given display.
+ */
+void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy)
+{
+   XMesaBuffer b, next;
+   for (b = XMesaBufferList; b; b = next) {
+      next = b->Next;
+      if (b->display == dpy) {
+         xmesa_free_buffer(b);
+      }
+   }
+}
+
 
 /*
  * Look for XMesaBuffers whose X window has been destroyed.
@@ -2527,12 +2154,12 @@ void XMesaGarbageCollect( void )
    XMesaBuffer b, next;
    for (b=XMesaBufferList; b; b=next) {
       next = b->Next;
-      if (b->display && b->frontbuffer && b->type == WINDOW) {
+      if (b->display && b->frontxrb->drawable && b->type == WINDOW) {
 #ifdef XFree86Server
         /* NOT_NEEDED */
 #else
          XSync(b->display, False);
-         if (!window_exists( b->display, b->frontbuffer )) {
+         if (!window_exists( b->display, b->frontxrb->drawable )) {
             /* found a dead window, free the ancillary info */
             XMesaDestroyBuffer( b );
          }
@@ -2542,19 +2169,11 @@ void XMesaGarbageCollect( void )
 }
 
 
-void XMesaReset( void )
-{
-    while (XMesaBufferList)
-       XMesaDestroyBuffer(XMesaBufferList);
-
-    XMesaBufferList = NULL;
-}
-
-
 unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
                                 GLfloat red, GLfloat green,
                                 GLfloat blue, GLfloat alpha )
 {
+   GLcontext *ctx = &xmesa->mesa;
    GLint r = (GLint) (red   * 255.0F);
    GLint g = (GLint) (green * 255.0F);
    GLint b = (GLint) (blue  * 255.0F);
@@ -2571,6 +2190,8 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
          }
       case PF_8A8B8G8R:
          return PACK_8A8B8G8R( r, g, b, a );
+      case PF_8A8R8G8B:
+         return PACK_8A8R8G8B( r, g, b, a );
       case PF_8R8G8B:
          return PACK_8R8G8B( r, g, b );
       case PF_5R6G5B:
@@ -2611,9 +2232,13 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y,
  * This is typically called when the window size changes and we need
  * to reallocate the buffer's back/depth/stencil/accum buffers.
  */
-void XMesaResizeBuffers( XMesaBuffer b )
+PUBLIC void
+XMesaResizeBuffers( XMesaBuffer b )
 {
-   xmesa_resize_buffers( &(b->mesa_buffer) );
-
+   GET_CURRENT_CONTEXT(ctx);
+   XMesaContext xmctx = XMESA_CONTEXT(ctx);
+   if (!xmctx)
+      return;
+   xmesa_check_and_update_buffer_size(xmctx, b);
 }