egl_xdri: Revive the driver.
authorChia-I Wu <olvaffe@gmail.com>
Sun, 16 Aug 2009 00:51:58 +0000 (08:51 +0800)
committerBrian Paul <brianp@vmware.com>
Mon, 24 Aug 2009 17:49:45 +0000 (11:49 -0600)
egl_xdri does not compile for some time.  This commit revives the
driver.  It no longer depends on libGL.so for GLX related functions.
Instead, it uses code from src/glx/ directly.  Both DRI and DRI2 are
supported.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
src/egl/drivers/xdri/Makefile
src/egl/drivers/xdri/driinit.c [new file with mode: 0644]
src/egl/drivers/xdri/driinit.h [new file with mode: 0644]
src/egl/drivers/xdri/egl_xdri.c
src/egl/drivers/xdri/glxinit.c [new file with mode: 0644]
src/egl/drivers/xdri/glxinit.h [new file with mode: 0644]

index 8a14027..4c1fc90 100644 (file)
@@ -16,19 +16,24 @@ INCLUDE_DIRS = \
        $(shell pkg-config --cflags-only-I libdrm) \
        -I$(TOP)/include \
        -I$(TOP)/include/GL/internal \
+       -I$(TOP)/src/mesa \
        -I$(TOP)/src/mesa/glapi \
-       -I$(TOP)/src/mesa/drivers/dri/common \
        -I$(TOP)/src/egl/main \
        -I$(TOP)/src/glx/x11
 
-SOURCES = egl_xdri.c
+HEADERS = glxinit.h driinit.h
+SOURCES = egl_xdri.c glxinit.c driinit.c
+
+DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c
+DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES))
+
+SOURCES += $(DRI_SOURCES)
 
 OBJECTS = $(SOURCES:.c=.o)
 
 DRM_LIB = `pkg-config --libs libdrm`
 
-MISC_LIBS = -ldl -lXext -lGL
-
+CFLAGS += -DGLX_DIRECT_RENDERING
 
 .c.o:
        $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -50,7 +55,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS)
                -major 1 -minor 0 \
                -L$(TOP)/$(LIB_DIR) \
                -install $(TOP)/$(LIB_DIR) \
-               $(OBJECTS) $(DRM_LIB) $(MISC_LIBS)
+               $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS)
 
 install:
        $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c
new file mode 100644 (file)
index 0000000..12da1bc
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * DRI initialization.  The DRI loaders are defined in src/glx/x11/.
+ */
+
+#include <sys/time.h>
+
+#include "glxclient.h"
+#include "driinit.h"
+
+/* for __DRI_SYSTEM_TIME extension */
+_X_HIDDEN int
+__glXGetUST(int64_t * ust)
+{
+   struct timeval tv;
+
+   if (ust == NULL) {
+      return -EFAULT;
+   }
+
+   if (gettimeofday(&tv, NULL) == 0) {
+      ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
+      return 0;
+   }
+   else {
+      return -errno;
+   }
+}
+
+_X_HIDDEN GLboolean
+__driGetMscRateOML(__DRIdrawable * draw,
+                   int32_t * numerator, int32_t * denominator, void *private)
+{
+   return GL_FALSE;
+}
+
+/* ignore glx extensions */
+_X_HIDDEN void
+__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name)
+{
+}
+
+_X_HIDDEN __GLXDRIdisplay *
+__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version)
+{
+   __GLXDRIdisplay *driDisplay;
+   int ver = 0;
+
+   /* try DRI2 first */
+   driDisplay = dri2CreateDisplay(dpyPriv->dpy);
+   if (driDisplay) {
+      /* fill in the required field */
+      dpyPriv->dri2Display = driDisplay;
+      ver = 2;
+   }
+   else {
+      /* try DRI */
+      driDisplay = driCreateDisplay(dpyPriv->dpy);
+      if (driDisplay) {
+         dpyPriv->driDisplay = driDisplay;
+         ver = 1;
+      }
+   }
+
+   if (version)
+      *version = ver;
+   return driDisplay;
+}
diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h
new file mode 100644 (file)
index 0000000..6ea05ce
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef DRIINIT_INCLUDED
+#define DRIINIT_INCLUDED
+
+#include "glxclient.h"
+
+extern __GLXDRIdisplay *
+__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version);
+
+#endif /* DRIINIT_INCLUDED */
index d8d29fc..518091a 100644 (file)
  * Authors: Brian Paul
  */
 
-
 #include <assert.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "dlfcn.h"
+#include <stdlib.h>
 #include <X11/Xlib.h>
-#include <GL/gl.h>
-#include "xf86dri.h"
-#include "glxclient.h"
-#include "dri_util.h"
-#include "drm_sarea.h"
 
-#define _EGL_PLATFORM_X
+#include "glxinit.h"
+#include "driinit.h"
+#include "glapi/glapi.h" /* for glapi functions */
 
 #include "eglconfig.h"
 #include "eglcontext.h"
 #include "egldisplay.h"
 #include "egldriver.h"
 #include "eglglobals.h"
-#include "eglhash.h"
 #include "egllog.h"
 #include "eglsurface.h"
 
-#include <GL/gl.h>
-
-typedef void (*glGetIntegerv_t)(GLenum, GLint *);
-typedef void (*glBindTexture_t)(GLenum, GLuint);
-typedef void (*glCopyTexImage2D_t)(GLenum, GLint, GLenum, GLint, GLint,
-                                   GLint, GLint, GLint);
-
-
 #define CALLOC_STRUCT(T)   (struct T *) calloc(1, sizeof(struct T))
 
-
 /** subclass of _EGLDriver */
 struct xdri_egl_driver
 {
    _EGLDriver Base;   /**< base class */
-
-   const char *dri_driver_name;  /**< name of DRI driver to load */
-   void *dri_driver_handle;      /**< returned by dlopen(dri_driver_name) */
-
-   __GLXdisplayPrivate *glx_priv;
+};
 
 
-   /* XXX we're not actually using these at this time: */
-   int chipset;
-   int minor;
-   int drmFD;
+/** driver data of _EGLDisplay */
+struct xdri_egl_display
+{
+   Display *dpy;
+   __GLXdisplayPrivate *dpyPriv;
+   __GLXDRIdisplay *driDisplay;
 
-   __DRIframebuffer framebuffer;
-   drm_handle_t hSAREA;
-   drmAddress pSAREA;
-   char *busID;
-   drm_magic_t magic;
+   __GLXscreenConfigs *psc;
+   EGLint scr;
 };
 
 
@@ -104,9 +81,10 @@ struct xdri_egl_context
 {
    _EGLContext Base;   /**< base class */
 
-   __DRIcontext driContext;
+   /* just enough info to create dri contexts */
+   GLXContext dummy_gc;
 
-   GLint bound_tex_object;
+   __GLXDRIcontext *driContext;
 };
 
 
@@ -115,8 +93,8 @@ struct xdri_egl_surface
 {
    _EGLSurface Base;   /**< base class */
 
-   __DRIid driDrawable;  /**< DRI surface */
-   drm_drawable_t hDrawable;
+   Drawable drawable;
+   __GLXDRIdrawable *driDrawable;
 };
 
 
@@ -131,46 +109,44 @@ struct xdri_egl_config
 
 
 /** cast wrapper */
-static struct xdri_egl_driver *
+static INLINE struct xdri_egl_driver *
 xdri_egl_driver(_EGLDriver *drv)
 {
    return (struct xdri_egl_driver *) drv;
 }
 
 
+static INLINE struct xdri_egl_display *
+lookup_display(_EGLDisplay *dpy)
+{
+   return (struct xdri_egl_display *) dpy->DriverData;
+}
+
+
 /** Map EGLSurface handle to xdri_egl_surface object */
-static struct xdri_egl_surface *
-lookup_surface(EGLSurface surf)
+static INLINE struct xdri_egl_surface *
+lookup_surface(_EGLSurface *surface)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
    return (struct xdri_egl_surface *) surface;
 }
 
 
 /** Map EGLContext handle to xdri_egl_context object */
-static struct xdri_egl_context *
-lookup_context(EGLContext c)
+static INLINE struct xdri_egl_context *
+lookup_context(_EGLContext *context)
 {
-   _EGLContext *context = _eglLookupContext(c);
    return (struct xdri_egl_context *) context;
 }
 
-static struct xdri_egl_context *
-current_context(void)
-{
-   return (struct xdri_egl_context *) _eglGetCurrentContext();
-}
 
 /** Map EGLConfig handle to xdri_egl_config object */
-static struct xdri_egl_config *
-lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+static INLINE struct xdri_egl_config *
+lookup_config(_EGLConfig *conf)
 {
-   _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
    return (struct xdri_egl_config *) conf;
 }
 
 
-
 /** Get size of given window */
 static Status
 get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
@@ -188,22 +164,18 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
 
 /**
  * Produce a set of EGL configs.
- * Note that we get the list of GLcontextModes from the GLX library.
- * This dependency on GLX lib will be removed someday.
  */
-static void
-create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
+static EGLint
+create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
 {
    static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
                                    EGL_OPENGL_ES2_BIT |
                                    EGL_OPENVG_BIT |
                                    EGL_OPENGL_BIT);
-   __GLXscreenConfigs *scrn = glx_priv->screenConfigs;
-   const __GLcontextModes *m;
-   int id = 1;
+   int id = first_id;
 
-   for (m = scrn->configs; m; m = m->next) {
-      /* EGL requires double-buffered configs */
+   for (; m; m = m->next) {
+      /* add double buffered visual */
       if (m->doubleBufferMode) {
          struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config);
 
@@ -222,9 +194,7 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
          SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType);
          SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis);
          SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis);
-         /* XXX only window rendering allowed ATM */
-         SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE,
-                           (EGL_WINDOW_BIT | EGL_PBUFFER_BIT));
+         SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
 
          /* XXX possibly other things to init... */
 
@@ -234,431 +204,76 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
          _eglAddConfig(disp, &config->Base);
       }
    }
-}
 
-
-/**
- * Called via __DRIinterfaceMethods object
- */
-static __DRIfuncPtr
-dri_get_proc_address(const char * proc_name)
-{
-   return NULL;
-}
-
-
-static void
-dri_context_modes_destroy(__GLcontextModes *modes)
-{
-   _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
-
-   while (modes) {
-      __GLcontextModes * const next = modes->next;
-      free(modes);
-      modes = next;
-   }
+   return id;
 }
 
 
 /**
- * Create a linked list of 'count' GLcontextModes.
- * These are used during the client/server visual negotiation phase,
- * then discarded.
+ * Called via eglInitialize(), xdri_dpy->API.Initialize().
  */
-static __GLcontextModes *
-dri_context_modes_create(unsigned count, size_t minimum_size)
-{
-   /* This code copied from libGLX, and modified */
-   const size_t size = (minimum_size > sizeof(__GLcontextModes))
-       ? minimum_size : sizeof(__GLcontextModes);
-   __GLcontextModes * head = NULL;
-   __GLcontextModes ** next;
-   unsigned   i;
-
-   next = & head;
-   for (i = 0 ; i < count ; i++) {
-      *next = (__GLcontextModes *) calloc(1, size);
-      if (*next == NULL) {
-        dri_context_modes_destroy(head);
-        head = NULL;
-        break;
-      }
-      
-      (*next)->doubleBufferMode = 1;
-      (*next)->visualID = GLX_DONT_CARE;
-      (*next)->visualType = GLX_DONT_CARE;
-      (*next)->visualRating = GLX_NONE;
-      (*next)->transparentPixel = GLX_NONE;
-      (*next)->transparentRed = GLX_DONT_CARE;
-      (*next)->transparentGreen = GLX_DONT_CARE;
-      (*next)->transparentBlue = GLX_DONT_CARE;
-      (*next)->transparentAlpha = GLX_DONT_CARE;
-      (*next)->transparentIndex = GLX_DONT_CARE;
-      (*next)->xRenderable = GLX_DONT_CARE;
-      (*next)->fbconfigID = GLX_DONT_CARE;
-      (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
-      (*next)->bindToTextureRgb = GLX_DONT_CARE;
-      (*next)->bindToTextureRgba = GLX_DONT_CARE;
-      (*next)->bindToMipmapTexture = GLX_DONT_CARE;
-      (*next)->bindToTextureTargets = 0;
-      (*next)->yInverted = GLX_DONT_CARE;
-
-      next = & ((*next)->next);
-   }
-
-   return head;
-}
-
-
-static __DRIscreen *
-dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn)
-{
-   __GLXdisplayPrivate *priv = __glXInitialize(ndpy);
-   __GLXscreenConfigs *scrnConf = priv->screenConfigs;
-   return &scrnConf->driScreen;
-}
-
-
-static GLboolean
-dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw)
-{
-   return EGL_TRUE;
-}
-
-
-static GLboolean
-dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID,
-                   void * contextID, drm_context_t * hw_context)
-{
-   assert(configID >= 0);
-   return XF86DRICreateContextWithConfig(ndpy, screenNum,
-                                         configID, contextID, hw_context);
-}
-
-
-static GLboolean
-dri_destroy_context(__DRInativeDisplay * ndpy, int screen, __DRIid context)
-{
-   return XF86DRIDestroyContext(ndpy, screen, context);
-}
-
-
-static GLboolean
-dri_create_drawable(__DRInativeDisplay * ndpy, int screen,
-                    __DRIid drawable, drm_drawable_t * hHWDrawable)
-{
-   _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
-
-   /* Create DRI drawable for given window ID (drawable) */
-   if (!XF86DRICreateDrawable(ndpy, screen, drawable, hHWDrawable))
-      return EGL_FALSE;
-
-   return EGL_TRUE;
-}
-
-
-static GLboolean
-dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable)
-{
-   _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
-   return XF86DRIDestroyDrawable(ndpy, screen, drawable);
-}
-
-
-static GLboolean
-dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn,
-                      __DRIid draw, unsigned int * index, unsigned int * stamp,
-                      int * x, int * y, int * width, int * height,
-                      int * numClipRects, drm_clip_rect_t ** pClipRects,
-                      int * backX, int * backY,
-                      int * numBackClipRects,
-                      drm_clip_rect_t ** pBackClipRects)
-{
-   _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
-
-   if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp,
-                               x, y, width, height,
-                               numClipRects, pClipRects,
-                               backX, backY,
-                               numBackClipRects, pBackClipRects)) {
-      return EGL_FALSE;
-   }
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Table of functions exported by the loader to the driver.
- */
-static const __DRIinterfaceMethods interface_methods = {
-   dri_get_proc_address,
-
-   dri_context_modes_create,
-   dri_context_modes_destroy,
-
-   dri_find_dri_screen,
-   dri_window_exists,
-
-   dri_create_context,
-   dri_destroy_context,
-
-   dri_create_drawable,
-   dri_destroy_drawable,
-   dri_get_drawable_info,
-
-   NULL,/*__eglGetUST,*/
-   NULL,/*__eglGetMSCRate,*/
-};
-
-
-
 static EGLBoolean
-init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp)
+xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
+                   EGLint *minor, EGLint *major)
 {
-   __DRIversion ddx_version;
-   __DRIversion dri_version;
-   __DRIversion drm_version;
-   drmVersionPtr version;
-   drm_handle_t  hFB;
-   int newlyopened;
-   int status;
-   int scrn = DefaultScreen(disp->Xdpy);
-
-#if 0
-   createNewScreen = (PFNCREATENEWSCREENFUNC)
-      dlsym(xdri_drv->dri_driver_handle, createNewScreenName);
-   if (!createNewScreen) {
-      _eglLog(_EGL_WARNING, "XDRI: Couldn't find %s function in the driver.",
-              createNewScreenName);
-      return EGL_FALSE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName);
-   }
-#endif
-
-   /*
-    * Get the DRI X extension version.
-    */
-   dri_version.major = 4;
-   dri_version.minor = 0;
-   dri_version.patch = 0;
-
-   if (!XF86DRIOpenConnection(disp->Xdpy, scrn,
-                              &xdri_drv->hSAREA, &xdri_drv->busID)) {
-      _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed");
-   }
-
-   xdri_drv->drmFD = drmOpenOnce(NULL, xdri_drv->busID, &newlyopened);
-   if (xdri_drv->drmFD < 0) {
-      perror("drmOpenOnce failed: ");
-      return EGL_FALSE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: drmOpenOnce returned %d", xdri_drv->drmFD);
-   }
-
-
-   if (drmGetMagic(xdri_drv->drmFD, &xdri_drv->magic)) {
-      perror("drmGetMagic failed: ");
-      return EGL_FALSE;
-   }
-
-   version = drmGetVersion(xdri_drv->drmFD);
-   if (version) {
-      drm_version.major = version->version_major;
-      drm_version.minor = version->version_minor;
-      drm_version.patch = version->version_patchlevel;
-      drmFreeVersion(version);
-      _eglLog(_EGL_DEBUG, "XDRI: Got DRM version %d.%d.%d",
-              drm_version.major,
-              drm_version.minor,
-              drm_version.patch);
-   }
-   else {
-      drm_version.major = -1;
-      drm_version.minor = -1;
-      drm_version.patch = -1;
-      _eglLog(_EGL_WARNING, "XDRI: drmGetVersion() failed");
-      return EGL_FALSE;
-   }
-
-   /* Authenticate w/ server.
-    */
-   if (!XF86DRIAuthConnection(disp->Xdpy, scrn, xdri_drv->magic)) {
-      _eglLog(_EGL_WARNING, "XDRI: XF86DRIAuthConnection() failed");
-      return EGL_FALSE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: XF86DRIAuthConnection() success");
-   }
-
-   /* Get ddx version.
-    */
-   {
-      char *driverName;
-
-      /*
-       * Get device name (like "tdfx") and the ddx version
-       * numbers.  We'll check the version in each DRI driver's
-       * "createNewScreen" function.
-       */
-      if (!XF86DRIGetClientDriverName(disp->Xdpy, scrn,
-                                     &ddx_version.major,
-                                     &ddx_version.minor,
-                                     &ddx_version.patch,
-                                     &driverName)) {
-         _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetClientDriverName failed");
-         return EGL_FALSE;
-      }
-      else {
-         _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetClientDriverName returned %s", driverName);
-      }
-   }
-
-   /* Get framebuffer info.
-    */
-   {
-      int junk;
-      if (!XF86DRIGetDeviceInfo(disp->Xdpy, scrn,
-                                &hFB,
-                                &junk,
-                                &xdri_drv->framebuffer.size,
-                                &xdri_drv->framebuffer.stride,
-                                &xdri_drv->framebuffer.dev_priv_size,
-                                &xdri_drv->framebuffer.dev_priv)) {
-         _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetDeviceInfo() failed");
-         return EGL_FALSE;
+   struct xdri_egl_display *xdri_dpy;
+   __GLXdisplayPrivate *dpyPriv;
+   __GLXDRIdisplay *driDisplay;
+   __GLXscreenConfigs *psc;
+   EGLint first_id = 1;
+   int scr;
+
+   xdri_dpy = CALLOC_STRUCT(xdri_egl_display);
+   if (!xdri_dpy)
+      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+   xdri_dpy->dpy = (Display *) dpy->NativeDisplay;
+   if (!xdri_dpy->dpy) {
+      xdri_dpy->dpy = XOpenDisplay(NULL);
+      if (!xdri_dpy->dpy) {
+         free(xdri_dpy);
+         return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
       }
-      else {
-         _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetDeviceInfo() success");
-      }
-      xdri_drv->framebuffer.width = DisplayWidth(disp->Xdpy, scrn);
-      xdri_drv->framebuffer.height = DisplayHeight(disp->Xdpy, scrn);
-   }
-
-   /* Map the framebuffer region. (this may not be needed)
-    */
-   status = drmMap(xdri_drv->drmFD, hFB, xdri_drv->framebuffer.size, 
-                   (drmAddressPtr) &xdri_drv->framebuffer.base);
-   if (status != 0) {
-      _eglLog(_EGL_WARNING, "XDRI: drmMap(framebuffer) failed");
-      return EGL_FALSE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: drmMap(framebuffer) success");
    }
 
-   /* Map the SAREA region.
-    */
-   status = drmMap(xdri_drv->drmFD, xdri_drv->hSAREA, SAREA_MAX, &xdri_drv->pSAREA);
-   if (status != 0) {
-      _eglLog(_EGL_WARNING, "XDRI: drmMap(sarea) failed");
-      return EGL_FALSE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success");
-   }
-
-   return EGL_TRUE;
-}
-
-
-/**
- * Load the DRI driver named by "xdri_drv->dri_driver_name".
- * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle".
- *
- * Later, we'll call dlsym(createNewScreenName) to get a pointer to
- * the driver's createNewScreen() function which is the bootstrap function.
- *
- * \return EGL_TRUE for success, EGL_FALSE for failure
- */
-static EGLBoolean
-load_dri_driver(struct xdri_egl_driver *xdri_drv)
-{
-   char filename[100];
-   int flags = RTLD_NOW;
-
-   /* try "egl_xxx_dri.so" first */
-   snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name);
-   _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
-   xdri_drv->dri_driver_handle = dlopen(filename, flags);
-   if (xdri_drv->dri_driver_handle) {
-      _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
-      return EGL_TRUE;
-   }
-   else {
-      _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror());
+   dpyPriv = __glXInitialize(xdri_dpy->dpy);
+   if (!dpyPriv) {
+      _eglLog(_EGL_WARNING, "failed to create GLX display");
+      free(xdri_dpy);
+      return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
    }
 
-   /* try regular "xxx_dri.so" next */
-   snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name);
-   _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
-   xdri_drv->dri_driver_handle = dlopen(filename, flags);
-   if (xdri_drv->dri_driver_handle) {
-      _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
-      return EGL_TRUE;
+   driDisplay = __driCreateDisplay(dpyPriv, NULL);
+   if (!driDisplay) {
+      _eglLog(_EGL_WARNING, "failed to create DRI display");
+      free(xdri_dpy);
+      return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
    }
 
-   _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror());
-   return EGL_FALSE;
-}
-
-
-/**
- * Called via eglInitialize(), xdri_drv->API.Initialize().
- */
-static EGLBoolean
-xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
-                   EGLint *minor, EGLint *major)
-{
-   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   static char name[100];
+   scr = DefaultScreen(xdri_dpy->dpy);
+   psc = &dpyPriv->screenConfigs[scr];
 
-   _eglLog(_EGL_DEBUG, "XDRI: eglInitialize");
+   xdri_dpy->dpyPriv = dpyPriv;
+   xdri_dpy->driDisplay = driDisplay;
+   xdri_dpy->psc = psc;
+   xdri_dpy->scr = scr;
 
-   if (!disp->Xdpy) {
-      disp->Xdpy = XOpenDisplay(NULL);
-      if (!disp->Xdpy) {
-         _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed");
-         return EGL_FALSE;
-      }
+   psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv);
+   if (!psc->driScreen) {
+      _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr);
+      free(xdri_dpy);
+      return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
    }
 
-#if 0
-   /* choose the DRI driver to load */
-   xdri_drv->dri_driver_name = _eglChooseDRMDriver(0);
-   if (!load_dri_driver(xdri_drv))
-      return EGL_FALSE;
-#else
-   (void) load_dri_driver;
-#endif
-
-#if 0
-   if (!init_drm(xdri_drv, disp))
-      return EGL_FALSE;
-#else
-   (void) init_drm;
-#endif
-
-   /*
-    * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI
-    * interface, loads the DRI driver, etc.
-    * This replaces the load_dri_driver()  and init_drm() code above.
-    */
-   xdri_drv->glx_priv = __glXInitialize(disp->Xdpy);
-
-   create_configs(disp, xdri_drv->glx_priv);
-
-   xdri_drv->Base.Initialized = EGL_TRUE;
+   /* add visuals and fbconfigs */
+   first_id = create_configs(dpy, psc->visuals, first_id);
+   create_configs(dpy, psc->configs, first_id);
 
-   if (xdri_drv->dri_driver_name)
-      snprintf(name, sizeof(name), "X/DRI:%s", xdri_drv->dri_driver_name);
-   else
-      snprintf(name, sizeof(name), "X/DRI");
-   xdri_drv->Base.Name = name;
+   dpy->DriverData = xdri_dpy;
+   dpy->ClientAPIsMask = (EGL_OPENGL_BIT |
+                          EGL_OPENGL_ES_BIT |
+                          EGL_OPENGL_ES2_BIT |
+                          EGL_OPENVG_BIT);
 
    /* we're supporting EGL 1.4 */
    *minor = 1;
@@ -668,57 +283,37 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
 }
 
 
-/*
- * Do some clean-up that normally occurs in XCloseDisplay().
- * We do this here because we're about to unload a dynamic library
- * that has added some per-display extension data and callbacks.
- * If we don't do this here we'll crash in XCloseDisplay() because it'll
- * try to call functions that went away when the driver library was unloaded.
- */
-static void
-FreeDisplayExt(Display *dpy)
-{
-   _XExtension *ext, *next;
-
-   for (ext = dpy->ext_procs; ext; ext = next) {
-      next = ext->next;
-      if (ext->close_display) {
-         ext->close_display(dpy, &ext->codes);
-         ext->close_display = NULL;
-      }
-      if (ext->name)
-         Xfree(ext->name);
-      Xfree(ext);
-   }
-   dpy->ext_procs = NULL;
-
-   _XFreeExtData (dpy->ext_data);
-   dpy->ext_data = NULL;
-}
-
-
 /**
  * Called via eglTerminate(), drv->API.Terminate().
  */
 static EGLBoolean
-xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
-   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+   __GLXscreenConfigs *psc;
 
-   _eglLog(_EGL_DEBUG, "XDRI: eglTerminate");
+   _eglReleaseDisplayResources(drv, dpy);
+   _eglCleanupDisplay(dpy);
 
-   _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name);
-
-   FreeDisplayExt(disp->Xdpy);
+   psc = xdri_dpy->psc;
+   if (psc->driver_configs) {
+      unsigned int i;
+      for (i = 0; psc->driver_configs[i]; i++)
+         free((__DRIconfig *) psc->driver_configs[i]);
+      free(psc->driver_configs);
+      psc->driver_configs = NULL;
+   }
+   if (psc->driScreen) {
+      psc->driScreen->destroyScreen(psc);
+      free(psc->driScreen);
+      psc->driScreen = NULL;
+   }
 
-#if 0
-   /* this causes a segfault for some reason */
-   dlclose(xdri_drv->dri_driver_handle);
-#endif
-   xdri_drv->dri_driver_handle = NULL;
+   xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
+   __glXRelease(xdri_dpy->dpyPriv);
 
-   free((void*) xdri_drv->dri_driver_name);
+   free(xdri_dpy);
+   dpy->DriverData = NULL;
 
    return EGL_TRUE;
 }
@@ -730,71 +325,77 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
 static _EGLProc
 xdri_eglGetProcAddress(const char *procname)
 {
-#if 0
-   _EGLDriver *drv = NULL;
-
-   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-   /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/
-   _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname);
-   return proc;
-#elif 1
-   /* This is a bit of a hack to get at the gallium/Mesa state tracker
-    * function st_get_proc_address().  This will probably change at
-    * some point.
-    */
-   _EGLProc (*st_get_proc_addr)(const char *procname);
-   st_get_proc_addr = dlsym(NULL, "st_get_proc_address");
-   if (st_get_proc_addr) {
-      return st_get_proc_addr(procname);
-   }
-   return NULL;   
-#else
-   return NULL;
-#endif
+   /* the symbol is defined in libGL.so */
+   return (_EGLProc) _glapi_get_proc_address(procname);
 }
 
 
 /**
  * Called via eglCreateContext(), drv->API.CreateContext().
  */
-static EGLContext
-xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                      EGLContext share_list, const EGLint *attrib_list)
-{
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
-   void *shared = NULL;
+static _EGLContext *
+xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                      _EGLContext *share_list, const EGLint *attrib_list)
+{
+   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+   struct xdri_egl_config *xdri_config = lookup_config(conf);
+   struct xdri_egl_context *shared = lookup_context(share_list);
+   __GLXscreenConfigs *psc = xdri_dpy->psc;
    int renderType = GLX_RGBA_BIT;
+   struct xdri_egl_context *xdri_ctx;
 
-   struct xdri_egl_context *xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
-   if (!xdri_ctx)
-      return EGL_NO_CONTEXT;
+   xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
+   if (!xdri_ctx) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+      return NULL;
+   }
 
-   if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
+   xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec);
+   if (!xdri_ctx->dummy_gc) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateContext");
       free(xdri_ctx);
-      return EGL_NO_CONTEXT;
+      return NULL;
    }
 
-   assert(xdri_config);
-
-   {
-      struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-      __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
-      xdri_ctx->driContext.private = 
-         scrnConf->driScreen.createNewContext(disp->Xdpy,
-                                              xdri_config->mode, renderType,
-                                              shared, &xdri_ctx->driContext);
+   if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
+      free(xdri_ctx->dummy_gc);
+      free(xdri_ctx);
+      return NULL;
    }
 
-   if (!xdri_ctx->driContext.private) {
-      _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed");
+   xdri_ctx->driContext =
+      psc->driScreen->createContext(psc,
+                                    xdri_config->mode,
+                                    xdri_ctx->dummy_gc,
+                                    (shared) ? shared->dummy_gc : NULL,
+                                    renderType);
+   if (!xdri_ctx->driContext) {
+      free(xdri_ctx->dummy_gc);
       free(xdri_ctx);
-      return EGL_NO_CONTEXT;
+      return NULL;
    }
 
-   xdri_ctx->driContext.mode = xdri_config->mode;
+   /* fill in the required field */
+   xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext;
 
-   return _eglLinkContext(&xdri_ctx->Base, &disp);
+   return &xdri_ctx->Base;
+}
+
+
+static EGLBoolean
+xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+   struct xdri_egl_context *xdri_ctx = lookup_context(ctx);
+
+   if (!_eglIsContextBound(ctx)) {
+      xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
+                                           xdri_dpy->psc, xdri_dpy->dpy);
+      free(xdri_ctx->dummy_gc);
+      free(xdri_ctx);
+   }
+
+   return EGL_TRUE;
 }
 
 
@@ -802,25 +403,32 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * Called via eglMakeCurrent(), drv->API.MakeCurrent().
  */
 static EGLBoolean
-xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
-                    EGLSurface r, EGLContext context)
+xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
+                    _EGLSurface *r, _EGLContext *context)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    struct xdri_egl_context *xdri_ctx = lookup_context(context);
-   struct xdri_egl_surface *xdri_draw = lookup_surface(d);
-   struct xdri_egl_surface *xdri_read = lookup_surface(r);
-   __DRIid draw = xdri_draw ? xdri_draw->driDrawable : 0;
-   __DRIid read = xdri_read ? xdri_read->driDrawable : 0;
-   int scrn = DefaultScreen(disp->Xdpy);
+   struct xdri_egl_surface *draw = lookup_surface(d);
+   struct xdri_egl_surface *read = lookup_surface(r);
 
    if (!_eglMakeCurrent(drv, dpy, d, r, context))
       return EGL_FALSE;
 
+   /* the symbol is defined in libGL.so */
+   _glapi_check_multithread();
 
-   if (xdri_ctx &&
-       !xdri_ctx->driContext.bindContext(disp->Xdpy, scrn, draw, read,
-                                         &xdri_ctx->driContext)) {
-      return EGL_FALSE;
+   if (xdri_ctx) {
+      if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext,
+                                             draw->driDrawable,
+                                             read->driDrawable)) {
+         return EGL_FALSE;
+      }
+   }
+   else {
+      _EGLContext *old = _eglGetCurrentContext();
+      if (old) {
+         xdri_ctx = lookup_context(old);
+         xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
+      }
    }
 
    return EGL_TRUE;
@@ -830,307 +438,106 @@ xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
-static EGLSurface
-xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                             NativeWindowType window, const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
+   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+   struct xdri_egl_config *xdri_config = lookup_config(conf);
    struct xdri_egl_surface *xdri_surf;
-   int scrn = DefaultScreen(disp->Xdpy);
    uint width, height;
 
    xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
-   if (!xdri_surf)
-      return EGL_NO_SURFACE;
+   if (!xdri_surf) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+      return NULL;
+   }
 
    if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT,
                         &xdri_config->Base, attrib_list)) {
       free(xdri_surf);
-      return EGL_FALSE;
+      return NULL;
    }
 
-   if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) {
+   xdri_surf->driDrawable =
+      xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc,
+                                               (XID) window,
+                                               (GLXDrawable) window,
+                                               xdri_config->mode);
+   if (!xdri_surf->driDrawable) {
       free(xdri_surf);
-      return EGL_FALSE;
+      return NULL;
    }
 
-   xdri_surf->driDrawable = window;
+   xdri_surf->drawable = (Drawable) window;
 
-   _eglLinkSurface(&xdri_surf->Base, disp);
-
-   get_drawable_size(disp->Xdpy, window, &width, &height);
+   get_drawable_size(xdri_dpy->dpy, window, &width, &height);
    xdri_surf->Base.Width = width;
    xdri_surf->Base.Height = height;
 
-   _eglLog(_EGL_DEBUG,
-           "XDRI: CreateWindowSurface win 0x%x  handle %d  hDrawable %d",
-           (int) window, _eglGetSurfaceHandle(&xdri_surf->Base),
-           (int) xdri_surf->hDrawable);
-
-   return _eglGetSurfaceHandle(&xdri_surf->Base);
+   return &xdri_surf->Base;
 }
 
 
 /**
  * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface().
  */
-static EGLSurface
-xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                              const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   struct xdri_egl_surface *xdri_surf;
-   struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
-   int scrn = DefaultScreen(disp->Xdpy);
-   Window window;
-
-   xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
-   if (!xdri_surf)
-      return EGL_NO_SURFACE;
-
-   if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_PBUFFER_BIT,
-                        &xdri_config->Base, attrib_list)) {
-      free(xdri_surf);
-      return EGL_FALSE;
-   }
-
-   /* Create a dummy X window */
-   {
-      Window root = RootWindow(disp->Xdpy, scrn);
-      XSetWindowAttributes attr;
-      XVisualInfo *visInfo, visTemplate;
-      unsigned mask;
-      int nvis;
-
-      visTemplate.visualid = xdri_config->mode->visualID;
-      visInfo = XGetVisualInfo(disp->Xdpy, VisualIDMask, &visTemplate, &nvis);
-      if (!visInfo) {
-         return EGL_NO_SURFACE;
-      }
-
-      attr.background_pixel = 0;
-      attr.border_pixel = 0;
-      attr.colormap = XCreateColormap(disp->Xdpy, root,
-                                      visInfo->visual, AllocNone);
-      attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
-      mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
-      
-      window = XCreateWindow(disp->Xdpy, root, 0, 0,
-                             xdri_surf->Base.Width, xdri_surf->Base.Height,
-                             0, visInfo->depth, InputOutput,
-                             visInfo->visual, mask, &attr);
-
-      /*XMapWindow(disp->Xdpy, window);*/
-      XFree(visInfo);
-
-      /* set hints and properties */
-      /*
-      sizehints.width = xdri_surf->Base.Width;
-      sizehints.height = xdri_surf->Base.Height;
-      sizehints.flags = USPosition;
-      XSetNormalHints(disp->Xdpy, window, &sizehints);
-      */
-   }
-
-   if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) {
-      free(xdri_surf);
-      return EGL_FALSE;
-   }
-
-   xdri_surf->driDrawable = window;
-
-   _eglLinkSurface(&xdri_surf->Base, disp);
-
-   _eglLog(_EGL_DEBUG,
-           "XDRI: CreatePbufferSurface handle %d  hDrawable %d",
-           _eglGetSurfaceHandle(&xdri_surf->Base),
-           (int) xdri_surf->hDrawable);
-
-   return _eglGetSurfaceHandle(&xdri_surf->Base);
+   return NULL;
 }
 
 
 
 static EGLBoolean
-xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
    struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-   if (xdri_surf) {
-      _eglUnlinkSurface(&xdri_surf->Base);
-      if (!_eglIsSurfaceBound(&xdri_surf->Base)) {
-         /*
-         st_unreference_framebuffer(surf->Framebuffer);
-         */
-         free(xdri_surf);
-      }
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
-      return EGL_FALSE;
+
+   if (!_eglIsSurfaceBound(&xdri_surf->Base)) {
+      xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
+      free(xdri_surf);
    }
+
+   return EGL_TRUE;
 }
 
 
 static EGLBoolean
-xdri_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                      EGLint buffer)
 {
-   typedef int (*bind_teximage)(__DRInativeDisplay *dpy,
-                                __DRIid surface, __DRIscreen *psc,
-                                int buffer, int target, int format,
-                                int level, int mipmap);
-
-   bind_teximage egl_dri_bind_teximage;
-
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
-   struct xdri_egl_context *xdri_ctx = current_context();
-   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-   struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-
-   __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
-
-   __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
-   __DRIscreen *psc = &scrnConf->driScreen;
-
-   /* this call just does error checking */
-   if (!_eglBindTexImage(drv, dpy, surface, buffer)) {
-      return EGL_FALSE;
-   }
-
-   egl_dri_bind_teximage =
-      (bind_teximage) dlsym(NULL, "egl_dri_bind_teximage");
-   if (egl_dri_bind_teximage) {
-      return egl_dri_bind_teximage(disp->Xdpy, dri_surf, psc,
-                                   buffer,
-                                   xdri_surf->Base.TextureTarget,
-                                   xdri_surf->Base.TextureFormat,
-                                   xdri_surf->Base.MipmapLevel,
-                                   xdri_surf->Base.MipmapTexture);
-   }
-   else {
-      /* fallback path based on glCopyTexImage() */
-      /* Get/save currently bound 2D texobj name */
-      glGetIntegerv_t glGetIntegerv_func = 
-         (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
-      GLint curTexObj = 0;
-      if (glGetIntegerv_func) {
-         (*glGetIntegerv_func)(GL_TEXTURE_BINDING_2D, &curTexObj);
-      }
-      xdri_ctx->bound_tex_object = curTexObj;
-   }
-
    return EGL_FALSE;
 }
 
 
 static EGLBoolean
-xdri_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                         EGLint buffer)
 {
-   typedef int (*release_teximage)(__DRInativeDisplay *dpy,
-                                   __DRIid surface, __DRIscreen *psc,
-                                   int buffer, int target, int format,
-                                   int level, int mipmap);
-   release_teximage egl_dri_release_teximage;
-
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
-   struct xdri_egl_context *xdri_ctx = current_context();
-   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-   struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-
-   __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
-
-   __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
-   __DRIscreen *psc = &scrnConf->driScreen;
-
-   /* this call just does error checking */
-   if (!_eglReleaseTexImage(drv, dpy, surface, buffer)) {
-      return EGL_FALSE;
-   }
-
-   egl_dri_release_teximage =
-      (release_teximage) dlsym(NULL, "egl_dri_release_teximage");
-   if (egl_dri_release_teximage) {
-      return egl_dri_release_teximage(disp->Xdpy, dri_surf, psc,
-                                      buffer,
-                                      xdri_surf->Base.TextureTarget,
-                                      xdri_surf->Base.TextureFormat,
-                                      xdri_surf->Base.MipmapLevel,
-                                      xdri_surf->Base.MipmapTexture);
-   }
-   else {
-      /* fallback path based on glCopyTexImage() */
-      glGetIntegerv_t glGetIntegerv_func = 
-         (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
-      glBindTexture_t glBindTexture_func = 
-         (glBindTexture_t) dlsym(NULL, "glBindTexture");
-      glCopyTexImage2D_t glCopyTexImage2D_func = 
-         (glCopyTexImage2D_t) dlsym(NULL, "glCopyTexImage2D");
-      GLint curTexObj;
-      GLenum intFormat;
-      GLint level, width, height;
-
-      if (xdri_surf->Base.TextureFormat == EGL_TEXTURE_RGBA)
-         intFormat = GL_RGBA;
-      else
-         intFormat = GL_RGB;
-      level = xdri_surf->Base.MipmapLevel;
-      width = xdri_surf->Base.Width >> level;
-      height = xdri_surf->Base.Height >> level;
-
-      if (width > 0 && height > 0 &&
-          glGetIntegerv_func && glBindTexture_func && glCopyTexImage2D_func) {
-         glGetIntegerv_func(GL_TEXTURE_BINDING_2D, &curTexObj);
-         /* restore texobj from time of eglBindTexImage() call */
-         if (curTexObj != xdri_ctx->bound_tex_object)
-            glBindTexture_func(GL_TEXTURE_2D, xdri_ctx->bound_tex_object);
-         /* copy pbuffer image to texture */
-         glCopyTexImage2D_func(GL_TEXTURE_2D,
-                               level,
-                               intFormat,
-                               0, 0, width, height, 0);
-         /* restore current texture */
-         if (curTexObj != xdri_ctx->bound_tex_object)
-            glBindTexture_func(GL_TEXTURE_2D, curTexObj);
-      }
-      xdri_ctx->bound_tex_object = -1;
-   }
-
    return EGL_FALSE;
 }
 
 
 static EGLBoolean
-xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+   struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
 
-   _eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers");
+   xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable);
 
-   /* error checking step: */
-   if (!_eglSwapBuffers(drv, dpy, draw))
-      return EGL_FALSE;
+   return EGL_TRUE;
+}
 
-   {
-      struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
-      struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
-      __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
-      __DRIscreen *psc = &scrnConf->driScreen;
-      __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy,
-                                                     xdri_surf->driDrawable,
-                                                     psc->private);
-
-      if (pdraw)
-         pdraw->swapBuffers(disp->Xdpy, pdraw->private);
-      else
-         _eglLog(_EGL_WARNING, "pdraw is null in SwapBuffers");
-   }
 
-   return EGL_TRUE;
+static void
+xdri_Unload(_EGLDriver *drv)
+{
+   struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+   free(xdri_drv);
 }
 
 
@@ -1139,15 +546,12 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
  * Create a new _EGLDriver object and init its dispatch table.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *disp, const char *args)
+_eglMain(const char *args)
 {
    struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver);
    if (!xdri_drv)
       return NULL;
 
-   /* Tell libGL to prefer the EGL drivers over regular DRI drivers */
-   __glXPreferEGL(1);
-
    _eglInitDriverFallbacks(&xdri_drv->Base);
    xdri_drv->Base.API.Initialize = xdri_eglInitialize;
    xdri_drv->Base.API.Terminate = xdri_eglTerminate;
@@ -1155,6 +559,7 @@ _eglMain(_EGLDisplay *disp, const char *args)
    xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress;
 
    xdri_drv->Base.API.CreateContext = xdri_eglCreateContext;
+   xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext;
    xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent;
    xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
    xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface;
@@ -1163,13 +568,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
    xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage;
    xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
 
-   xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT |
-                                    EGL_OPENGL_ES_BIT |
-                                    EGL_OPENGL_ES2_BIT |
-                                    EGL_OPENVG_BIT);
    xdri_drv->Base.Name = "X/DRI";
-
-   _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args);
+   xdri_drv->Base.Unload = xdri_Unload;
 
    return &xdri_drv->Base;
 }
diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c
new file mode 100644 (file)
index 0000000..7775009
--- /dev/null
@@ -0,0 +1,626 @@
+/**
+ * GLX initialization.  Code based on glxext.c, glx_query.c, and
+ * glcontextmodes.c under src/glx/x11/.  The major difference is that no DRI
+ * related code here.
+ *
+ */
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <sys/time.h>
+
+#include "glxinit.h"
+
+typedef struct GLXGenericGetString
+{
+   CARD8 reqType;
+   CARD8 glxCode;
+   CARD16 length B16;
+   CARD32 for_whom B32;
+   CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+/* Extension required boiler plate */
+
+static char *__glXExtensionName = GLX_EXTENSION_NAME;
+static XExtensionInfo *__glXExtensionInfo = NULL;
+
+static /* const */ XExtensionHooks __glXExtensionHooks = { NULL };
+static
+XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
+                           __glXExtensionName, &__glXExtensionHooks,
+                           __GLX_NUMBER_EVENTS, NULL)
+
+static GLint
+_gl_convert_from_x_visual_type(int visualType)
+{
+#define NUM_VISUAL_TYPES   6
+   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;
+}
+
+static __GLcontextModes *
+_gl_context_modes_create(unsigned count, size_t minimum_size)
+{
+   const size_t size = (minimum_size > sizeof(__GLcontextModes))
+      ? minimum_size : sizeof(__GLcontextModes);
+   __GLcontextModes *base = NULL;
+   __GLcontextModes **next;
+   unsigned i;
+
+   next = &base;
+   for (i = 0; i < count; i++) {
+      *next = (__GLcontextModes *) Xmalloc(size);
+      if (*next == NULL) {
+         _gl_context_modes_destroy(base);
+         base = NULL;
+         break;
+      }
+
+      memset(*next, 0, size);
+      (*next)->visualID = GLX_DONT_CARE;
+      (*next)->visualType = GLX_DONT_CARE;
+      (*next)->visualRating = GLX_NONE;
+      (*next)->transparentPixel = GLX_NONE;
+      (*next)->transparentRed = GLX_DONT_CARE;
+      (*next)->transparentGreen = GLX_DONT_CARE;
+      (*next)->transparentBlue = GLX_DONT_CARE;
+      (*next)->transparentAlpha = GLX_DONT_CARE;
+      (*next)->transparentIndex = GLX_DONT_CARE;
+      (*next)->xRenderable = GLX_DONT_CARE;
+      (*next)->fbconfigID = GLX_DONT_CARE;
+      (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+      (*next)->bindToTextureRgb = GLX_DONT_CARE;
+      (*next)->bindToTextureRgba = GLX_DONT_CARE;
+      (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+      (*next)->bindToTextureTargets = GLX_DONT_CARE;
+      (*next)->yInverted = GLX_DONT_CARE;
+
+      next = &((*next)->next);
+   }
+
+   return base;
+}
+
+_X_HIDDEN void
+_gl_context_modes_destroy(__GLcontextModes * modes)
+{
+   while (modes != NULL) {
+      __GLcontextModes *const next = modes->next;
+
+      Xfree(modes);
+      modes = next;
+   }
+}
+
+_X_HIDDEN char *
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
+{
+   xGLXGenericGetStringReq *req;
+   xGLXSingleReply reply;
+   int length;
+   int numbytes;
+   char *buf;
+   CARD32 for_whom = screen;
+   CARD32 glxCode = X_GLXQueryServerString;
+
+
+   LockDisplay(dpy);
+
+
+   /* All of the GLX protocol requests for getting a string from the server
+    * look the same.  The exact meaning of the for_whom field is usually
+    * either the screen number (for glXQueryServerString) or the context tag
+    * (for GLXSingle).
+    */
+
+   GetReq(GLXGenericGetString, req);
+   req->reqType = opcode;
+   req->glxCode = glxCode;
+   req->for_whom = for_whom;
+   req->name = name;
+
+   _XReply(dpy, (xReply *) & reply, 0, False);
+
+   length = reply.length * 4;
+   numbytes = reply.size;
+
+   buf = (char *) Xmalloc(numbytes);
+   if (buf != NULL) {
+      _XRead(dpy, buf, numbytes);
+      length -= numbytes;
+   }
+
+   _XEatData(dpy, length);
+
+   UnlockDisplay(dpy);
+   SyncHandle();
+
+   return buf;
+}
+
+/************************************************************************/
+/*
+** Free the per screen configs data as well as the array of
+** __glXScreenConfigs.
+*/
+static void
+FreeScreenConfigs(__GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+   GLint i, screens;
+
+   /* Free screen configuration information */
+   psc = priv->screenConfigs;
+   screens = ScreenCount(priv->dpy);
+   for (i = 0; i < screens; i++, psc++) {
+      if (psc->configs) {
+         _gl_context_modes_destroy(psc->configs);
+         psc->configs = NULL;   /* NOTE: just for paranoia */
+      }
+      if (psc->visuals) {
+         _gl_context_modes_destroy(psc->visuals);
+         psc->visuals = NULL;   /* NOTE: just for paranoia */
+      }
+      Xfree((char *) psc->serverGLXexts);
+   }
+   XFree((char *) priv->screenConfigs);
+   priv->screenConfigs = NULL;
+}
+
+/************************************************************************/
+
+/*
+** Query the version of the GLX extension.  This procedure works even if
+** the client extension is not completely set up.
+*/
+static Bool
+QueryVersion(Display * dpy, int opcode, int *major, int *minor)
+{
+   xGLXQueryVersionReq *req;
+   xGLXQueryVersionReply reply;
+
+   /* Send the glXQueryVersion request */
+   LockDisplay(dpy);
+   GetReq(GLXQueryVersion, req);
+   req->reqType = opcode;
+   req->glxCode = X_GLXQueryVersion;
+   req->majorVersion = GLX_MAJOR_VERSION;
+   req->minorVersion = GLX_MINOR_VERSION;
+   _XReply(dpy, (xReply *) & reply, 0, False);
+   UnlockDisplay(dpy);
+   SyncHandle();
+
+   if (reply.majorVersion != GLX_MAJOR_VERSION) {
+      /*
+       ** The server does not support the same major release as this
+       ** client.
+       */
+      return GL_FALSE;
+   }
+   *major = reply.majorVersion;
+   *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
+   return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
+                                    const INT32 * bp, Bool tagged_only,
+                                    Bool fbconfig_style_tags)
+{
+   int i;
+
+   if (!tagged_only) {
+      /* Copy in the first set of properties */
+      config->visualID = *bp++;
+
+      config->visualType = _gl_convert_from_x_visual_type(*bp++);
+
+      config->rgbMode = *bp++;
+
+      config->redBits = *bp++;
+      config->greenBits = *bp++;
+      config->blueBits = *bp++;
+      config->alphaBits = *bp++;
+      config->accumRedBits = *bp++;
+      config->accumGreenBits = *bp++;
+      config->accumBlueBits = *bp++;
+      config->accumAlphaBits = *bp++;
+
+      config->doubleBufferMode = *bp++;
+      config->stereoMode = *bp++;
+
+      config->rgbBits = *bp++;
+      config->depthBits = *bp++;
+      config->stencilBits = *bp++;
+      config->numAuxBuffers = *bp++;
+      config->level = *bp++;
+
+      count -= __GLX_MIN_CONFIG_PROPS;
+   }
+
+   /*
+    ** Additional properties may be in a list at the end
+    ** of the reply.  They are in pairs of property type
+    ** and property value.
+    */
+
+#define FETCH_OR_SET(tag) \
+    config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
+
+   for (i = 0; i < count; i += 2) {
+      switch (*bp++) {
+      case GLX_RGBA:
+         FETCH_OR_SET(rgbMode);
+         break;
+      case GLX_BUFFER_SIZE:
+         config->rgbBits = *bp++;
+         break;
+      case GLX_LEVEL:
+         config->level = *bp++;
+         break;
+      case GLX_DOUBLEBUFFER:
+         FETCH_OR_SET(doubleBufferMode);
+         break;
+      case GLX_STEREO:
+         FETCH_OR_SET(stereoMode);
+         break;
+      case GLX_AUX_BUFFERS:
+         config->numAuxBuffers = *bp++;
+         break;
+      case GLX_RED_SIZE:
+         config->redBits = *bp++;
+         break;
+      case GLX_GREEN_SIZE:
+         config->greenBits = *bp++;
+         break;
+      case GLX_BLUE_SIZE:
+         config->blueBits = *bp++;
+         break;
+      case GLX_ALPHA_SIZE:
+         config->alphaBits = *bp++;
+         break;
+      case GLX_DEPTH_SIZE:
+         config->depthBits = *bp++;
+         break;
+      case GLX_STENCIL_SIZE:
+         config->stencilBits = *bp++;
+         break;
+      case GLX_ACCUM_RED_SIZE:
+         config->accumRedBits = *bp++;
+         break;
+      case GLX_ACCUM_GREEN_SIZE:
+         config->accumGreenBits = *bp++;
+         break;
+      case GLX_ACCUM_BLUE_SIZE:
+         config->accumBlueBits = *bp++;
+         break;
+      case GLX_ACCUM_ALPHA_SIZE:
+         config->accumAlphaBits = *bp++;
+         break;
+      case GLX_VISUAL_CAVEAT_EXT:
+         config->visualRating = *bp++;
+         break;
+      case GLX_X_VISUAL_TYPE:
+         config->visualType = *bp++;
+         break;
+      case GLX_TRANSPARENT_TYPE:
+         config->transparentPixel = *bp++;
+         break;
+      case GLX_TRANSPARENT_INDEX_VALUE:
+         config->transparentIndex = *bp++;
+         break;
+      case GLX_TRANSPARENT_RED_VALUE:
+         config->transparentRed = *bp++;
+         break;
+      case GLX_TRANSPARENT_GREEN_VALUE:
+         config->transparentGreen = *bp++;
+         break;
+      case GLX_TRANSPARENT_BLUE_VALUE:
+         config->transparentBlue = *bp++;
+         break;
+      case GLX_TRANSPARENT_ALPHA_VALUE:
+         config->transparentAlpha = *bp++;
+         break;
+      case GLX_VISUAL_ID:
+         config->visualID = *bp++;
+         break;
+      case GLX_DRAWABLE_TYPE:
+         config->drawableType = *bp++;
+         break;
+      case GLX_RENDER_TYPE:
+         config->renderType = *bp++;
+         break;
+      case GLX_X_RENDERABLE:
+         config->xRenderable = *bp++;
+         break;
+      case GLX_FBCONFIG_ID:
+         config->fbconfigID = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_WIDTH:
+         config->maxPbufferWidth = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_HEIGHT:
+         config->maxPbufferHeight = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_PIXELS:
+         config->maxPbufferPixels = *bp++;
+         break;
+      case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+         config->optimalPbufferWidth = *bp++;
+         break;
+      case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+         config->optimalPbufferHeight = *bp++;
+         break;
+      case GLX_VISUAL_SELECT_GROUP_SGIX:
+         config->visualSelectGroup = *bp++;
+         break;
+      case GLX_SWAP_METHOD_OML:
+         config->swapMethod = *bp++;
+         break;
+      case GLX_SAMPLE_BUFFERS_SGIS:
+         config->sampleBuffers = *bp++;
+         break;
+      case GLX_SAMPLES_SGIS:
+         config->samples = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_RGB_EXT:
+         config->bindToTextureRgb = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+         config->bindToTextureRgba = *bp++;
+         break;
+      case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+         config->bindToMipmapTexture = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+         config->bindToTextureTargets = *bp++;
+         break;
+      case GLX_Y_INVERTED_EXT:
+         config->yInverted = *bp++;
+         break;
+      case None:
+         i = count;
+         break;
+      default:
+         break;
+      }
+   }
+
+   config->renderType =
+      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+
+   config->haveAccumBuffer = ((config->accumRedBits +
+                               config->accumGreenBits +
+                               config->accumBlueBits +
+                               config->accumAlphaBits) > 0);
+   config->haveDepthBuffer = (config->depthBits > 0);
+   config->haveStencilBuffer = (config->stencilBits > 0);
+}
+
+static __GLcontextModes *
+createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
+                            int screen, GLboolean tagged_only)
+{
+   INT32 buf[__GLX_TOTAL_CONFIG], *props;
+   unsigned prop_size;
+   __GLcontextModes *modes, *m;
+   int i;
+
+   if (nprops == 0)
+      return NULL;
+
+   /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
+
+   /* Check number of properties */
+   if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+      return NULL;
+
+   /* Allocate memory for our config structure */
+   modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+   if (!modes)
+      return NULL;
+
+   prop_size = nprops * __GLX_SIZE_INT32;
+   if (prop_size <= sizeof(buf))
+      props = buf;
+   else
+      props = Xmalloc(prop_size);
+
+   /* Read each config structure and convert it into our format */
+   m = modes;
+   for (i = 0; i < nvisuals; i++) {
+      _XRead(dpy, (char *) props, prop_size);
+      /* Older X servers don't send this so we default it here. */
+      m->drawableType = GLX_WINDOW_BIT;
+      __glXInitializeVisualConfigFromTags(m, nprops, props,
+                                     tagged_only, GL_TRUE);
+      m->screen = screen;
+      m = m->next;
+   }
+
+   if (props != buf)
+      Xfree(props);
+
+   return modes;
+}
+
+static GLboolean
+getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+   xGLXGetVisualConfigsReq *req;
+   __GLXscreenConfigs *psc;
+   xGLXGetVisualConfigsReply reply;
+
+   LockDisplay(dpy);
+
+   psc = priv->screenConfigs + screen;
+   psc->visuals = NULL;
+   GetReq(GLXGetVisualConfigs, req);
+   req->reqType = priv->majorOpcode;
+   req->glxCode = X_GLXGetVisualConfigs;
+   req->screen = screen;
+
+   if (!_XReply(dpy, (xReply *) & reply, 0, False))
+      goto out;
+
+   psc->visuals = createConfigsFromProperties(dpy,
+                                              reply.numVisuals,
+                                              reply.numProps,
+                                              screen, GL_FALSE);
+
+ out:
+   UnlockDisplay(dpy);
+   return psc->visuals != NULL;
+}
+
+static GLboolean
+getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+   xGLXGetFBConfigsReq *fb_req;
+   xGLXGetFBConfigsSGIXReq *sgi_req;
+   xGLXVendorPrivateWithReplyReq *vpreq;
+   xGLXGetFBConfigsReply reply;
+   __GLXscreenConfigs *psc;
+
+   psc = priv->screenConfigs + screen;
+   psc->serverGLXexts =
+      __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+
+   LockDisplay(dpy);
+
+   psc->configs = NULL;
+   if (atof(priv->serverGLXversion) >= 1.3) {
+      GetReq(GLXGetFBConfigs, fb_req);
+      fb_req->reqType = priv->majorOpcode;
+      fb_req->glxCode = X_GLXGetFBConfigs;
+      fb_req->screen = screen;
+   }
+   else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+      GetReqExtra(GLXVendorPrivateWithReply,
+                  sz_xGLXGetFBConfigsSGIXReq +
+                  sz_xGLXVendorPrivateWithReplyReq, vpreq);
+      sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+      sgi_req->reqType = priv->majorOpcode;
+      sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+      sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+      sgi_req->screen = screen;
+   }
+   else
+      goto out;
+
+   if (!_XReply(dpy, (xReply *) & reply, 0, False))
+      goto out;
+
+   psc->configs = createConfigsFromProperties(dpy,
+                                              reply.numFBConfigs,
+                                              reply.numAttribs * 2,
+                                              screen, GL_TRUE);
+
+ out:
+   UnlockDisplay(dpy);
+   return psc->configs != NULL;
+}
+
+static GLboolean
+AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+   GLint i, screens;
+
+   /*
+    ** First allocate memory for the array of per screen configs.
+    */
+   screens = ScreenCount(dpy);
+   psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
+   if (!psc) {
+      return GL_FALSE;
+   }
+   memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
+   priv->screenConfigs = psc;
+
+   priv->serverGLXversion =
+      __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
+   if (priv->serverGLXversion == NULL) {
+      FreeScreenConfigs(priv);
+      return GL_FALSE;
+   }
+
+   for (i = 0; i < screens; i++, psc++) {
+      getFBConfigs(dpy, priv, i);
+      getVisualConfigs(dpy, priv, i);
+      psc->scr = i;
+      psc->dpy = dpy;
+   }
+
+   SyncHandle();
+
+   return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXRelease(__GLXdisplayPrivate *dpyPriv)
+{
+   FreeScreenConfigs(dpyPriv);
+
+   if (dpyPriv->serverGLXvendor) {
+      Xfree((char *) dpyPriv->serverGLXvendor);
+      dpyPriv->serverGLXvendor = NULL;
+   }
+   if (dpyPriv->serverGLXversion) {
+      Xfree((char *) dpyPriv->serverGLXversion);
+      dpyPriv->serverGLXversion = NULL;
+   }
+
+   Xfree(dpyPriv);
+}
+
+_X_HIDDEN __GLXdisplayPrivate *
+__glXInitialize(Display * dpy)
+{
+   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+   __GLXdisplayPrivate *dpyPriv;
+   int major, minor;
+
+   if (!XextHasExtension(info))
+      return NULL;
+
+   /* See if the versions are compatible */
+   if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
+      return NULL;
+
+   dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
+   if (!dpyPriv)
+      return NULL;
+
+   /*
+    ** Init the display private and then read in the screen config
+    ** structures from the server.
+    */
+   dpyPriv->majorOpcode = info->codes->major_opcode;
+   dpyPriv->majorVersion = major;
+   dpyPriv->minorVersion = minor;
+   dpyPriv->dpy = dpy;
+
+   dpyPriv->serverGLXvendor = NULL;
+   dpyPriv->serverGLXversion = NULL;
+
+   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+      Xfree(dpyPriv);
+      return NULL;
+   }
+
+   return dpyPriv;
+}
diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h
new file mode 100644 (file)
index 0000000..57206e6
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef GLXINIT_INCLUDED
+#define GLXINIT_INCLUDED
+
+#include <X11/Xlib.h>
+#include "glxclient.h"
+
+/* this is used by DRI loaders */
+extern void
+_gl_context_modes_destroy(__GLcontextModes * modes);
+
+extern void
+__glXRelease(__GLXdisplayPrivate *dpyPriv);
+
+#endif /* GLXINIT_INCLUDED */