Remove XIDs from DRI interface (see #5714).
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 8d24e31..a1a2940 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -48,16 +48,16 @@
  * side library and the DRI (direct rendering infrastructure).
  */
 /*@{*/
-typedef struct __DRIdisplayRec  __DRIdisplay;
-typedef struct __DRIscreenRec   __DRIscreen;
-typedef struct __DRIcontextRec  __DRIcontext;
-typedef struct __DRIdrawableRec __DRIdrawable;
-typedef struct __DRIdriverRec   __DRIdriver;
-typedef struct __DRIframebufferRec __DRIframebuffer;
-typedef struct __DRIversionRec     __DRIversion;
-typedef struct __DRIinterfaceMethodsRec  __DRIinterfaceMethods;
-typedef unsigned long __DRIid;
-typedef void __DRInativeDisplay;
+typedef struct __DRIdisplayRec		__DRIdisplay;
+typedef struct __DRIscreenRec		__DRIscreen;
+typedef struct __DRIcontextRec		__DRIcontext;
+typedef struct __DRIdrawableRec		__DRIdrawable;
+typedef struct __DRIdriverRec		__DRIdriver;
+typedef struct __DRIframebufferRec	__DRIframebuffer;
+typedef struct __DRIversionRec		__DRIversion;
+typedef struct __DRIinterfaceMethodsRec	__DRIinterfaceMethods;
+typedef unsigned long			__DRIid;
+typedef void				__DRInativeDisplay;
 /*@}*/
 
 
@@ -106,7 +106,7 @@
     const __DRIinterfaceMethods * interface,
     __GLcontextModes ** driver_modes);
 typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
-extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
+extern CREATENEWSCREENFUNC __driCreateNewScreen_20070105;
 
 
 /**
@@ -170,16 +170,6 @@
      * the wire protocol (e.g., EGL) will implement glorified no-op functions.
      */
     /*@{*/
-    /**
-     * Determine if the specified window ID still exists.
-     * 
-     * \note
-     * Implementations may assume that the driver will only pass an ID into
-     * this function that actually corresponds to a window.  On
-     * implementations where windows can only be destroyed by the DRI driver
-     * (e.g., EGL), this function is allowed to always return \c GL_TRUE.
-     */
-    GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
 
     /**
      * Create the server-side portion of the GL context.
@@ -307,12 +297,6 @@
 			       int renderType, const int *attrs);
 
     /**
-     * Method to return a pointer to the DRI drawable data.
-     */
-    __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
-				  void *drawablePrivate);
-
-    /**
      * Opaque pointer to private per screen direct rendering data.  \c NULL
      * if direct rendering is not supported on this screen.  Never
      * dereferenced in libGL.
@@ -393,27 +377,22 @@
     void *private;
 
     /**
-     * Pointer to the mode used to create this context.
-     *
-     * \since Internal API version 20040317.
-     */
-    const __GLcontextModes * mode;
-
-    /**
      * Method to bind a DRI drawable to a DRI graphics context.
      *
      * \since Internal API version 20050727.
      */
-    GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
-			 __DRIid read, __DRIcontext *ctx);
+    GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn,
+			     __DRIdrawable *pdraw,
+			     __DRIdrawable *pread,
+			     __DRIcontext *ctx);
 
     /**
      * Method to unbind a DRI drawable from a DRI graphics context.
      *
      * \since Internal API version 20050727.
      */
-    GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
-			   __DRIid read, __DRIcontext *ctx);
+    GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn,
+			       __DRIcontext *ctx);
 };
 
 /**
diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c
index 8909a04..721bb3e 100644
--- a/src/glx/x11/XF86dri.c
+++ b/src/glx/x11/XF86dri.c
@@ -427,16 +427,37 @@
     return True;
 }
 
+static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+    return 0;
+}
+
 PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
     __DRIid drawable )
 {
     Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIDestroyDrawableReq *req;
+    int (*oldXErrorHandler)(Display *, XErrorEvent *);
 
     TRACE("DestroyDrawable...");
     XF86DRICheckExtension (dpy, info, False);
 
+    /* This is called from the DRI driver, which used call it like this
+     *
+     *   if (windowExists(drawable))
+     *     destroyDrawable(drawable);
+     *
+     * which is a textbook race condition - the window may disappear
+     * from the server between checking for its existance and
+     * destroying it.  Instead we change the semantics of
+     * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
+     * the windows is gone, by wrapping the destroy call in an error
+     * handler. */
+
+    XSync(dpy, GL_FALSE);
+    oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
+
     LockDisplay(dpy);
     GetReq(XF86DRIDestroyDrawable, req);
     req->reqType = info->codes->major_opcode;
@@ -445,6 +466,9 @@
     req->drawable = drawable;
     UnlockDisplay(dpy);
     SyncHandle();
+
+    XSetErrorHandler(oldXErrorHandler);
+
     TRACE("DestroyDrawable... return True");
     return True;
 }
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 5cf9923..d68adda 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -171,7 +171,7 @@
  * \todo
  * Create a macro or something so that this is automatically updated.
  */
-static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
+static const char createNewScreenName[] = "__driCreateNewScreen_20070105";
 
 
 /**
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 477566c..3dbdc30 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -60,6 +60,7 @@
 #include "GL/internal/glcore.h"
 #include "glapitable.h"
 #include "glxextensions.h"
+#include "glxhash.h"
 #if defined( USE_XTHREADS )
 # include <X11/Xthreads.h>
 #elif defined( PTHREADS )
@@ -349,6 +350,11 @@
      * Per context direct rendering interface functions and data.
      */
     __DRIcontext driContext;
+
+    /**
+     * Pointer to the mode used to create this context.
+     */
+    const __GLcontextModes * mode;
 #endif
     
     /**
@@ -456,6 +462,7 @@
      * Per screen direct rendering interface functions and data.
      */
     __DRIscreen driScreen;
+    __glxHashTable *drawHash;
 #endif
 
     /**
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index f52b71f..0951493 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -61,41 +61,92 @@
 
 
 /****************************************************************************/
+
+#ifdef GLX_DIRECT_RENDERING
+
+static Bool windowExistsFlag;
+static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+    if (xerr->error_code == BadWindow) {
+	windowExistsFlag = GL_FALSE;
+    }
+    return 0;
+}
+
+/**
+ * Find drawables in the local hash that have been destroyed on the
+ * server.
+ * 
+ * \param dpy    Display to destroy drawables for
+ * \param screen Screen number to destroy drawables for
+ */
+static void GarbageCollectDRIDrawables(Display *dpy, int screen)
+{
+    __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+    __GLXscreenConfigs *sc;
+    __DRIid draw;
+    __DRIdrawable *pdraw;
+    XWindowAttributes xwa;
+    int (*oldXErrorHandler)(Display *, XErrorEvent *);
+
+    if (priv == NULL || priv->driDisplay.private == NULL)
+	return;
+
+    /* Set no-op error handler so Xlib doesn't bail out if the windows
+     * has alreay been destroyed on the server. */
+    XSync(dpy, GL_FALSE);
+    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
+
+    sc = &priv->screenConfigs[screen];
+    if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {
+	do {
+	    windowExistsFlag = GL_TRUE;
+	    XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
+	    if (!windowExistsFlag) {
+		/* Destroy the local drawable data, if the drawable no
+		   longer exists in the Xserver */
+		(*pdraw->destroyDrawable)(dpy, pdraw->private);
+		Xfree(pdraw);
+	    }
+	} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
+    }
+
+    XSetErrorHandler(oldXErrorHandler);
+}
+
 /**
  * Get the __DRIdrawable for the drawable associated with a GLXContext
  * 
  * \param dpy       The display associated with \c drawable.
  * \param drawable  GLXDrawable whose __DRIdrawable part is to be retrieved.
+ * \param scrn_num  If non-NULL, the drawables screen is stored there
  * \returns  A pointer to the context's __DRIdrawable on success, or NULL if
  *           the drawable is not associated with a direct-rendering context.
  */
-
-#ifdef GLX_DIRECT_RENDERING
 static __DRIdrawable *
 GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num )
 {
     __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+    __DRIdrawable * const pdraw;
+    const unsigned  screen_count = ScreenCount(dpy);
+    unsigned   i;
+    __GLXscreenConfigs *sc;
 
-    if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) {
-	const unsigned  screen_count = ScreenCount(dpy);
-	unsigned   i;
-
-	for ( i = 0 ; i < screen_count ; i++ ) {
-	    __DRIscreen * const psc = &priv->screenConfigs[i].driScreen;
-	    __DRIdrawable * const pdraw = (psc->private != NULL)
-	       ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL;
-
-	    if ( pdraw != NULL ) {
-		if ( scrn_num != NULL ) {
-		    *scrn_num = i;
-		}
-		return pdraw;
-	    }
+    if (priv == NULL || priv->driDisplay.private == NULL)
+	return NULL;
+    
+    for (i = 0; i < screen_count; i++) {
+	sc = &priv->screenConfigs[i];
+	if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) {
+	    if (scrn_num != NULL)
+		*scrn_num = i;
+	    return pdraw;
 	}
     }
 
     return NULL;
 }
+
 #endif
 
 
@@ -359,7 +410,7 @@
 		    gc->screen = mode->screen;
 		    gc->vid = mode->visualID;
 		    gc->fbconfigID = mode->fbconfigID;
-		    gc->driContext.mode = mode;
+		    gc->mode = mode;
 		}
 	    }
 	}
@@ -473,6 +524,7 @@
 					     gc->driContext.private);
 	    gc->driContext.private = NULL;
 	}
+	GarbageCollectDRIDrawables(dpy, gc->screen);
     }
 #endif
 
@@ -1730,9 +1782,7 @@
       if ( (psc != NULL) && (psc->driScreen.private != NULL)
 	   && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
 	 __DRIdrawable * const pdraw = 
-	     (*psc->driScreen.getDrawable)(gc->currentDpy,
-					   gc->currentDrawable,
-					   psc->driScreen.private);
+	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
 	 if ( pdraw != NULL ) {
 	    pdraw->swap_interval = interval;
 	    return 0;
@@ -1759,9 +1809,7 @@
       if ( (psc != NULL) && (psc->driScreen.private != NULL)
 	   && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
 	 __DRIdrawable * const pdraw = 
-	     (*psc->driScreen.getDrawable)(gc->currentDpy,
-					   gc->currentDrawable,
-					   psc->driScreen.private);
+	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
 	 if ( pdraw != NULL ) {
 	    return pdraw->swap_interval;
 	 }
@@ -1919,9 +1967,7 @@
       if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
 	   && psc->driScreen.private ) {
 	 __DRIdrawable * const pdraw = 
-	     (*psc->driScreen.getDrawable)(gc->currentDpy,
-					   gc->currentDrawable,
-					   psc->driScreen.private);
+	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
 	 if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
 	    int       ret;
 	    int64_t   msc;
@@ -2140,11 +2186,10 @@
       int   i;
 
 
-      GetDRIDrawable( dpy, drawable, & screen_num );
-      if ( (screen_num != -1)
-	   && XF86VidModeQueryVersion( dpy, & i, & i )
-	   && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
-				      & mode_line ) ) {
+      if (GetDRIDrawable( dpy, drawable, & screen_num) != NULL
+	  && XF86VidModeQueryVersion( dpy, & i, & i )
+	  && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
+				     & mode_line ) ) {
 	 unsigned   n = dot_clock * 1000;
 	 unsigned   d = mode_line.vtotal * mode_line.htotal;
 
@@ -2889,50 +2934,6 @@
 }
 
 
-
-static Bool windowExistsFlag;
-
-static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
-{
-    if (xerr->error_code == BadWindow) {
-        windowExistsFlag = GL_FALSE;
-    }
-    return 0;
-}
-
-/**
- * Determine if a window associated with a \c GLXDrawable exists on the
- * X-server.  This function is not used internally by libGL.  It is provided
- * as a utility function for DRI drivers.
- * Drivers should not call this function directly.  They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \param dpy  Display associated with the drawable to be queried.
- * \param draw \c GLXDrawable to test.
- * 
- * \returns \c GL_TRUE if a window exists that is associated with \c draw,
- *          otherwise \c GL_FALSE is returned.
- * 
- * \warning This function is not currently thread-safe.
- *
- * \sa glXGetProcAddress
- *
- * \since Internal API version 20021128.
- */
-Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
-{
-    XWindowAttributes xwa;
-    int (*oldXErrorHandler)(Display *, XErrorEvent *);
-
-    XSync(dpy, GL_FALSE);
-    windowExistsFlag = GL_TRUE;
-    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
-    XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
-    XSetErrorHandler(oldXErrorHandler);
-    return windowExistsFlag;
-}
-
-
 /**
  * Get the unadjusted system time (UST).  Currently, the UST is measured in
  * microseconds since Epoc.  The actual resolution of the UST may vary from
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 8fe1033..7f0428c 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -61,6 +61,7 @@
 #include <inttypes.h>
 #include <sys/mman.h>
 #include "xf86dri.h"
+#include "xf86drm.h"
 #include "sarea.h"
 #include "dri_glx.h"
 #endif
@@ -366,6 +367,7 @@
 	    (*psc->driScreen.destroyScreen)(priv->dpy, i,
 					    psc->driScreen.private);
 	psc->driScreen.private = NULL;
+	__glxHashDestroy(psc->drawHash);
 #endif
     }
     XFree((char*) priv->screenConfigs);
@@ -781,7 +783,6 @@
     _gl_context_modes_destroy,
       
     __glXFindDRIScreen,
-    __glXWindowExists,
       
     XF86DRICreateContextWithConfig,
     XF86DRIDestroyContext,
@@ -816,7 +817,7 @@
  *       returned by the client-side driver.
  */
 static void *
-CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
 		    __DRIdisplay * driDpy,
 		    PFNCREATENEWSCREENFUNC createNewScreen)
 {
@@ -937,13 +938,12 @@
 
 				if ( status == 0 ) {
 				    __GLcontextModes * driver_modes = NULL;
-				    __GLXscreenConfigs *configs = psc->screenConfigs;
 
 				    err_msg = "InitDriver";
 				    err_extra = NULL;
 				    psp = (*createNewScreen)(dpy, scrn,
-							     psc,
-							     configs->configs,
+							     &psc->driScreen,
+							     psc->configs,
 							     & ddx_version,
 							     & dri_version,
 							     & drm_version,
@@ -954,7 +954,7 @@
 							     & interface_methods,
 							     & driver_modes );
 
-				    filter_modes( & configs->configs,
+				    filter_modes( & psc->configs,
 						  driver_modes );
 				    _gl_context_modes_destroy( driver_modes );
 				}
@@ -1169,6 +1169,14 @@
 	UnlockDisplay(dpy);
 
 #ifdef GLX_DIRECT_RENDERING
+	/* Create drawable hash */
+	psc->drawHash = __glxHashCreate();
+	if ( psc->drawHash == NULL ) {
+	    SyncHandle();
+	    FreeScreenConfigs(priv);
+	    return GL_FALSE;
+	}
+
         /* Initialize per screen dynamic client GLX extensions */
 	psc->ext_list_first_time = GL_TRUE;
 	/* Initialize the direct rendering per screen data and functions */
@@ -1181,7 +1189,7 @@
 
 		psc->driScreen.screenConfigs = (void *)psc;
 		psc->driScreen.private =
-		    CallCreateNewScreen(dpy, i, & psc->driScreen,
+		    CallCreateNewScreen(dpy, i, psc,
 					& priv->driDisplay,
 					priv->driDisplay.createNewScreen[i] );
 	    }
@@ -1617,20 +1625,64 @@
 
 
 #ifdef GLX_DIRECT_RENDERING
+static __DRIdrawable *
+FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc)
+{
+    __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+    __DRIdrawable *pdraw;
+    __GLXscreenConfigs *sc;
+    void *empty_attribute_list = NULL;
+
+    if (priv == NULL || priv->driDisplay.private == NULL)
+	return NULL;
+    
+    sc = &priv->screenConfigs[gc->screen];
+    if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0)
+	return pdraw;
+
+    /* Allocate a new drawable */
+    pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable));
+    if (!pdraw)
+	return NULL;
+
+    /* Create a new drawable */
+    pdraw->private =
+	(*sc->driScreen.createNewDrawable)(dpy,
+					   gc->mode,
+					   drawable, pdraw,
+					   GLX_WINDOW_BIT,
+					   empty_attribute_list);
+
+    if (!pdraw->private) {
+	/* ERROR!!! */
+	Xfree(pdraw);
+	return NULL;
+    }
+
+    if (__glxHashInsert(sc->drawHash, drawable, pdraw)) {
+	(*pdraw->destroyDrawable)(dpy, pdraw->private);
+	Xfree(pdraw);
+	return NULL;
+    }
+
+    return pdraw;
+}
+
 static Bool BindContextWrapper( Display *dpy, GLXContext gc,
 				GLXDrawable draw, GLXDrawable read )
 {
-    return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
+    __DRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
+    __DRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);
+
+    return (*gc->driContext.bindContext)(dpy, gc->screen, pdraw, pread,
 					 & gc->driContext);
 }
 
 
 static Bool UnbindContextWrapper( GLXContext gc )
 {
-    return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, 
-					   gc->currentDrawable,
-					   gc->currentReadable,
-					   & gc->driContext );
+    return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
+					   &gc->driContext );
 }
 #endif /* GLX_DIRECT_RENDERING */
 
diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c
index f722cba..1b284c5 100644
--- a/src/glx/x11/glxhash.c
+++ b/src/glx/x11/glxhash.c
@@ -1,4 +1,6 @@
-/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
+/* glxhash.c -- Small hash table support for integer -> integer mapping
+ * Taken from libdrm.
+ *
  * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
  *
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -25,8 +27,6 @@
  *
  * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
  *
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
- *
  * DESCRIPTION
  *
  * This file contains a straightforward implementation of a fixed-sized
diff --git a/src/glx/x11/xf86dristr.h b/src/glx/x11/xf86dristr.h
index ac05b18..7e8bc55 100644
--- a/src/glx/x11/xf86dristr.h
+++ b/src/glx/x11/xf86dristr.h
@@ -50,9 +50,10 @@
  *    4.0.0: Original
  *    4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
  *    4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
+ *    5.0.0: Drop XIDs from DRI interface.
  */
-#define XF86DRI_MAJOR_VERSION	4
-#define XF86DRI_MINOR_VERSION	1
+#define XF86DRI_MAJOR_VERSION	5
+#define XF86DRI_MINOR_VERSION	0
 #define XF86DRI_PATCH_VERSION	0
 
 typedef struct _XF86DRIQueryVersion {
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index c30e66f..1f916a8 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -89,63 +89,6 @@
 
 
 /*****************************************************************/
-/** \name Drawable list management */
-/*****************************************************************/
-/*@{*/
-
-static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
-{
-    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
-
-    if (drmHashInsert(drawHash, pdp->draw, pdraw))
-	return GL_FALSE;
-
-    return GL_TRUE;
-}
-
-static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
-{
-    int retcode;
-    __DRIdrawable *pdraw;
-
-    retcode = drmHashLookup(drawHash, draw, (void *)&pdraw);
-    if (retcode)
-	return NULL;
-
-    return pdraw;
-}
-
-
-/**
- * Find drawables in the local hash that have been destroyed on the
- * server.
- * 
- * \param drawHash  Hash-table containing all know drawables.
- */
-static void __driGarbageCollectDrawables(void *drawHash)
-{
-    __DRIid draw;
-    __DRInativeDisplay *dpy;
-    __DRIdrawable *pdraw;
-
-    if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) {
-	do {
-	    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
-	    dpy = pdp->driScreenPriv->display;
-	    if (! (*dri_interface->windowExists)(dpy, draw)) {
-		/* Destroy the local drawable data, if the drawable no
-		   longer exists in the Xserver */
-		(*pdraw->destroyDrawable)(dpy, pdraw->private);
-		_mesa_free(pdraw);
-	    }
-	} while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1);
-    }
-}
-
-/*@}*/
-
-
-/*****************************************************************/
 /** \name Context (un)binding functions                          */
 /*****************************************************************/
 /*@{*/
@@ -155,8 +98,6 @@
  * 
  * \param dpy the display handle.
  * \param scrn the screen number.
- * \param draw drawable.
- * \param read Current reading drawable.
  * \param gc context.
  *
  * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
@@ -170,12 +111,9 @@
  * into their respective real types it also assures they are not \c NULL. 
  */
 static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
-			      __DRIid draw, __DRIid read,
-			      __DRIcontext *ctx)
+				  __DRIcontext *ctx)
 {
     __DRIscreen *pDRIScreen;
-    __DRIdrawable *pdraw;
-    __DRIdrawable *pread;
     __DRIcontextPrivate *pcp;
     __DRIscreenPrivate *psp;
     __DRIdrawablePrivate *pdp;
@@ -186,7 +124,7 @@
     ** calling driUnbindContext.
     */
 
-    if (ctx == NULL || draw == None || read == None) {
+    if (ctx == NULL) {
 	/* ERROR!!! */
 	return GL_FALSE;
     }
@@ -199,26 +137,12 @@
 
     psp = (__DRIscreenPrivate *)pDRIScreen->private;
     pcp = (__DRIcontextPrivate *)ctx->private;
-
-    pdraw = __driFindDrawable(psp->drawHash, draw);
-    if (!pdraw) {
-	/* ERROR!!! */
-	return GL_FALSE;
-    }
-    pdp = (__DRIdrawablePrivate *)pdraw->private;
-
-    pread = __driFindDrawable(psp->drawHash, read);
-    if (!pread) {
-	/* ERROR!!! */
-	return GL_FALSE;
-    }
-    prp = (__DRIdrawablePrivate *)pread->private;
-
+    pdp = (__DRIdrawablePrivate *)pcp->driDrawablePriv;
+    prp = (__DRIdrawablePrivate *)pcp->driReadablePriv;
 
     /* Let driver unbind drawable from context */
     (*psp->DriverAPI.UnbindContext)(pcp);
 
-
     if (pdp->refcount == 0) {
 	/* ERROR!!! */
 	return GL_FALSE;
@@ -254,72 +178,20 @@
  * This function takes both a read buffer and a draw buffer.  This is needed
  * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
  * function.
- * 
- * \bug This function calls \c driCreateNewDrawable in two places with the
- *      \c renderType hard-coded to \c GLX_WINDOW_BIT.  Some checking might
- *      be needed in those places when support for pbuffers and / or pixmaps
- *      is added.  Is it safe to assume that the drawable is a window?
  */
 static GLboolean DoBindContext(__DRInativeDisplay *dpy,
-			  __DRIid draw, __DRIid read,
-			  __DRIcontext *ctx, const __GLcontextModes * modes,
-			  __DRIscreenPrivate *psp)
+			       __DRIdrawable *pdraw,
+			       __DRIdrawable *pread,
+			       __DRIcontext *ctx,
+			       __DRIscreenPrivate *psp)
 {
-    __DRIdrawable *pdraw;
     __DRIdrawablePrivate *pdp;
-    __DRIdrawable *pread;
     __DRIdrawablePrivate *prp;
     __DRIcontextPrivate * const pcp = ctx->private;
 
 
-    /* Find the _DRIdrawable which corresponds to the writing drawable. */
-    pdraw = __driFindDrawable(psp->drawHash, draw);
-    if (!pdraw) {
-	/* Allocate a new drawable */
-	pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
-	if (!pdraw) {
-	    /* ERROR!!! */
-	    return GL_FALSE;
-	}
-
-	/* Create a new drawable */
-	driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
-			     empty_attribute_list);
-	if (!pdraw->private) {
-	    /* ERROR!!! */
-	    _mesa_free(pdraw);
-	    return GL_FALSE;
-	}
-
-    }
     pdp = (__DRIdrawablePrivate *) pdraw->private;
-
-    /* Find the _DRIdrawable which corresponds to the reading drawable. */
-    if (read == draw) {
-        /* read buffer == draw buffer */
-        prp = pdp;
-    }
-    else {
-        pread = __driFindDrawable(psp->drawHash, read);
-        if (!pread) {
-            /* Allocate a new drawable */
-            pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
-            if (!pread) {
-                /* ERROR!!! */
-                return GL_FALSE;
-            }
-
-            /* Create a new drawable */
-	    driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
-				 empty_attribute_list);
-            if (!pread->private) {
-                /* ERROR!!! */
-                _mesa_free(pread);
-                return GL_FALSE;
-            }
-        }
-        prp = (__DRIdrawablePrivate *) pread->private;
-    }
+    prp = (__DRIdrawablePrivate *) pread->private;
 
     /* Bind the drawable to the context */
     pcp->driDrawablePriv = pdp;
@@ -359,8 +231,9 @@
  * function.
  */
 static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
-                            __DRIid draw, __DRIid read,
-                            __DRIcontext * ctx)
+				__DRIdrawable *pdraw,
+				__DRIdrawable *pread,
+				__DRIcontext * ctx)
 {
     __DRIscreen *pDRIScreen;
 
@@ -369,7 +242,7 @@
     ** calling driBindContext.
     */
 
-    if (ctx == NULL || draw == None || read == None) {
+    if (ctx == NULL || pdraw == None || pread == None) {
 	/* ERROR!!! */
 	return GL_FALSE;
     }
@@ -380,7 +253,7 @@
 	return GL_FALSE;
     }
 
-    return DoBindContext( dpy, draw, read, ctx, ctx->mode,
+    return DoBindContext( dpy, pdraw, pread, ctx,
 			  (__DRIscreenPrivate *)pDRIScreen->private );
 }
 /*@}*/
@@ -438,8 +311,7 @@
 
     DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
 
-    if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
-	! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
+    if (! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
 			  &pdp->index, &pdp->lastStamp,
 			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
 			  &pdp->numClipRects, &pdp->pClipRects,
@@ -675,30 +547,9 @@
 
     pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
 
-    /* Add pdraw to drawable list */
-    if (!__driAddDrawable(psp->drawHash, pdraw)) {
-	/* ERROR!!! */
-	(*pdraw->destroyDrawable)(dpy, pdp);
-	_mesa_free(pdp);
-	pdp = NULL;
-	pdraw->private = NULL;
-    }
-
    return (void *) pdp;
 }
 
-static __DRIdrawable *
-driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
-{
-    __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
-
-    /*
-    ** Make sure this routine returns NULL if the drawable is not bound
-    ** to a direct rendering context!
-    */
-    return __driFindDrawable(psp->drawHash, draw);
-}
-
 static void
 driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
 {
@@ -710,9 +561,7 @@
 	psp = pdp->driScreenPriv;
 	scrn = psp->myNum;
         (*psp->DriverAPI.DestroyBuffer)(pdp);
-	if ((*dri_interface->windowExists)(dpy, pdp->draw))
-	    (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
-	drmHashDelete(psp->drawHash, pdp->draw);
+	(void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
 	if (pdp->pClipRects) {
 	    _mesa_free(pdp->pClipRects);
 	    pdp->pClipRects = NULL;
@@ -751,7 +600,6 @@
 
     if (pcp) {
 	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
-	__driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
 	(void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
 	_mesa_free(pcp);
     }
@@ -836,8 +684,6 @@
         return NULL;
     }
 
-    __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
-
     return pcp;
 }
 /*@}*/
@@ -874,15 +720,11 @@
 
 	(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
 	(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
-	_mesa_free(psp->pDevPriv);
 	(void)drmCloseOnce(psp->fd);
 	if ( psp->modes != NULL ) {
 	    (*dri_interface->destroyContextModes)( psp->modes );
 	}
 
-	assert(psp->drawHash);
-	drmHashDestroy(psp->drawHash);
-
 	_mesa_free(psp);
     }
 }
@@ -939,13 +781,6 @@
 	return NULL;
     }
 
-    /* Create the hash table */
-    psp->drawHash = drmHashCreate();
-    if ( psp->drawHash == NULL ) {
-	_mesa_free( psp );
-	return NULL;
-    }
-
     psp->display = dpy;
     psp->myNum = scrn;
     psp->psc = psc;
@@ -993,7 +828,6 @@
 
     psc->destroyScreen     = driDestroyScreen;
     psc->createNewDrawable = driCreateNewDrawable;
-    psc->getDrawable       = driGetDrawable;
     psc->getMSC            = driGetMSC;
     psc->createNewContext  = driCreateNewContext;
 
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 539d28d..a08eab1 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -490,11 +490,6 @@
     __DRIcontextPrivate dummyContextPriv;
 
     /**
-     * Hash table to hold the drawable information for this screen.
-     */
-    void *drawHash;
-
-    /**
      * Device-dependent private information (not stored in the SAREA).
      * 
      * This pointer is never touched by the DRI layer.
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index f8cf050..c0a7cdb 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -431,7 +431,7 @@
  *         failure.
  */
 PUBLIC
-void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
+void * __driCreateNewScreen_20070105( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
 			     const __GLcontextModes * modes,
 			     const __DRIversion * ddx_version,
 			     const __DRIversion * dri_version,