From 57a879849643e79d9674198a3a77c59532fb79b4 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Thu, 28 Apr 2011 07:58:00 +0000
Subject: xserver xkeyboard-config mesa git update 28 Apr 2011

---
 xorg-server/glx/glapi.c    | 1022 ++++++++++---------
 xorg-server/glx/glapi.h    |  285 +++---
 xorg-server/glx/glthread.h |    3 +-
 xorg-server/glx/glxdri.c   | 2327 ++++++++++++++++++++++----------------------
 4 files changed, 1821 insertions(+), 1816 deletions(-)

(limited to 'xorg-server/glx')

diff --git a/xorg-server/glx/glapi.c b/xorg-server/glx/glapi.c
index d5275dc81..9e219f680 100644
--- a/xorg-server/glx/glapi.c
+++ b/xorg-server/glx/glapi.c
@@ -1,512 +1,510 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * This file manages the OpenGL API dispatch layer.  There are functions
- * to set/get the current dispatch table for the current thread and to
- * manage registration/dispatch of dynamically added extension functions.
- *
- * This code was originally general enough to be shared with Mesa, but
- * they diverged long ago, so this is now just enough support to make
- * indirect GLX work.
- */
-
-#include <dix-config.h>
-#include <X11/Xfuncproto.h>
-#include <os.h>
-#define PUBLIC _X_EXPORT
-
-#include <stdlib.h>
-#include <string.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include "glapi.h"
-#include "glapioffsets.h"
-#include "glapitable.h"
-
-#if defined(PTHREADS) || defined(GLX_USE_TLS)
-static void init_glapi_relocs(void);
-#endif
-
-/**
- * \name Current dispatch and current context control variables
- *
- * Depending on whether or not multithreading is support, and the type of
- * support available, several variables are used to store the current context
- * pointer and the current dispatch table pointer.  In the non-threaded case,
- * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
- * purpose.
- *
- * In the "normal" threaded case, the variables \c _glapi_Dispatch and
- * \c _glapi_Context will be \c NULL if an application is detected as being
- * multithreaded.  Single-threaded applications will use \c _glapi_Dispatch
- * and \c _glapi_Context just like the case without any threading support.
- * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
- * data \c _gl_DispatchTSD and \c ContextTSD are used.  Drivers and the
- * static dispatch functions access these variables via \c _glapi_get_dispatch
- * and \c _glapi_get_context.
- *
- * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
- * hardcoded to \c NULL.  Instead the TLS variables \c _glapi_tls_Dispatch and
- * \c _glapi_tls_Context are used.  Having \c _glapi_Dispatch and
- * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
- * between TLS enabled loaders and non-TLS DRI drivers.
- */
-/*@{*/
-#if defined(GLX_USE_TLS)
-
-PUBLIC TLS struct _glapi_table * _glapi_tls_Dispatch
-    __attribute__((tls_model("initial-exec"))) = NULL;
-
-PUBLIC TLS void * _glapi_tls_Context
-    __attribute__((tls_model("initial-exec")));
-
-PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL;
-PUBLIC const void *_glapi_Context = NULL;
-
-#else
-
-#if defined(THREADS)
-
-_glthread_TSD _gl_DispatchTSD;           /**< Per-thread dispatch pointer */
-static _glthread_TSD ContextTSD;         /**< Per-thread context pointer */
-
-#if defined(WIN32_THREADS)
-void FreeTSD(_glthread_TSD *p);
-void FreeAllTSD(void)
-{
-   FreeTSD(&_gl_DispatchTSD);
-   FreeTSD(&ContextTSD);
-}
-#endif /* defined(WIN32_THREADS) */
-
-#endif /* defined(THREADS) */
-
-PUBLIC struct _glapi_table *_glapi_Dispatch = NULL;
-PUBLIC void *_glapi_Context = NULL;
-
-#endif /* defined(GLX_USE_TLS) */
-/*@}*/
-
-/*
- * xserver's gl is not multithreaded, we promise.
- */
-PUBLIC void
-_glapi_check_multithread(void)
-{
-}
-
-/**
- * Set the current context pointer for this thread.
- * The context pointer is an opaque type which should be cast to
- * void from the real context pointer type.
- */
-PUBLIC void
-_glapi_set_context(void *context)
-{
-#if defined(GLX_USE_TLS)
-   _glapi_tls_Context = context;
-#elif defined(THREADS)
-   _glthread_SetTSD(&ContextTSD, context);
-   _glapi_Context = context;
-#else
-   _glapi_Context = context;
-#endif
-}
-
-
-
-/**
- * Get the current context pointer for this thread.
- * The context pointer is an opaque type which should be cast from
- * void to the real context pointer type.
- */
-PUBLIC void *
-_glapi_get_context(void)
-{
-#if defined(GLX_USE_TLS)
-   return _glapi_tls_Context;
-#else
-   return _glapi_Context;
-#endif
-}
-
-
-
-/**
- * Set the global or per-thread dispatch table pointer.
- */
-PUBLIC void
-_glapi_set_dispatch(struct _glapi_table *dispatch)
-{
-#if defined(PTHREADS) || defined(GLX_USE_TLS)
-   static pthread_once_t once_control = PTHREAD_ONCE_INIT;
-   pthread_once( & once_control, init_glapi_relocs );
-#endif
-
-#if defined(GLX_USE_TLS)
-   _glapi_tls_Dispatch = dispatch;
-#elif defined(THREADS)
-   _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
-   _glapi_Dispatch = dispatch;
-#else /*THREADS*/
-   _glapi_Dispatch = dispatch;
-#endif /*THREADS*/
-}
-
-
-
-/**
- * Return pointer to current dispatch table for calling thread.
- */
-PUBLIC struct _glapi_table *
-_glapi_get_dispatch(void)
-{
-   struct _glapi_table * api;
-#if defined(GLX_USE_TLS)
-   api = _glapi_tls_Dispatch;
-#else
-   api = _glapi_Dispatch;
-#endif
-   return api;
-}
-
-
-
-/***
- *** The rest of this file is pretty much concerned with GetProcAddress
- *** functionality.
- ***/
-
-#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
-# define DISPATCH_FUNCTION_SIZE  16
-#elif defined(USE_X86_ASM)
-# if defined(THREADS) && !defined(GLX_USE_TLS)
-#  define DISPATCH_FUNCTION_SIZE  32
-# else
-#  define DISPATCH_FUNCTION_SIZE  16
-# endif
-#endif
-
-
-/* The code in this file is auto-generated with Python */
-#include "glprocs.h"
-
-
-/**
- * Search the table of static entrypoint functions for the named function
- * and return the corresponding glprocs_table_t entry.
- */
-static const glprocs_table_t *
-find_entry( const char * n )
-{
-   GLuint i;
-   for (i = 0; static_functions[i].Name_offset >= 0; i++) {
-      const char *testName = gl_string_table + static_functions[i].Name_offset;
-      if (strcmp(testName, n) == 0) {
-	 return &static_functions[i];
-      }
-   }
-   return NULL;
-}
-
-
-/**
- * Return dispatch table offset of the named static (built-in) function.
- * Return -1 if function not found.
- */
-static GLint
-get_static_proc_offset(const char *funcName)
-{
-   const glprocs_table_t * const f = find_entry( funcName );
-   if (f) {
-      return f->Offset;
-   }
-   return -1;
-}
-
-
-
-/**********************************************************************
- * Extension function management.
- */
-
-/*
- * Number of extension functions which we can dynamically add at runtime.
- */
-#define MAX_EXTENSION_FUNCS 300
-
-
-/*
- * The dispatch table size (number of entries) is the size of the
- * _glapi_table struct plus the number of dynamic entries we can add.
- * The extra slots can be filled in by DRI drivers that register new extension
- * functions.
- */
-#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)
-
-
-/**
- * Track information about a function added to the GL API.
- */
-struct _glapi_function {
-   /**
-    * Name of the function.
-    */
-   const char * name;
-
-   /**
-    * Text string that describes the types of the parameters passed to the
-    * named function.   Parameter types are converted to characters using the
-    * following rules:
-    *   - 'i' for \c GLint, \c GLuint, and \c GLenum
-    *   - 'p' for any pointer type
-    *   - 'f' for \c GLfloat and \c GLclampf
-    *   - 'd' for \c GLdouble and \c GLclampd
-    */
-   const char * parameter_signature;
-
-   /**
-    * Offset in the dispatch table where the pointer to the real function is
-    * located.  If the driver has not requested that the named function be
-    * added to the dispatch table, this will have the value ~0.
-    */
-   unsigned dispatch_offset;
-};
-
-static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS];
-static GLuint NumExtEntryPoints = 0;
-
-/**
- * Generate new entrypoint
- *
- * Use a temporary dispatch offset of ~0 (i.e. -1).  Later, when the driver
- * calls \c _glapi_add_dispatch we'll put in the proper offset.  If that
- * never happens, and the user calls this function, he'll segfault.  That's
- * what you get when you try calling a GL function that doesn't really exist.
- * 
- * \param funcName  Name of the function to create an entry-point for.
- * 
- * \sa _glapi_add_entrypoint
- */
-
-static struct _glapi_function *
-add_function_name( const char * funcName )
-{
-   struct _glapi_function * entry = NULL;
-   
-   if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) {
-      entry = &ExtEntryTable[NumExtEntryPoints];
-
-      ExtEntryTable[NumExtEntryPoints].name = strdup(funcName);
-      ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL;
-      ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0;
-      NumExtEntryPoints++;
-   }
-
-   return entry;
-}
-
-
-/**
- * Fill-in the dispatch stub for the named function.
- * 
- * This function is intended to be called by a hardware driver.  When called,
- * a dispatch stub may be created created for the function.  A pointer to this
- * dispatch function will be returned by glXGetProcAddress.
- *
- * \param function_names       Array of pointers to function names that should
- *                             share a common dispatch offset.
- * \param parameter_signature  String representing the types of the parameters
- *                             passed to the named function.  Parameter types
- *                             are converted to characters using the following
- *                             rules:
- *                               - 'i' for \c GLint, \c GLuint, and \c GLenum
- *                               - 'p' for any pointer type
- *                               - 'f' for \c GLfloat and \c GLclampf
- *                               - 'd' for \c GLdouble and \c GLclampd
- *
- * \returns
- * The offset in the dispatch table of the named function.  A pointer to the
- * driver's implementation of the named function should be stored at
- * \c dispatch_table[\c offset].
- *
- * \sa glXGetProcAddress
- *
- * \warning
- * This function can only handle up to 8 names at a time.  As far as I know,
- * the maximum number of names ever associated with an existing GL function is
- * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
- * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
- * too painful of a limitation.
- *
- * \todo
- * Determine whether or not \c parameter_signature should be allowed to be
- * \c NULL.  It doesn't seem like much of a hardship for drivers to have to
- * pass in an empty string.
- *
- * \todo
- * Determine if code should be added to reject function names that start with
- * 'glX'.
- * 
- * \bug
- * Add code to compare \c parameter_signature with the parameter signature of
- * a static function.  In order to do that, we need to find a way to \b get
- * the parameter signature of a static function.
- */
-
-PUBLIC int
-_glapi_add_dispatch( const char * const * function_names,
-		     const char * parameter_signature )
-{
-   static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC;
-   const char * const real_sig = (parameter_signature != NULL)
-     ? parameter_signature : "";
-   struct _glapi_function * entry[8];
-   GLboolean is_static[8];
-   unsigned i;
-   unsigned j;
-   int offset = ~0;
-   int new_offset;
-
-
-   (void) memset(is_static, 0, sizeof(is_static));
-   (void) memset(entry, 0, sizeof(entry));
-
-   for (i = 0 ; function_names[i] != NULL ; i++) {
-      /* Do some trivial validation on the name of the function. */
-
-      if (function_names[i][0] != 'g' || function_names[i][1] != 'l')
-	return GL_FALSE;
-   
-      /* Determine if the named function already exists.  If the function does
-       * exist, it must have the same parameter signature as the function
-       * being added.
-       */
-
-      new_offset = get_static_proc_offset(function_names[i]);
-      if (new_offset >= 0) {
-	 /* FIXME: Make sure the parameter signatures match!  How do we get
-	  * FIXME: the parameter signature for static functions?
-	  */
-
-	 if ((offset != ~0) && (new_offset != offset)) {
-	    return -1;
-	 }
-
-	 is_static[i] = GL_TRUE;
-	 offset = new_offset;
-      }
-   
-      for (j = 0; j < NumExtEntryPoints; j++) {
-	 if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) {
-	    /* The offset may be ~0 if the function name was added by
-	     * glXGetProcAddress but never filled in by the driver.
-	     */
-
-	    if (ExtEntryTable[j].dispatch_offset != ~0) {
-	       if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) != 0)
-		  return -1;
-
-	       if ((offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset)) {
-		  return -1;
-	       }
-
-	       offset = ExtEntryTable[j].dispatch_offset;
-	    }
-	    
-	    entry[i] = & ExtEntryTable[j];
-	    break;
-	 }
-      }
-   }
-
-   if (offset == ~0) {
-      offset = next_dynamic_offset;
-      next_dynamic_offset++;
-   }
-
-   for (i = 0 ; function_names[i] != NULL ; i++) {
-      if (!is_static[i]) {
-	 if (entry[i] == NULL) {
-	    entry[i] = add_function_name(function_names[i]);
-	    if (entry[i] == NULL)
-	       return -1;
-	 }
-
-	 entry[i]->parameter_signature = strdup(real_sig);
-	 entry[i]->dispatch_offset = offset;
-      }
-   }
-   
-   return offset;
-}
-
-/*
- * glXGetProcAddress doesn't exist in the protocol, the drivers never call
- * this themselves, and neither does the server.  warn if it happens though.
- */
-PUBLIC _glapi_proc
-_glapi_get_proc_address(const char *funcName)
-{
-    ErrorF("_glapi_get_proc_address called!\n");
-    return NULL;
-}
-
-/**
- * Return size of dispatch table struct as number of functions (or
- * slots).
- */
-PUBLIC GLuint
-_glapi_get_dispatch_table_size(void)
-{
-   return DISPATCH_TABLE_SIZE;
-}
-
-#if defined(PTHREADS) || defined(GLX_USE_TLS)
-/**
- * Perform platform-specific GL API entry-point fixups.
- */
-static void
-init_glapi_relocs( void )
-{
-#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
-    extern unsigned long _x86_get_dispatch(void);
-    char run_time_patch[] = {
-       0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
-    };
-    GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
-    const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
-    GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
-
-    *offset = _x86_get_dispatch();
-    while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
-	(void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
-	curr_func += DISPATCH_FUNCTION_SIZE;
-    }
-#endif
-}
-#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * This file manages the OpenGL API dispatch layer.  There are functions
+ * to set/get the current dispatch table for the current thread and to
+ * manage registration/dispatch of dynamically added extension functions.
+ *
+ * This code was originally general enough to be shared with Mesa, but
+ * they diverged long ago, so this is now just enough support to make
+ * indirect GLX work.
+ */
+
+#include <dix-config.h>
+#include <X11/Xfuncproto.h>
+#include <os.h>
+#define PUBLIC _X_EXPORT
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include "glapi.h"
+#include "glapioffsets.h"
+#include "glapitable.h"
+
+#if defined(PTHREADS) || defined(GLX_USE_TLS)
+static void init_glapi_relocs(void);
+#endif
+
+/**
+ * \name Current dispatch and current context control variables
+ *
+ * Depending on whether or not multithreading is support, and the type of
+ * support available, several variables are used to store the current context
+ * pointer and the current dispatch table pointer.  In the non-threaded case,
+ * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
+ * purpose.
+ *
+ * In the "normal" threaded case, the variables \c _glapi_Dispatch and
+ * \c _glapi_Context will be \c NULL if an application is detected as being
+ * multithreaded.  Single-threaded applications will use \c _glapi_Dispatch
+ * and \c _glapi_Context just like the case without any threading support.
+ * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
+ * data \c _gl_DispatchTSD and \c ContextTSD are used.  Drivers and the
+ * static dispatch functions access these variables via \c _glapi_get_dispatch
+ * and \c _glapi_get_context.
+ *
+ * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
+ * hardcoded to \c NULL.  Instead the TLS variables \c _glapi_tls_Dispatch and
+ * \c _glapi_tls_Context are used.  Having \c _glapi_Dispatch and
+ * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
+ * between TLS enabled loaders and non-TLS DRI drivers.
+ */
+/*@{*/
+#if defined(GLX_USE_TLS)
+
+PUBLIC TLS struct _glapi_table * _glapi_tls_Dispatch = NULL;
+
+PUBLIC TLS void * _glapi_tls_Context;
+
+PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL;
+PUBLIC const void *_glapi_Context = NULL;
+
+#else
+
+#if defined(THREADS)
+
+_glthread_TSD _gl_DispatchTSD;           /**< Per-thread dispatch pointer */
+static _glthread_TSD ContextTSD;         /**< Per-thread context pointer */
+
+#if defined(WIN32_THREADS)
+void FreeTSD(_glthread_TSD *p);
+void FreeAllTSD(void)
+{
+   FreeTSD(&_gl_DispatchTSD);
+   FreeTSD(&ContextTSD);
+}
+#endif /* defined(WIN32_THREADS) */
+
+#endif /* defined(THREADS) */
+
+PUBLIC struct _glapi_table *_glapi_Dispatch = NULL;
+PUBLIC void *_glapi_Context = NULL;
+
+#endif /* defined(GLX_USE_TLS) */
+/*@}*/
+
+/*
+ * xserver's gl is not multithreaded, we promise.
+ */
+PUBLIC void
+_glapi_check_multithread(void)
+{
+}
+
+/**
+ * Set the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast to
+ * void from the real context pointer type.
+ */
+PUBLIC void
+_glapi_set_context(void *context)
+{
+#if defined(GLX_USE_TLS)
+   _glapi_tls_Context = context;
+#elif defined(THREADS)
+   _glthread_SetTSD(&ContextTSD, context);
+   _glapi_Context = context;
+#else
+   _glapi_Context = context;
+#endif
+}
+
+
+
+/**
+ * Get the current context pointer for this thread.
+ * The context pointer is an opaque type which should be cast from
+ * void to the real context pointer type.
+ */
+PUBLIC void *
+_glapi_get_context(void)
+{
+#if defined(GLX_USE_TLS)
+   return _glapi_tls_Context;
+#else
+   return _glapi_Context;
+#endif
+}
+
+
+
+/**
+ * Set the global or per-thread dispatch table pointer.
+ */
+PUBLIC void
+_glapi_set_dispatch(struct _glapi_table *dispatch)
+{
+#if defined(PTHREADS) || defined(GLX_USE_TLS)
+   static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+   pthread_once( & once_control, init_glapi_relocs );
+#endif
+
+#if defined(GLX_USE_TLS)
+   _glapi_tls_Dispatch = dispatch;
+#elif defined(THREADS)
+   _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
+   _glapi_Dispatch = dispatch;
+#else /*THREADS*/
+   _glapi_Dispatch = dispatch;
+#endif /*THREADS*/
+}
+
+
+
+/**
+ * Return pointer to current dispatch table for calling thread.
+ */
+PUBLIC struct _glapi_table *
+_glapi_get_dispatch(void)
+{
+   struct _glapi_table * api;
+#if defined(GLX_USE_TLS)
+   api = _glapi_tls_Dispatch;
+#else
+   api = _glapi_Dispatch;
+#endif
+   return api;
+}
+
+
+
+/***
+ *** The rest of this file is pretty much concerned with GetProcAddress
+ *** functionality.
+ ***/
+
+#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
+# define DISPATCH_FUNCTION_SIZE  16
+#elif defined(USE_X86_ASM)
+# if defined(THREADS) && !defined(GLX_USE_TLS)
+#  define DISPATCH_FUNCTION_SIZE  32
+# else
+#  define DISPATCH_FUNCTION_SIZE  16
+# endif
+#endif
+
+
+/* The code in this file is auto-generated with Python */
+#include "glprocs.h"
+
+
+/**
+ * Search the table of static entrypoint functions for the named function
+ * and return the corresponding glprocs_table_t entry.
+ */
+static const glprocs_table_t *
+find_entry( const char * n )
+{
+   GLuint i;
+   for (i = 0; static_functions[i].Name_offset >= 0; i++) {
+      const char *testName = gl_string_table + static_functions[i].Name_offset;
+      if (strcmp(testName, n) == 0) {
+	 return &static_functions[i];
+      }
+   }
+   return NULL;
+}
+
+
+/**
+ * Return dispatch table offset of the named static (built-in) function.
+ * Return -1 if function not found.
+ */
+static GLint
+get_static_proc_offset(const char *funcName)
+{
+   const glprocs_table_t * const f = find_entry( funcName );
+   if (f) {
+      return f->Offset;
+   }
+   return -1;
+}
+
+
+
+/**********************************************************************
+ * Extension function management.
+ */
+
+/*
+ * Number of extension functions which we can dynamically add at runtime.
+ */
+#define MAX_EXTENSION_FUNCS 300
+
+
+/*
+ * The dispatch table size (number of entries) is the size of the
+ * _glapi_table struct plus the number of dynamic entries we can add.
+ * The extra slots can be filled in by DRI drivers that register new extension
+ * functions.
+ */
+#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)
+
+
+/**
+ * Track information about a function added to the GL API.
+ */
+struct _glapi_function {
+   /**
+    * Name of the function.
+    */
+   const char * name;
+
+   /**
+    * Text string that describes the types of the parameters passed to the
+    * named function.   Parameter types are converted to characters using the
+    * following rules:
+    *   - 'i' for \c GLint, \c GLuint, and \c GLenum
+    *   - 'p' for any pointer type
+    *   - 'f' for \c GLfloat and \c GLclampf
+    *   - 'd' for \c GLdouble and \c GLclampd
+    */
+   const char * parameter_signature;
+
+   /**
+    * Offset in the dispatch table where the pointer to the real function is
+    * located.  If the driver has not requested that the named function be
+    * added to the dispatch table, this will have the value ~0.
+    */
+   unsigned dispatch_offset;
+};
+
+static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS];
+static GLuint NumExtEntryPoints = 0;
+
+/**
+ * Generate new entrypoint
+ *
+ * Use a temporary dispatch offset of ~0 (i.e. -1).  Later, when the driver
+ * calls \c _glapi_add_dispatch we'll put in the proper offset.  If that
+ * never happens, and the user calls this function, he'll segfault.  That's
+ * what you get when you try calling a GL function that doesn't really exist.
+ * 
+ * \param funcName  Name of the function to create an entry-point for.
+ * 
+ * \sa _glapi_add_entrypoint
+ */
+
+static struct _glapi_function *
+add_function_name( const char * funcName )
+{
+   struct _glapi_function * entry = NULL;
+   
+   if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) {
+      entry = &ExtEntryTable[NumExtEntryPoints];
+
+      ExtEntryTable[NumExtEntryPoints].name = strdup(funcName);
+      ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL;
+      ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0;
+      NumExtEntryPoints++;
+   }
+
+   return entry;
+}
+
+
+/**
+ * Fill-in the dispatch stub for the named function.
+ * 
+ * This function is intended to be called by a hardware driver.  When called,
+ * a dispatch stub may be created created for the function.  A pointer to this
+ * dispatch function will be returned by glXGetProcAddress.
+ *
+ * \param function_names       Array of pointers to function names that should
+ *                             share a common dispatch offset.
+ * \param parameter_signature  String representing the types of the parameters
+ *                             passed to the named function.  Parameter types
+ *                             are converted to characters using the following
+ *                             rules:
+ *                               - 'i' for \c GLint, \c GLuint, and \c GLenum
+ *                               - 'p' for any pointer type
+ *                               - 'f' for \c GLfloat and \c GLclampf
+ *                               - 'd' for \c GLdouble and \c GLclampd
+ *
+ * \returns
+ * The offset in the dispatch table of the named function.  A pointer to the
+ * driver's implementation of the named function should be stored at
+ * \c dispatch_table[\c offset].
+ *
+ * \sa glXGetProcAddress
+ *
+ * \warning
+ * This function can only handle up to 8 names at a time.  As far as I know,
+ * the maximum number of names ever associated with an existing GL function is
+ * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
+ * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
+ * too painful of a limitation.
+ *
+ * \todo
+ * Determine whether or not \c parameter_signature should be allowed to be
+ * \c NULL.  It doesn't seem like much of a hardship for drivers to have to
+ * pass in an empty string.
+ *
+ * \todo
+ * Determine if code should be added to reject function names that start with
+ * 'glX'.
+ * 
+ * \bug
+ * Add code to compare \c parameter_signature with the parameter signature of
+ * a static function.  In order to do that, we need to find a way to \b get
+ * the parameter signature of a static function.
+ */
+
+PUBLIC int
+_glapi_add_dispatch( const char * const * function_names,
+		     const char * parameter_signature )
+{
+   static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC;
+   const char * const real_sig = (parameter_signature != NULL)
+     ? parameter_signature : "";
+   struct _glapi_function * entry[8];
+   GLboolean is_static[8];
+   unsigned i;
+   unsigned j;
+   int offset = ~0;
+   int new_offset;
+
+
+   (void) memset(is_static, 0, sizeof(is_static));
+   (void) memset(entry, 0, sizeof(entry));
+
+   for (i = 0 ; function_names[i] != NULL ; i++) {
+      /* Do some trivial validation on the name of the function. */
+
+      if (function_names[i][0] != 'g' || function_names[i][1] != 'l')
+	return GL_FALSE;
+   
+      /* Determine if the named function already exists.  If the function does
+       * exist, it must have the same parameter signature as the function
+       * being added.
+       */
+
+      new_offset = get_static_proc_offset(function_names[i]);
+      if (new_offset >= 0) {
+	 /* FIXME: Make sure the parameter signatures match!  How do we get
+	  * FIXME: the parameter signature for static functions?
+	  */
+
+	 if ((offset != ~0) && (new_offset != offset)) {
+	    return -1;
+	 }
+
+	 is_static[i] = GL_TRUE;
+	 offset = new_offset;
+      }
+   
+      for (j = 0; j < NumExtEntryPoints; j++) {
+	 if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) {
+	    /* The offset may be ~0 if the function name was added by
+	     * glXGetProcAddress but never filled in by the driver.
+	     */
+
+	    if (ExtEntryTable[j].dispatch_offset != ~0) {
+	       if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) != 0)
+		  return -1;
+
+	       if ((offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset)) {
+		  return -1;
+	       }
+
+	       offset = ExtEntryTable[j].dispatch_offset;
+	    }
+	    
+	    entry[i] = & ExtEntryTable[j];
+	    break;
+	 }
+      }
+   }
+
+   if (offset == ~0) {
+      offset = next_dynamic_offset;
+      next_dynamic_offset++;
+   }
+
+   for (i = 0 ; function_names[i] != NULL ; i++) {
+      if (!is_static[i]) {
+	 if (entry[i] == NULL) {
+	    entry[i] = add_function_name(function_names[i]);
+	    if (entry[i] == NULL)
+	       return -1;
+	 }
+
+	 entry[i]->parameter_signature = strdup(real_sig);
+	 entry[i]->dispatch_offset = offset;
+      }
+   }
+   
+   return offset;
+}
+
+/*
+ * glXGetProcAddress doesn't exist in the protocol, the drivers never call
+ * this themselves, and neither does the server.  warn if it happens though.
+ */
+PUBLIC _glapi_proc
+_glapi_get_proc_address(const char *funcName)
+{
+    ErrorF("_glapi_get_proc_address called!\n");
+    return NULL;
+}
+
+/**
+ * Return size of dispatch table struct as number of functions (or
+ * slots).
+ */
+PUBLIC GLuint
+_glapi_get_dispatch_table_size(void)
+{
+   return DISPATCH_TABLE_SIZE;
+}
+
+#if defined(PTHREADS) || defined(GLX_USE_TLS)
+/**
+ * Perform platform-specific GL API entry-point fixups.
+ */
+static void
+init_glapi_relocs( void )
+{
+#if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
+    extern unsigned long _x86_get_dispatch(void);
+    char run_time_patch[] = {
+       0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
+    };
+    GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
+    const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
+    GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
+
+    *offset = _x86_get_dispatch();
+    while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
+	(void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
+	curr_func += DISPATCH_FUNCTION_SIZE;
+    }
+#endif
+}
+#endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
diff --git a/xorg-server/glx/glapi.h b/xorg-server/glx/glapi.h
index 3a33ccae0..7051c1e3c 100644
--- a/xorg-server/glx/glapi.h
+++ b/xorg-server/glx/glapi.h
@@ -1,143 +1,142 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * \mainpage Mesa GL API Module
- *
- * \section GLAPIIntroduction Introduction
- *
- * The Mesa GL API module is responsible for dispatching all the
- * gl*() functions.  All GL functions are dispatched by jumping through
- * the current dispatch table (basically a struct full of function
- * pointers.)
- *
- * A per-thread current dispatch table and per-thread current context
- * pointer are managed by this module too.
- *
- * This module is intended to be non-Mesa-specific so it can be used
- * with the X/DRI libGL also.
- */
-
-
-#ifndef _GLAPI_H
-#define _GLAPI_H
-
-#define GL_GLEXT_PROTOTYPES
-
-#include "GL/gl.h"
-#include "GL/glext.h"
-#include "glthread.h"
-
-
-struct _glapi_table;
-
-typedef void (*_glapi_proc)(void); /* generic function pointer */
-
-typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...);
-
-
-#if defined(USE_MGL_NAMESPACE)
-#define _glapi_set_dispatch _mglapi_set_dispatch
-#define _glapi_get_dispatch _mglapi_get_dispatch
-#define _glapi_set_context _mglapi_set_context
-#define _glapi_get_context _mglapi_get_context
-#define _glapi_Context _mglapi_Context
-#define _glapi_Dispatch _mglapi_Dispatch
-#endif
-
-
-/*
- * Number of extension functions which we can dynamically add at runtime.
- */
-#define MAX_EXTENSION_FUNCS 300
-
-
-/**
- ** Define the GET_CURRENT_CONTEXT() macro.
- ** \param C local variable which will hold the current context.
- **/
-#if defined (GLX_USE_TLS)
-
-const extern void *_glapi_Context;
-const extern struct _glapi_table *_glapi_Dispatch;
-
-extern TLS void * _glapi_tls_Context
-    __attribute__((tls_model("initial-exec")));
-
-# define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_tls_Context
-
-#else
-
-extern void *_glapi_Context;
-extern struct _glapi_table *_glapi_Dispatch;
-
-# ifdef THREADS
-#  define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())
-# else
-#  define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_Context
-# endif
-
-#endif /* defined (GLX_USE_TLS) */
-
-
-/**
- ** GL API public functions
- **/
-
-extern void
-_glapi_check_multithread(void);
-
-extern void
-_glapi_set_context(void *context);
-
-extern void *
-_glapi_get_context(void);
-
-extern void
-_glapi_set_dispatch(struct _glapi_table *dispatch);
-
-extern struct _glapi_table *
-_glapi_get_dispatch(void);
-
-extern int
-_glapi_begin_dispatch_override(struct _glapi_table *override);
-
-extern void
-_glapi_end_dispatch_override(int layer);
-
-struct _glapi_table *
-_glapi_get_override_dispatch(int layer);
-
-extern GLuint
-_glapi_get_dispatch_table_size(void);
-
-extern int
-_glapi_add_dispatch( const char * const * function_names,
-		     const char * parameter_signature );
-
-extern _glapi_proc
-_glapi_get_proc_address(const char *funcName);
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \mainpage Mesa GL API Module
+ *
+ * \section GLAPIIntroduction Introduction
+ *
+ * The Mesa GL API module is responsible for dispatching all the
+ * gl*() functions.  All GL functions are dispatched by jumping through
+ * the current dispatch table (basically a struct full of function
+ * pointers.)
+ *
+ * A per-thread current dispatch table and per-thread current context
+ * pointer are managed by this module too.
+ *
+ * This module is intended to be non-Mesa-specific so it can be used
+ * with the X/DRI libGL also.
+ */
+
+
+#ifndef _GLAPI_H
+#define _GLAPI_H
+
+#define GL_GLEXT_PROTOTYPES
+
+#include "GL/gl.h"
+#include "GL/glext.h"
+#include "glthread.h"
+
+
+struct _glapi_table;
+
+typedef void (*_glapi_proc)(void); /* generic function pointer */
+
+typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...);
+
+
+#if defined(USE_MGL_NAMESPACE)
+#define _glapi_set_dispatch _mglapi_set_dispatch
+#define _glapi_get_dispatch _mglapi_get_dispatch
+#define _glapi_set_context _mglapi_set_context
+#define _glapi_get_context _mglapi_get_context
+#define _glapi_Context _mglapi_Context
+#define _glapi_Dispatch _mglapi_Dispatch
+#endif
+
+
+/*
+ * Number of extension functions which we can dynamically add at runtime.
+ */
+#define MAX_EXTENSION_FUNCS 300
+
+
+/**
+ ** Define the GET_CURRENT_CONTEXT() macro.
+ ** \param C local variable which will hold the current context.
+ **/
+#if defined (GLX_USE_TLS)
+
+const extern void *_glapi_Context;
+const extern struct _glapi_table *_glapi_Dispatch;
+
+extern TLS void * _glapi_tls_Context;
+
+# define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_tls_Context
+
+#else
+
+extern void *_glapi_Context;
+extern struct _glapi_table *_glapi_Dispatch;
+
+# ifdef THREADS
+#  define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())
+# else
+#  define GET_CURRENT_CONTEXT(C)  GLcontext *C = (GLcontext *) _glapi_Context
+# endif
+
+#endif /* defined (GLX_USE_TLS) */
+
+
+/**
+ ** GL API public functions
+ **/
+
+extern void
+_glapi_check_multithread(void);
+
+extern void
+_glapi_set_context(void *context);
+
+extern void *
+_glapi_get_context(void);
+
+extern void
+_glapi_set_dispatch(struct _glapi_table *dispatch);
+
+extern struct _glapi_table *
+_glapi_get_dispatch(void);
+
+extern int
+_glapi_begin_dispatch_override(struct _glapi_table *override);
+
+extern void
+_glapi_end_dispatch_override(int layer);
+
+struct _glapi_table *
+_glapi_get_override_dispatch(int layer);
+
+extern GLuint
+_glapi_get_dispatch_table_size(void);
+
+extern int
+_glapi_add_dispatch( const char * const * function_names,
+		     const char * parameter_signature );
+
+extern _glapi_proc
+_glapi_get_proc_address(const char *funcName);
+
+#endif
diff --git a/xorg-server/glx/glthread.h b/xorg-server/glx/glthread.h
index 140e2aa8e..532401a73 100644
--- a/xorg-server/glx/glthread.h
+++ b/xorg-server/glx/glthread.h
@@ -233,8 +233,7 @@ _glthread_SetTSD(_glthread_TSD *, void *);
 
 #if defined(GLX_USE_TLS)
 
-extern TLS struct _glapi_table * _glapi_tls_Dispatch
-    __attribute__((tls_model("initial-exec")));
+extern TLS struct _glapi_table * _glapi_tls_Dispatch;
 
 #define GET_DISPATCH() _glapi_tls_Dispatch
 
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c
index 399683da7..244eac6c2 100644
--- a/xorg-server/glx/glxdri.c
+++ b/xorg-server/glx/glxdri.c
@@ -1,1159 +1,1168 @@
-/*
- * Copyright © 2006 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of Red Hat,
- * Inc not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission.  Red Hat, Inc makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
- * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <dlfcn.h>
-
-#include <drm.h>
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include <GL/glxtokens.h>
-
-#include <windowstr.h>
-#include <os.h>
-#include <damage.h>
-
-#define _XF86DRI_SERVER_
-#include <drm_sarea.h>
-#include <xf86drm.h>
-#include <X11/dri/xf86driproto.h>
-#include <xf86str.h>
-#include <xf86.h>
-#include <dri.h>
-
-#include "servermd.h"
-
-#define DRI_NEW_INTERFACE_ONLY
-#include "glxserver.h"
-#include "glxutil.h"
-#include "glxdricommon.h"
-
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "extension_string.h"
-
-typedef struct __GLXDRIscreen   __GLXDRIscreen;
-typedef struct __GLXDRIcontext  __GLXDRIcontext;
-typedef struct __GLXDRIdrawable __GLXDRIdrawable;
-
-struct __GLXDRIscreen {
-    __GLXscreen		 base;
-    __DRIscreen		*driScreen;
-    void		*driver;
-
-    xf86EnterVTProc	*enterVT;
-    xf86LeaveVTProc	*leaveVT;
-
-    const __DRIcoreExtension *core;
-    const __DRIlegacyExtension *legacy;
-    const __DRIcopySubBufferExtension *copySubBuffer;
-    const __DRIswapControlExtension *swapControl;
-
-#ifdef __DRI_TEX_OFFSET
-    const __DRItexOffsetExtension *texOffset;
-    DRITexOffsetStartProcPtr texOffsetStart;
-    DRITexOffsetFinishProcPtr texOffsetFinish;
-    __GLXDRIdrawable *texOffsetOverride[16];
-    GLuint lastTexOffsetOverride;
-#endif
-
-    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
-};
-
-struct __GLXDRIcontext {
-    __GLXcontext base;
-    __DRIcontext *driContext;
-    XID hwContextID;
-};
-
-struct __GLXDRIdrawable {
-    __GLXdrawable base;
-    __DRIdrawable *driDrawable;
-
-    /* Pulled in from old __GLXpixmap */
-#ifdef __DRI_TEX_OFFSET
-    GLint texname;
-    __GLXDRIcontext *ctx;
-    unsigned long long offset;
-    DamagePtr pDamage;
-#endif
-};
-
-static void
-__glXDRIleaveServer(GLboolean rendering)
-{
-    int i;
-
-    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
-	__GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
-	GLuint lastOverride = screen->lastTexOffsetOverride;
-
-	if (lastOverride) {
-	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
-	    int j;
-
-	    for (j = 0; j < lastOverride; j++) {
-		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
-
-		if (pGlxPix && pGlxPix->texname) {
-		    pGlxPix->offset =
-			screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
-		}
-	    }
-	}
-    }
-
-    DRIBlockHandler(NULL, NULL, NULL);
-
-    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
-	__GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
-	GLuint lastOverride = screen->lastTexOffsetOverride;
-
-	if (lastOverride) {
-	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
-	    int j;
-
-	    for (j = 0; j < lastOverride; j++) {
-		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
-
-		if (pGlxPix && pGlxPix->texname) {
-		    screen->texOffset->setTexOffset(pGlxPix->ctx->driContext,
-						    pGlxPix->texname,
-						    pGlxPix->offset,
-						    pGlxPix->base.pDraw->depth,
-						    ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
-		}
-	    }
-	}
-    }
-}
-    
-static void
-__glXDRIenterServer(GLboolean rendering)
-{
-    int i;
-
-    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
-	__GLXDRIscreen * const screen = (__GLXDRIscreen *)
-	    glxGetScreen(screenInfo.screens[i]);
-
-	if (screen->lastTexOffsetOverride) {
-	    CALL_Flush(GET_DISPATCH(), ());
-	    break;
-	}
-    }
-
-    DRIWakeupHandler(NULL, 0, NULL);
-}
-
-
-static void
-__glXDRIdoReleaseTexImage(__GLXDRIscreen *screen, __GLXDRIdrawable *drawable)
-{
-    GLuint lastOverride = screen->lastTexOffsetOverride;
-
-    if (lastOverride) {
-	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
-	int i;
-
-	for (i = 0; i < lastOverride; i++) {
-	    if (texOffsetOverride[i] == drawable) {
-		if (screen->texOffsetFinish)
-		    screen->texOffsetFinish((PixmapPtr)drawable->base.pDraw);
-
-		texOffsetOverride[i] = NULL;
-
-		if (i + 1 == lastOverride) {
-		    lastOverride = 0;
-
-		    while (i--) {
-			if (texOffsetOverride[i]) {
-			    lastOverride = i + 1;
-			    break;
-			}
-		    }
-
-		    screen->lastTexOffsetOverride = lastOverride;
-
-		    break;
-		}
-	    }
-	}
-    }
-}
-
-
-static void
-__glXDRIdrawableDestroy(__GLXdrawable *drawable)
-{
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-    __GLXDRIscreen *screen;
-    int i;
-
-    for (i = 0; i < screenInfo.numScreens; i++) {
-	screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
-	__glXDRIdoReleaseTexImage(screen, private);
-    }
-
-    /* If the X window was destroyed, the dri DestroyWindow hook will
-     * aready have taken care of this, so only call if pDraw isn't NULL. */
-    if (drawable->pDraw != NULL) {
-	screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen);
-	(*screen->core->destroyDrawable)(private->driDrawable);
-
-	__glXenterServer(GL_FALSE);
-	DRIDestroyDrawable(drawable->pDraw->pScreen,
-			   serverClient, drawable->pDraw);
-	__glXleaveServer(GL_FALSE);
-    }
-
-    __glXDrawableRelease(drawable);
-
-    free(private);
-}
-
-static GLboolean
-__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate)
-{
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
-    __GLXDRIscreen *screen =
-	(__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen);
-
-    (*screen->core->swapBuffers)(private->driDrawable);
-
-    return TRUE;
-}
-
-
-static int
-__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
-{
-    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
-    __GLXDRIscreen *screen =
-	(__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen);
-
-    if (screen->swapControl)
-	screen->swapControl->setSwapInterval(draw->driDrawable, interval);
-
-    return 0;
-}
-
-
-static void
-__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
-			       int x, int y, int w, int h)
-{
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	glxGetScreen(basePrivate->pDraw->pScreen);
-
-    if (screen->copySubBuffer)
-	screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h);
-}
-
-static void
-__glXDRIcontextDestroy(__GLXcontext *baseContext)
-{
-    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-    Bool retval;
-
-    screen->core->destroyContext(context->driContext);
-
-    __glXenterServer(GL_FALSE);
-    retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen,
-			       context->hwContextID);
-    __glXleaveServer(GL_FALSE);
-
-    __glXContextDestroy(&context->base);
-    free(context);
-}
-
-static int
-__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
-{
-    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
-    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
-
-    return (*screen->core->bindContext)(context->driContext,
-					draw->driDrawable,
-					read->driDrawable);
-}					      
-
-static int
-__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
-{
-    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
-    return (*screen->core->unbindContext)(context->driContext);
-}
-
-static int
-__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
-		    unsigned long mask)
-{
-    __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
-    __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
-
-    return (*screen->core->copyContext)(dst->driContext,
-					src->driContext, mask);
-}
-
-static void
-glxFillAlphaChannel (CARD32 *pixels, CARD32 rowstride, int width, int height)
-{
-    int i;
-    CARD32 *p, *end;
-
-    rowstride /= 4;
-    
-    for (i = 0; i < height; i++)
-    {
-	p = pixels;
-	end = p + width;
-	while (p < end)
-	  *p++ |= 0xFF000000;
-	pixels += rowstride;
-    }
-}
-
-static Bool
-testTexOffset(__GLXDRIscreen * const screen, PixmapPtr pPixmap)
-{
-    Bool ret;
-
-    if (!screen->texOffsetStart || !screen->texOffset)
-	return FALSE;
-
-    __glXenterServer(GL_FALSE);
-    ret = screen->texOffsetStart(pPixmap) != ~0ULL;
-    __glXleaveServer(GL_FALSE);
-
-    return ret;
-}
-
-/*
- * (sticking this here for lack of a better place)
- * Known issues with the GLX_EXT_texture_from_pixmap implementation:
- * - In general we ignore the fbconfig, lots of examples follow
- * - No fbconfig handling for multiple mipmap levels
- * - No fbconfig handling for 1D textures
- * - No fbconfig handling for TEXTURE_TARGET
- * - No fbconfig exposure of Y inversion state
- * - No GenerateMipmapEXT support (due to no FBO support)
- * - No support for anything but 16bpp and 32bpp-sparse pixmaps
- */
-
-static int
-__glXDRIbindTexImage(__GLXcontext *baseContext,
-		     int buffer,
-		     __GLXdrawable *glxPixmap)
-{
-    RegionPtr	pRegion = NULL;
-    PixmapPtr	pixmap;
-    int		bpp, override = 0, texname;
-    GLenum	format, type;
-    ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
-    __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap;
-    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
-
-    CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
-				      GL_TEXTURE_BINDING_2D :
-				      GL_TEXTURE_BINDING_RECTANGLE_NV,
-				      &texname));
-
-    if (!texname)
-	return __glXError(GLXBadContextState);
-
-    pixmap = (PixmapPtr) glxPixmap->pDraw;
-
-    if (testTexOffset(screen, pixmap)) {
-	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
-	int i, firstEmpty = 16;
-
-	for (i = 0; i < 16; i++) {
-	    if (texOffsetOverride[i] == driDraw)
-		goto alreadyin; 
-
-	    if (firstEmpty == 16 && !texOffsetOverride[i])
-		firstEmpty = i;
-	}
-
-	if (firstEmpty == 16) {
-	    ErrorF("%s: Failed to register texture offset override\n", __func__);
-	    goto nooverride;
-	}
-
-	if (firstEmpty >= screen->lastTexOffsetOverride)
-	    screen->lastTexOffsetOverride = firstEmpty + 1;
-
-	texOffsetOverride[firstEmpty] = driDraw;
-
-alreadyin:
-	override = 1;
-
-	driDraw->ctx = (__GLXDRIcontext*)baseContext;
-
-	if (texname == driDraw->texname)
-	    return Success;
-
-	driDraw->texname = texname;
-
-	screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0,
-					pixmap->drawable.depth,
-					pixmap->devKind);
-    }
-nooverride:
-
-    if (!driDraw->pDamage) {
-	if (!override) {
-	    driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
-					    TRUE, pScreen, NULL);
-	    if (!driDraw->pDamage)
-		return BadAlloc;
-
-	    DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
-	}
-
-	pRegion = NULL;
-    } else {
-	pRegion = DamageRegion(driDraw->pDamage);
-	if (RegionNil(pRegion))
-	    return Success;
-    }
-
-    /* XXX 24bpp packed, 8, etc */
-    if (pixmap->drawable.depth >= 24) {
-	bpp = 4;
-	format = GL_BGRA;
-	type =
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-	    !override ? GL_UNSIGNED_INT_8_8_8_8_REV :
-#endif
-	    GL_UNSIGNED_BYTE;
-    } else {
-	bpp = 2;
-	format = GL_RGB;
-	type = GL_UNSIGNED_SHORT_5_6_5;
-    }
-
-    if (pRegion == NULL)
-    {
-	void *data = NULL;
-
-	if (!override) {
-	    unsigned pitch = PixmapBytePad(pixmap->drawable.width,
-					   pixmap->drawable.depth); 
-
-	    data = malloc(pitch * pixmap->drawable.height);
-
-	    __glXenterServer(GL_FALSE);
-	    pScreen->GetImage(&pixmap->drawable, 0 /*pixmap->drawable.x*/,
-			      0 /*pixmap->drawable.y*/, pixmap->drawable.width,
-			      pixmap->drawable.height, ZPixmap, ~0, data);
-	    __glXleaveServer(GL_FALSE);
-
-	    if (pixmap->drawable.depth == 24)
-		glxFillAlphaChannel(data,
-				    pitch,
-				    pixmap->drawable.width,
-				    pixmap->drawable.height);
-
-	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
-					       pitch / bpp) );
-	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
-	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
-	}
-
-	CALL_TexImage2D( GET_DISPATCH(),
-			 (glxPixmap->target,
-			  0,
-			  bpp == 4 ? 4 : 3,
-			  pixmap->drawable.width,
-			  pixmap->drawable.height,
-			  0,
-			  format,
-			  type,
-			  data) );
-
-	free(data);
-    } else if (!override) {
-        int i, numRects;
-	BoxPtr p;
-
-	numRects = RegionNumRects (pRegion);
-	p = RegionRects (pRegion);
-
-	CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
-	CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
-
-	for (i = 0; i < numRects; i++)
-	{
-	    unsigned pitch = PixmapBytePad(p[i].x2 - p[i].x1,
-					   pixmap->drawable.depth);
-	    void *data = malloc(pitch * (p[i].y2 - p[i].y1));
-
-	    __glXenterServer(GL_FALSE);
-	    pScreen->GetImage(&pixmap->drawable, /*pixmap->drawable.x +*/ p[i].x1,
-			      /*pixmap->drawable.y*/ + p[i].y1, p[i].x2 - p[i].x1,
-			      p[i].y2 - p[i].y1, ZPixmap, ~0, data);
-	    __glXleaveServer(GL_FALSE);
-
-	    if (pixmap->drawable.depth == 24)
-		glxFillAlphaChannel(data,
-				    pitch,
-				    p[i].x2 - p[i].x1,
-				    p[i].y2 - p[i].y1);
-
-	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
-					       pitch / bpp) );
-
-	    CALL_TexSubImage2D( GET_DISPATCH(),
-				(glxPixmap->target,
-				 0,
-				 p[i].x1, p[i].y1,
-				 p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
-				 format,
-				 type,
-				 data) );
-
-	    free(data);
-	}
-    }
-
-    if (!override)
-	DamageEmpty(driDraw->pDamage);
-
-    return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext *baseContext,
-			int buffer,
-			__GLXdrawable *pixmap)
-{
-    __GLXDRIscreen *screen =
-	(__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen);
-    __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap;
-
-    __glXDRIdoReleaseTexImage(screen, drawable);
-
-    return Success;
-}
-
-static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
-    __glXDRIbindTexImage,
-    __glXDRIreleaseTexImage
-};
-
-static void
-__glXDRIscreenDestroy(__GLXscreen *baseScreen)
-{
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
-
-    screen->core->destroyScreen(screen->driScreen);
-
-    dlclose(screen->driver);
-
-    __glXScreenDestroy(baseScreen);
-
-    free(screen);
-}
-
-static __GLXcontext *
-__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
-			    __GLXconfig *glxConfig,
-			    __GLXcontext *baseShareContext)
-{
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
-    __GLXDRIcontext *context, *shareContext;
-    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
-    VisualPtr visual;
-    int i;
-    GLboolean retval;
-    __DRIcontext *driShare;
-    drm_context_t hwContext;
-    ScreenPtr pScreen = baseScreen->pScreen;
-
-    shareContext = (__GLXDRIcontext *) baseShareContext;
-    if (shareContext)
-	driShare = shareContext->driContext;
-    else
-	driShare = NULL;
-
-    if (baseShareContext && baseShareContext->isDirect)
-        return NULL;
-
-    context = calloc(1, sizeof *context);
-    if (context == NULL)
-	return NULL;
-
-    context->base.destroy           = __glXDRIcontextDestroy;
-    context->base.makeCurrent       = __glXDRIcontextMakeCurrent;
-    context->base.loseCurrent       = __glXDRIcontextLoseCurrent;
-    context->base.copy              = __glXDRIcontextCopy;
-
-    context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
-    /* Find the requested X visual */
-    visual = pScreen->visuals;
-    for (i = 0; i < pScreen->numVisuals; i++, visual++)
-	if (visual->vid == glxConfig->visualID)
-	    break;
-    if (i == pScreen->numVisuals)
-	return NULL;
-
-    context->hwContextID = FakeClientID(0);
-
-    __glXenterServer(GL_FALSE);
-    retval = DRICreateContext(baseScreen->pScreen, visual,
-			      context->hwContextID, &hwContext);
-    __glXleaveServer(GL_FALSE);
-
-    if (!retval)
-    	return NULL;
-
-    context->driContext =
-	screen->legacy->createNewContext(screen->driScreen,
-					 config->driConfig,
-					 0, /* render type */
-					 driShare,
-					 hwContext,
-					 context);
-
-    if (context->driContext == NULL) {
-    	__glXenterServer(GL_FALSE);
-	retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID);
-    	__glXleaveServer(GL_FALSE);
-	free(context);
-	return NULL;
-    }
-
-    return &context->base;
-}
-
-static __GLXdrawable *
-__glXDRIscreenCreateDrawable(ClientPtr client,
-			     __GLXscreen *screen,
-			     DrawablePtr pDraw,
-			     XID drawId,
-			     int type,
-			     XID glxDrawId,
-			     __GLXconfig *glxConfig)
-{
-    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
-    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
-    __GLXDRIdrawable *private;
-    GLboolean retval;
-    drm_drawable_t hwDrawable;
-
-    private = calloc(1, sizeof *private);
-    if (private == NULL)
-	return NULL;
-
-    if (!__glXDrawableInit(&private->base, screen,
-			   pDraw, type, glxDrawId, glxConfig)) {
-        free(private);
-	return NULL;
-    }
-
-    private->base.destroy       = __glXDRIdrawableDestroy;
-    private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
-    private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
-    private->base.waitX		= NULL;
-    private->base.waitGL	= NULL;
-
-    __glXenterServer(GL_FALSE);
-    retval = DRICreateDrawable(screen->pScreen, serverClient,
-			       pDraw, &hwDrawable);
-    __glXleaveServer(GL_FALSE);
-
-    if (!retval) {
-        free(private);
-    	return NULL;
-    }
-
-    /* The last argument is 'attrs', which is used with pbuffers which
-     * we currently don't support. */
-
-    private->driDrawable =
-	(driScreen->legacy->createNewDrawable)(driScreen->driScreen,
-					       config->driConfig,
-					       hwDrawable, 0, NULL, private);
-
-    if (private->driDrawable == NULL) {
-	__glXenterServer(GL_FALSE);
-	DRIDestroyDrawable(screen->pScreen, serverClient, pDraw);
-	__glXleaveServer(GL_FALSE);
-	free(private);
-	return NULL;
-    }
-
-    return &private->base;
-}
-
-static GLboolean
-getDrawableInfo(__DRIdrawable *driDrawable,
-		unsigned int *index, unsigned int *stamp,
-		int *x, int *y, int *width, int *height,
-		int *numClipRects, drm_clip_rect_t **ppClipRects,
-		int *backX, int *backY,
-		int *numBackClipRects, drm_clip_rect_t **ppBackClipRects,
-		void *data)
-{
-    __GLXDRIdrawable *drawable = data;
-    ScreenPtr pScreen;
-    drm_clip_rect_t *pClipRects, *pBackClipRects;
-    GLboolean retval;
-    size_t size;
-
-    /* If the X window has been destroyed, give up here. */
-    if (drawable->base.pDraw == NULL)
-	return GL_FALSE;
-
-    pScreen = drawable->base.pDraw->pScreen;
-    __glXenterServer(GL_FALSE);
-    retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp,
-				x, y, width, height,
-				numClipRects, &pClipRects,
-				backX, backY,
-				numBackClipRects, &pBackClipRects);
-    __glXleaveServer(GL_FALSE);
-
-    if (retval && *numClipRects > 0) {
-	size = sizeof (drm_clip_rect_t) * *numClipRects;
-	*ppClipRects = malloc(size);
-
-	/* Clip cliprects to screen dimensions (redirected windows) */
-	if (*ppClipRects != NULL) {
-	    int i, j;
-
-	    for (i = 0, j = 0; i < *numClipRects; i++) {
-	        (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
-		(*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
-		(*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
-		(*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
-		if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
-		    (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
-		    j++;
-		}
-	    }
-
-	    if (*numClipRects != j) {
-		*numClipRects = j;
-		*ppClipRects = realloc(*ppClipRects,
-					 sizeof (drm_clip_rect_t) *
-					 *numClipRects);
-	    }
-	} else
-	    *numClipRects = 0;
-    }
-    else {
-      *ppClipRects = NULL;
-      *numClipRects = 0;
-    }
-      
-    if (retval && *numBackClipRects > 0) {
-	size = sizeof (drm_clip_rect_t) * *numBackClipRects;
-	*ppBackClipRects = malloc(size);
-	if (*ppBackClipRects != NULL)
-	    memcpy (*ppBackClipRects, pBackClipRects, size);
-	else
-	    *numBackClipRects = 0;
-    }
-    else {
-      *ppBackClipRects = NULL;
-      *numBackClipRects = 0;
-    }
-
-    return retval;
-}
-
-static void __glXReportDamage(__DRIdrawable *driDraw,
-			      int x, int y,
-			      drm_clip_rect_t *rects, int num_rects,
-			      GLboolean front_buffer,
-			      void *data)
-{
-    __GLXDRIdrawable *drawable = data;
-    DrawablePtr pDraw = drawable->base.pDraw;
-    RegionRec region;
-
-    __glXenterServer(GL_FALSE);
-
-    RegionInit(&region, (BoxPtr) rects, num_rects);
-    RegionTranslate(&region, pDraw->x, pDraw->y);
-    DamageDamageRegion(pDraw, &region);
-    RegionUninit(&region);
-
-    __glXleaveServer(GL_FALSE);
-}
-
-static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
-    { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
-    getDrawableInfo
-};
-
-static const __DRIdamageExtension damageExtension = {
-    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
-    __glXReportDamage,
-};
-
-static const __DRIextension *loader_extensions[] = {
-    &systemTimeExtension.base,
-    &getDrawableInfoExtension.base,
-    &damageExtension.base,
-    NULL
-};
-
-
-
-static Bool
-glxDRIEnterVT (int index, int flags)
-{
-    ScrnInfoPtr scrn = xf86Screens[index];
-    Bool	ret;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) 
-	glxGetScreen(screenInfo.screens[index]);
-
-    LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
-
-    scrn->EnterVT = screen->enterVT;
-
-    ret = scrn->EnterVT (index, flags);
-
-    screen->enterVT = scrn->EnterVT;
-    scrn->EnterVT = glxDRIEnterVT;
-
-    if (!ret)
-	return FALSE;
-    
-    glxResumeClients();
-
-    return TRUE;
-}
-
-static void
-glxDRILeaveVT (int index, int flags)
-{
-    ScrnInfoPtr scrn = xf86Screens[index];
-    __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	glxGetScreen(screenInfo.screens[index]);
-
-    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
-
-    glxSuspendClients();
-
-    scrn->LeaveVT = screen->leaveVT;
-    (*screen->leaveVT) (index, flags);
-    screen->leaveVT = scrn->LeaveVT;
-    scrn->LeaveVT = glxDRILeaveVT;
-}
-
-static void
-initializeExtensions(__GLXDRIscreen *screen)
-{
-    const __DRIextension **extensions;
-    int i;
-
-    extensions = screen->core->getExtensions(screen->driScreen);
-
-    for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_READ_DRAWABLE
-	if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_SGI_make_current_read");
-	    
-	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
-	}
-#endif
-
-#ifdef __DRI_COPY_SUB_BUFFER
-	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
-	    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_MESA_copy_sub_buffer");
-	    
-	    LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
-	}
-#endif
-
-#ifdef __DRI_SWAP_CONTROL
-	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
-	    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_SGI_swap_control");
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_MESA_swap_control");
-	    
-	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
-	}
-#endif
-
-#ifdef __DRI_TEX_OFFSET
-	if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) {
-	    screen->texOffset = (__DRItexOffsetExtension *) extensions[i];
-	    LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n");
-	}
-#endif
-	/* Ignore unknown extensions */
-    }
-}
-    
-static __GLXscreen *
-__glXDRIscreenProbe(ScreenPtr pScreen)
-{
-    drm_handle_t hSAREA;
-    drmAddress pSAREA = NULL;
-    char *BusID;
-    __DRIversion   ddx_version;
-    __DRIversion   dri_version;
-    __DRIversion   drm_version;
-    __DRIframebuffer  framebuffer;
-    int   fd = -1;
-    int   status;
-    drm_magic_t magic;
-    drmVersionPtr version;
-    int newlyopened;
-    char *driverName;
-    drm_handle_t  hFB;
-    int        junk;
-    __GLXDRIscreen *screen;
-    Bool isCapable;
-    size_t buffer_size;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    const __DRIconfig **driConfigs;
-
-    if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
-	!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
-	!isCapable) {
-	LogMessage(X_INFO,
-		   "AIGLX: Screen %d is not DRI capable\n", pScreen->myNum);
-	return NULL;
-    }
-
-    screen = calloc(1, sizeof *screen);
-    if (screen == NULL)
-      return NULL;
-
-    screen->base.destroy        = __glXDRIscreenDestroy;
-    screen->base.createContext  = __glXDRIscreenCreateContext;
-    screen->base.createDrawable = __glXDRIscreenCreateDrawable;
-    screen->base.swapInterval   = __glXDRIdrawableSwapInterval;
-    screen->base.pScreen       = pScreen;
-
-    __glXInitExtensionEnableBits(screen->glx_enable_bits);
-
-    /* DRI protocol version. */
-    dri_version.major = XF86DRI_MAJOR_VERSION;
-    dri_version.minor = XF86DRI_MINOR_VERSION;
-    dri_version.patch = XF86DRI_PATCH_VERSION;
-
-    if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) {
-	LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n");
-	goto handle_error;
-    }
-
-    fd = drmOpenOnce(NULL, BusID, &newlyopened);
-
-    if (fd < 0) {
-	LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n",
-		   strerror(-fd));
-	goto handle_error;
-    }
-
-    if (drmGetMagic(fd, &magic)) {
-	LogMessage(X_ERROR, "AIGLX error: drmGetMagic failed\n");
-	goto handle_error;
-    }
-
-    version = drmGetVersion(fd);
-    if (version) {
-	drm_version.major = version->version_major;
-	drm_version.minor = version->version_minor;
-	drm_version.patch = version->version_patchlevel;
-	drmFreeVersion(version);
-    }
-    else {
-	drm_version.major = -1;
-	drm_version.minor = -1;
-	drm_version.patch = -1;
-    }
-
-    if (newlyopened && !DRIAuthConnection(pScreen, magic)) {
-	LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n");
-	goto handle_error;
-    }
-
-    /* Get device name (like "tdfx") and the ddx version numbers.
-     * We'll check the version in each DRI driver's "createNewScreen"
-     * function. */
-    if (!DRIGetClientDriverName(pScreen,
-				&ddx_version.major,
-				&ddx_version.minor,
-				&ddx_version.patch,
-				&driverName)) {
-	LogMessage(X_ERROR, "AIGLX error: DRIGetClientDriverName failed\n");
-	goto handle_error;
-    }
-
-    screen->driver = glxProbeDriver(driverName,
-				    (void **)&screen->core,
-				    __DRI_CORE, __DRI_CORE_VERSION,
-				    (void **)&screen->legacy,
-				    __DRI_LEGACY, __DRI_LEGACY_VERSION);
-    if (screen->driver == NULL) {
-        goto handle_error;
-    }
-    
-    /*
-     * Get device-specific info.  pDevPriv will point to a struct
-     * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
-     * has information about the screen size, depth, pitch, ancilliary
-     * buffers, DRM mmap handles, etc.
-     */
-    if (!DRIGetDeviceInfo(pScreen, &hFB, &junk,
-			  &framebuffer.size, &framebuffer.stride,
-			  &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
-	LogMessage(X_ERROR, "AIGLX error: XF86DRIGetDeviceInfo failed\n");
-	goto handle_error;
-    }
-
-    framebuffer.width = pScreen->width;
-    framebuffer.height = pScreen->height;
-
-    /* Map the framebuffer region. */
-    status = drmMap(fd, hFB, framebuffer.size, 
-		    (drmAddressPtr)&framebuffer.base);
-    if (status != 0) {
-	LogMessage(X_ERROR, "AIGLX error: drmMap of framebuffer failed (%s)\n",
-		   strerror(-status));
-	goto handle_error;
-    }
-
-    /* Map the SAREA region.  Further mmap regions may be setup in
-     * each DRI driver's "createNewScreen" function.
-     */
-    status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
-    if (status != 0) {
-	LogMessage(X_ERROR, "AIGLX error: drmMap of SAREA failed (%s)\n",
-		   strerror(-status));
-	goto handle_error;
-    }
-    
-    screen->driScreen =
-	(*screen->legacy->createNewScreen)(pScreen->myNum,
-					   &ddx_version,
-					   &dri_version,
-					   &drm_version,
-					   &framebuffer,
-					   pSAREA,
-					   fd,
-					   loader_extensions,
-					   &driConfigs,
-					   screen);
-
-    if (screen->driScreen == NULL) {
-	LogMessage(X_ERROR,
-		   "AIGLX error: Calling driver entry point failed\n");
-	goto handle_error;
-    }
-
-    screen->base.fbconfigs = glxConvertConfigs(screen->core,
-					       driConfigs, GLX_WINDOW_BIT);
-
-    initializeExtensions(screen);
-
-    DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
-			 &screen->texOffsetFinish);
-
-    __glXScreenInit(&screen->base, pScreen);
-
-    /* The first call simply determines the length of the extension string.
-     * This allows us to allocate some memory to hold the extension string,
-     * but it requires that we call __glXGetExtensionString a second time.
-     */
-    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
-    if (buffer_size > 0) {
-	free(screen->base.GLXextensions);
-
-	screen->base.GLXextensions = xnfalloc(buffer_size);
-	(void) __glXGetExtensionString(screen->glx_enable_bits, 
-				       screen->base.GLXextensions);
-    }
-
-    __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer);
-
-    screen->enterVT = pScrn->EnterVT;
-    pScrn->EnterVT = glxDRIEnterVT;
-    screen->leaveVT = pScrn->LeaveVT;
-    pScrn->LeaveVT = glxDRILeaveVT;
-
-    LogMessage(X_INFO,
-	       "AIGLX: Loaded and initialized %s\n", driverName);
-
-    return &screen->base;
-
- handle_error:
-    if (pSAREA != NULL)
-	drmUnmap(pSAREA, SAREA_MAX);
-
-    if (framebuffer.base != NULL)
-	drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
-
-    if (fd >= 0)
-	drmCloseOnce(fd);
-
-    DRICloseConnection(pScreen);
-
-    if (screen->driver)
-        dlclose(screen->driver);
-
-    free(screen);
-
-    LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
-
-    return NULL;
-}
-
-_X_EXPORT __GLXprovider __glXDRIProvider = {
-    __glXDRIscreenProbe,
-    "DRI",
-    NULL
-};
+/*
+ * Copyright © 2006 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat,
+ * Inc not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.  Red Hat, Inc makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+
+#include <drm.h>
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include <GL/glxtokens.h>
+
+#include <windowstr.h>
+#include <os.h>
+#include <damage.h>
+
+#define _XF86DRI_SERVER_
+#include <drm_sarea.h>
+#include <xf86drm.h>
+#include <X11/dri/xf86driproto.h>
+#include <xf86str.h>
+#include <xf86.h>
+#include <dri.h>
+
+#include "servermd.h"
+
+#define DRI_NEW_INTERFACE_ONLY
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxdricommon.h"
+
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "extension_string.h"
+
+typedef struct __GLXDRIscreen   __GLXDRIscreen;
+typedef struct __GLXDRIcontext  __GLXDRIcontext;
+typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+struct __GLXDRIscreen {
+    __GLXscreen		 base;
+    __DRIscreen		*driScreen;
+    void		*driver;
+
+    xf86EnterVTProc	*enterVT;
+    xf86LeaveVTProc	*leaveVT;
+
+    const __DRIcoreExtension *core;
+    const __DRIlegacyExtension *legacy;
+    const __DRIcopySubBufferExtension *copySubBuffer;
+    const __DRIswapControlExtension *swapControl;
+
+#ifdef __DRI_TEX_OFFSET
+    const __DRItexOffsetExtension *texOffset;
+    DRITexOffsetStartProcPtr texOffsetStart;
+    DRITexOffsetFinishProcPtr texOffsetFinish;
+    __GLXDRIdrawable *texOffsetOverride[16];
+    GLuint lastTexOffsetOverride;
+#endif
+
+    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+};
+
+struct __GLXDRIcontext {
+    __GLXcontext base;
+    __DRIcontext *driContext;
+    XID hwContextID;
+};
+
+struct __GLXDRIdrawable {
+    __GLXdrawable base;
+    __DRIdrawable *driDrawable;
+
+    /* Pulled in from old __GLXpixmap */
+#ifdef __DRI_TEX_OFFSET
+    GLint texname;
+    __GLXDRIcontext *ctx;
+    unsigned long long offset;
+    DamagePtr pDamage;
+#endif
+};
+
+static void
+__glXDRIleaveServer(GLboolean rendering)
+{
+    int i;
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+	GLuint lastOverride = screen->lastTexOffsetOverride;
+
+	if (lastOverride) {
+	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+	    int j;
+
+	    for (j = 0; j < lastOverride; j++) {
+		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
+
+		if (pGlxPix && pGlxPix->texname) {
+		    pGlxPix->offset =
+			screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
+		}
+	    }
+	}
+    }
+
+    DRIBlockHandler(NULL, NULL, NULL);
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen =
+	    (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+	GLuint lastOverride = screen->lastTexOffsetOverride;
+
+	if (lastOverride) {
+	    __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+	    int j;
+
+	    for (j = 0; j < lastOverride; j++) {
+		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
+
+		if (pGlxPix && pGlxPix->texname) {
+		    screen->texOffset->setTexOffset(pGlxPix->ctx->driContext,
+						    pGlxPix->texname,
+						    pGlxPix->offset,
+						    pGlxPix->base.pDraw->depth,
+						    ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
+		}
+	    }
+	}
+    }
+}
+    
+static void
+__glXDRIenterServer(GLboolean rendering)
+{
+    int i;
+
+    for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+	__GLXDRIscreen * const screen = (__GLXDRIscreen *)
+	    glxGetScreen(screenInfo.screens[i]);
+
+	if (screen->lastTexOffsetOverride) {
+	    CALL_Flush(GET_DISPATCH(), ());
+	    break;
+	}
+    }
+
+    DRIWakeupHandler(NULL, 0, NULL);
+}
+
+
+static void
+__glXDRIdoReleaseTexImage(__GLXDRIscreen *screen, __GLXDRIdrawable *drawable)
+{
+    GLuint lastOverride = screen->lastTexOffsetOverride;
+
+    if (lastOverride) {
+	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+	int i;
+
+	for (i = 0; i < lastOverride; i++) {
+	    if (texOffsetOverride[i] == drawable) {
+		if (screen->texOffsetFinish)
+		    screen->texOffsetFinish((PixmapPtr)drawable->base.pDraw);
+
+		texOffsetOverride[i] = NULL;
+
+		if (i + 1 == lastOverride) {
+		    lastOverride = 0;
+
+		    while (i--) {
+			if (texOffsetOverride[i]) {
+			    lastOverride = i + 1;
+			    break;
+			}
+		    }
+
+		    screen->lastTexOffsetOverride = lastOverride;
+
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+
+static void
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    __GLXDRIscreen *screen;
+    int i;
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+	screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+	__glXDRIdoReleaseTexImage(screen, private);
+    }
+
+    /* If the X window was destroyed, the dri DestroyWindow hook will
+     * aready have taken care of this, so only call if pDraw isn't NULL. */
+    if (drawable->pDraw != NULL) {
+	screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen);
+	(*screen->core->destroyDrawable)(private->driDrawable);
+
+	__glXenterServer(GL_FALSE);
+	DRIDestroyDrawable(drawable->pDraw->pScreen,
+			   serverClient, drawable->pDraw);
+	__glXleaveServer(GL_FALSE);
+    }
+
+    __glXDrawableRelease(drawable);
+
+    free(private);
+}
+
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen);
+
+    (*screen->core->swapBuffers)(private->driDrawable);
+
+    return TRUE;
+}
+
+
+static int
+__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
+{
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen);
+
+    if (screen->swapControl)
+	screen->swapControl->setSwapInterval(draw->driDrawable, interval);
+
+    return 0;
+}
+
+
+static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
+			       int x, int y, int w, int h)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(basePrivate->pDraw->pScreen);
+
+    if (screen->copySubBuffer)
+	screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h);
+}
+
+static void
+__glXDRIcontextDestroy(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+    Bool retval;
+
+    screen->core->destroyContext(context->driContext);
+
+    __glXenterServer(GL_FALSE);
+    retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen,
+			       context->hwContextID);
+    __glXleaveServer(GL_FALSE);
+
+    __glXContextDestroy(&context->base);
+    free(context);
+}
+
+static int
+__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+
+    return (*screen->core->bindContext)(context->driContext,
+					draw->driDrawable,
+					read->driDrawable);
+}					      
+
+static int
+__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+    return (*screen->core->unbindContext)(context->driContext);
+}
+
+static int
+__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
+		    unsigned long mask)
+{
+    __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
+    __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
+
+    return (*screen->core->copyContext)(dst->driContext,
+					src->driContext, mask);
+}
+
+static void
+glxFillAlphaChannel (CARD32 *pixels, CARD32 rowstride, int width, int height)
+{
+    int i;
+    CARD32 *p, *end;
+
+    rowstride /= 4;
+    
+    for (i = 0; i < height; i++)
+    {
+	p = pixels;
+	end = p + width;
+	while (p < end)
+	  *p++ |= 0xFF000000;
+	pixels += rowstride;
+    }
+}
+
+static Bool
+testTexOffset(__GLXDRIscreen * const screen, PixmapPtr pPixmap)
+{
+    Bool ret;
+
+    if (!screen->texOffsetStart || !screen->texOffset)
+	return FALSE;
+
+    __glXenterServer(GL_FALSE);
+    ret = screen->texOffsetStart(pPixmap) != ~0ULL;
+    __glXleaveServer(GL_FALSE);
+
+    return ret;
+}
+
+/*
+ * (sticking this here for lack of a better place)
+ * Known issues with the GLX_EXT_texture_from_pixmap implementation:
+ * - In general we ignore the fbconfig, lots of examples follow
+ * - No fbconfig handling for multiple mipmap levels
+ * - No fbconfig handling for 1D textures
+ * - No fbconfig handling for TEXTURE_TARGET
+ * - No fbconfig exposure of Y inversion state
+ * - No GenerateMipmapEXT support (due to no FBO support)
+ * - No support for anything but 16bpp and 32bpp-sparse pixmaps
+ */
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+		     int buffer,
+		     __GLXdrawable *glxPixmap)
+{
+    RegionPtr	pRegion = NULL;
+    PixmapPtr	pixmap;
+    int		bpp, override = 0, texname;
+    GLenum	format, type;
+    ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
+    __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap;
+    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
+
+    CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
+				      GL_TEXTURE_BINDING_2D :
+				      GL_TEXTURE_BINDING_RECTANGLE_NV,
+				      &texname));
+
+    if (!texname)
+	return __glXError(GLXBadContextState);
+
+    pixmap = (PixmapPtr) glxPixmap->pDraw;
+
+    if (testTexOffset(screen, pixmap)) {
+	__GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+	int i, firstEmpty = 16;
+
+	for (i = 0; i < 16; i++) {
+	    if (texOffsetOverride[i] == driDraw)
+		goto alreadyin; 
+
+	    if (firstEmpty == 16 && !texOffsetOverride[i])
+		firstEmpty = i;
+	}
+
+	if (firstEmpty == 16) {
+	    ErrorF("%s: Failed to register texture offset override\n", __func__);
+	    goto nooverride;
+	}
+
+	if (firstEmpty >= screen->lastTexOffsetOverride)
+	    screen->lastTexOffsetOverride = firstEmpty + 1;
+
+	texOffsetOverride[firstEmpty] = driDraw;
+
+alreadyin:
+	override = 1;
+
+	driDraw->ctx = (__GLXDRIcontext*)baseContext;
+
+	if (texname == driDraw->texname)
+	    return Success;
+
+	driDraw->texname = texname;
+
+	screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0,
+					pixmap->drawable.depth,
+					pixmap->devKind);
+    }
+nooverride:
+
+    if (!driDraw->pDamage) {
+	if (!override) {
+	    driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+					    TRUE, pScreen, NULL);
+	    if (!driDraw->pDamage)
+		return BadAlloc;
+
+	    DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
+	}
+
+	pRegion = NULL;
+    } else {
+	pRegion = DamageRegion(driDraw->pDamage);
+	if (RegionNil(pRegion))
+	    return Success;
+    }
+
+    /* XXX 24bpp packed, 8, etc */
+    if (pixmap->drawable.depth >= 24) {
+	bpp = 4;
+	format = GL_BGRA;
+	type =
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	    !override ? GL_UNSIGNED_INT_8_8_8_8_REV :
+#endif
+	    GL_UNSIGNED_BYTE;
+    } else {
+	bpp = 2;
+	format = GL_RGB;
+	type = GL_UNSIGNED_SHORT_5_6_5;
+    }
+
+    if (pRegion == NULL)
+    {
+	void *data = NULL;
+
+	if (!override) {
+	    unsigned pitch = PixmapBytePad(pixmap->drawable.width,
+					   pixmap->drawable.depth); 
+
+	    data = malloc(pitch * pixmap->drawable.height);
+
+	    __glXenterServer(GL_FALSE);
+	    pScreen->GetImage(&pixmap->drawable, 0 /*pixmap->drawable.x*/,
+			      0 /*pixmap->drawable.y*/, pixmap->drawable.width,
+			      pixmap->drawable.height, ZPixmap, ~0, data);
+	    __glXleaveServer(GL_FALSE);
+
+	    if (pixmap->drawable.depth == 24)
+		glxFillAlphaChannel(data,
+				    pitch,
+				    pixmap->drawable.width,
+				    pixmap->drawable.height);
+
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
+					       pitch / bpp) );
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
+	}
+
+	CALL_TexImage2D( GET_DISPATCH(),
+			 (glxPixmap->target,
+			  0,
+			  bpp == 4 ? 4 : 3,
+			  pixmap->drawable.width,
+			  pixmap->drawable.height,
+			  0,
+			  format,
+			  type,
+			  data) );
+
+	free(data);
+    } else if (!override) {
+        int i, numRects;
+	BoxPtr p;
+
+	numRects = RegionNumRects (pRegion);
+	p = RegionRects (pRegion);
+
+	CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
+	CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
+
+	for (i = 0; i < numRects; i++)
+	{
+	    unsigned pitch = PixmapBytePad(p[i].x2 - p[i].x1,
+					   pixmap->drawable.depth);
+	    void *data = malloc(pitch * (p[i].y2 - p[i].y1));
+
+	    __glXenterServer(GL_FALSE);
+	    pScreen->GetImage(&pixmap->drawable, /*pixmap->drawable.x +*/ p[i].x1,
+			      /*pixmap->drawable.y*/ + p[i].y1, p[i].x2 - p[i].x1,
+			      p[i].y2 - p[i].y1, ZPixmap, ~0, data);
+	    __glXleaveServer(GL_FALSE);
+
+	    if (pixmap->drawable.depth == 24)
+		glxFillAlphaChannel(data,
+				    pitch,
+				    p[i].x2 - p[i].x1,
+				    p[i].y2 - p[i].y1);
+
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
+					       pitch / bpp) );
+
+	    CALL_TexSubImage2D( GET_DISPATCH(),
+				(glxPixmap->target,
+				 0,
+				 p[i].x1, p[i].y1,
+				 p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
+				 format,
+				 type,
+				 data) );
+
+	    free(data);
+	}
+    }
+
+    if (!override)
+	DamageEmpty(driDraw->pDamage);
+
+    return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+			int buffer,
+			__GLXdrawable *pixmap)
+{
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen);
+    __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap;
+
+    __glXDRIdoReleaseTexImage(screen, drawable);
+
+    return Success;
+}
+
+static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
+    __glXDRIbindTexImage,
+    __glXDRIreleaseTexImage
+};
+
+static void
+__glXDRIscreenDestroy(__GLXscreen *baseScreen)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+
+    screen->core->destroyScreen(screen->driScreen);
+
+    dlclose(screen->driver);
+
+    __glXScreenDestroy(baseScreen);
+
+    free(screen);
+}
+
+static __GLXcontext *
+__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
+			    __GLXconfig *glxConfig,
+			    __GLXcontext *baseShareContext)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+    __GLXDRIcontext *context, *shareContext;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+    VisualPtr visual;
+    int i;
+    GLboolean retval;
+    __DRIcontext *driShare;
+    drm_context_t hwContext;
+    ScreenPtr pScreen = baseScreen->pScreen;
+
+    shareContext = (__GLXDRIcontext *) baseShareContext;
+    if (shareContext)
+	driShare = shareContext->driContext;
+    else
+	driShare = NULL;
+
+    if (baseShareContext && baseShareContext->isDirect)
+        return NULL;
+
+    context = calloc(1, sizeof *context);
+    if (context == NULL)
+	return NULL;
+
+    context->base.destroy           = __glXDRIcontextDestroy;
+    context->base.makeCurrent       = __glXDRIcontextMakeCurrent;
+    context->base.loseCurrent       = __glXDRIcontextLoseCurrent;
+    context->base.copy              = __glXDRIcontextCopy;
+
+    context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+    /* Find the requested X visual */
+    visual = pScreen->visuals;
+    for (i = 0; i < pScreen->numVisuals; i++, visual++)
+	if (visual->vid == glxConfig->visualID)
+	    break;
+    if (i == pScreen->numVisuals)
+	return NULL;
+
+    context->hwContextID = FakeClientID(0);
+
+    __glXenterServer(GL_FALSE);
+    retval = DRICreateContext(baseScreen->pScreen, visual,
+			      context->hwContextID, &hwContext);
+    __glXleaveServer(GL_FALSE);
+
+    if (!retval)
+    	return NULL;
+
+    context->driContext =
+	screen->legacy->createNewContext(screen->driScreen,
+					 config->driConfig,
+					 0, /* render type */
+					 driShare,
+					 hwContext,
+					 context);
+
+    if (context->driContext == NULL) {
+    	__glXenterServer(GL_FALSE);
+	retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID);
+    	__glXleaveServer(GL_FALSE);
+	free(context);
+	return NULL;
+    }
+
+    return &context->base;
+}
+
+static __GLXdrawable *
+__glXDRIscreenCreateDrawable(ClientPtr client,
+			     __GLXscreen *screen,
+			     DrawablePtr pDraw,
+			     XID drawId,
+			     int type,
+			     XID glxDrawId,
+			     __GLXconfig *glxConfig)
+{
+    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+    __GLXDRIdrawable *private;
+    GLboolean retval;
+    drm_drawable_t hwDrawable;
+
+    private = calloc(1, sizeof *private);
+    if (private == NULL)
+	return NULL;
+
+    if (!__glXDrawableInit(&private->base, screen,
+			   pDraw, type, glxDrawId, glxConfig)) {
+        free(private);
+	return NULL;
+    }
+
+    private->base.destroy       = __glXDRIdrawableDestroy;
+    private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
+    private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+    private->base.waitX		= NULL;
+    private->base.waitGL	= NULL;
+
+    __glXenterServer(GL_FALSE);
+    retval = DRICreateDrawable(screen->pScreen, serverClient,
+			       pDraw, &hwDrawable);
+    __glXleaveServer(GL_FALSE);
+
+    if (!retval) {
+        free(private);
+    	return NULL;
+    }
+
+    /* The last argument is 'attrs', which is used with pbuffers which
+     * we currently don't support. */
+
+    private->driDrawable =
+	(driScreen->legacy->createNewDrawable)(driScreen->driScreen,
+					       config->driConfig,
+					       hwDrawable, 0, NULL, private);
+
+    if (private->driDrawable == NULL) {
+	__glXenterServer(GL_FALSE);
+	DRIDestroyDrawable(screen->pScreen, serverClient, pDraw);
+	__glXleaveServer(GL_FALSE);
+	free(private);
+	return NULL;
+    }
+
+    return &private->base;
+}
+
+static GLboolean
+getDrawableInfo(__DRIdrawable *driDrawable,
+		unsigned int *index, unsigned int *stamp,
+		int *x, int *y, int *width, int *height,
+		int *numClipRects, drm_clip_rect_t **ppClipRects,
+		int *backX, int *backY,
+		int *numBackClipRects, drm_clip_rect_t **ppBackClipRects,
+		void *data)
+{
+    __GLXDRIdrawable *drawable = data;
+    ScreenPtr pScreen;
+    drm_clip_rect_t *pClipRects, *pBackClipRects;
+    GLboolean retval;
+    size_t size;
+
+    /* If the X window has been destroyed, give up here. */
+    if (drawable->base.pDraw == NULL)
+	return GL_FALSE;
+
+    pScreen = drawable->base.pDraw->pScreen;
+    __glXenterServer(GL_FALSE);
+    retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp,
+				x, y, width, height,
+				numClipRects, &pClipRects,
+				backX, backY,
+				numBackClipRects, &pBackClipRects);
+    __glXleaveServer(GL_FALSE);
+
+    if (retval && *numClipRects > 0) {
+	size = sizeof (drm_clip_rect_t) * *numClipRects;
+	*ppClipRects = malloc(size);
+
+	/* Clip cliprects to screen dimensions (redirected windows) */
+	if (*ppClipRects != NULL) {
+	    int i, j;
+
+	    for (i = 0, j = 0; i < *numClipRects; i++) {
+	        (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
+		(*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
+		(*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
+		(*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+		if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
+		    (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
+		    j++;
+		}
+	    }
+
+	    if (*numClipRects != j) {
+		*numClipRects = j;
+		*ppClipRects = realloc(*ppClipRects,
+					 sizeof (drm_clip_rect_t) *
+					 *numClipRects);
+	    }
+	} else
+	    *numClipRects = 0;
+    }
+    else {
+      *ppClipRects = NULL;
+      *numClipRects = 0;
+    }
+      
+    if (retval && *numBackClipRects > 0) {
+	size = sizeof (drm_clip_rect_t) * *numBackClipRects;
+	*ppBackClipRects = malloc(size);
+	if (*ppBackClipRects != NULL)
+	    memcpy (*ppBackClipRects, pBackClipRects, size);
+	else
+	    *numBackClipRects = 0;
+    }
+    else {
+      *ppBackClipRects = NULL;
+      *numBackClipRects = 0;
+    }
+
+    return retval;
+}
+
+static void __glXReportDamage(__DRIdrawable *driDraw,
+			      int x, int y,
+			      drm_clip_rect_t *rects, int num_rects,
+			      GLboolean front_buffer,
+			      void *data)
+{
+    __GLXDRIdrawable *drawable = data;
+    DrawablePtr pDraw = drawable->base.pDraw;
+    RegionRec region;
+
+    __glXenterServer(GL_FALSE);
+
+    if (RegionInitBoxes(&region, (BoxPtr) rects, num_rects)) {
+	RegionTranslate(&region, pDraw->x, pDraw->y);
+	DamageDamageRegion(pDraw, &region);
+	RegionUninit(&region);
+    }
+    else {
+	while (num_rects--) {
+	    RegionInit (&region, (BoxPtr) rects++, 1);
+	    RegionTranslate(&region, pDraw->x, pDraw->y);
+	    DamageDamageRegion(pDraw, &region);
+	    RegionUninit(&region);
+	}
+    }
+
+    __glXleaveServer(GL_FALSE);
+}
+
+static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
+    { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
+    getDrawableInfo
+};
+
+static const __DRIdamageExtension damageExtension = {
+    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
+    __glXReportDamage,
+};
+
+static const __DRIextension *loader_extensions[] = {
+    &systemTimeExtension.base,
+    &getDrawableInfoExtension.base,
+    &damageExtension.base,
+    NULL
+};
+
+
+
+static Bool
+glxDRIEnterVT (int index, int flags)
+{
+    ScrnInfoPtr scrn = xf86Screens[index];
+    Bool	ret;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) 
+	glxGetScreen(screenInfo.screens[index]);
+
+    LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
+
+    scrn->EnterVT = screen->enterVT;
+
+    ret = scrn->EnterVT (index, flags);
+
+    screen->enterVT = scrn->EnterVT;
+    scrn->EnterVT = glxDRIEnterVT;
+
+    if (!ret)
+	return FALSE;
+    
+    glxResumeClients();
+
+    return TRUE;
+}
+
+static void
+glxDRILeaveVT (int index, int flags)
+{
+    ScrnInfoPtr scrn = xf86Screens[index];
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(screenInfo.screens[index]);
+
+    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+
+    glxSuspendClients();
+
+    scrn->LeaveVT = screen->leaveVT;
+    (*screen->leaveVT) (index, flags);
+    screen->leaveVT = scrn->LeaveVT;
+    scrn->LeaveVT = glxDRILeaveVT;
+}
+
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+    const __DRIextension **extensions;
+    int i;
+
+    extensions = screen->core->getExtensions(screen->driScreen);
+
+    for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_READ_DRAWABLE
+	if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_SGI_make_current_read");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+	}
+#endif
+
+#ifdef __DRI_COPY_SUB_BUFFER
+	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+	    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_copy_sub_buffer");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+	}
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+	    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_SGI_swap_control");
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_swap_control");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+	}
+#endif
+
+#ifdef __DRI_TEX_OFFSET
+	if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) {
+	    screen->texOffset = (__DRItexOffsetExtension *) extensions[i];
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n");
+	}
+#endif
+	/* Ignore unknown extensions */
+    }
+}
+    
+static __GLXscreen *
+__glXDRIscreenProbe(ScreenPtr pScreen)
+{
+    drm_handle_t hSAREA;
+    drmAddress pSAREA = NULL;
+    char *BusID;
+    __DRIversion   ddx_version;
+    __DRIversion   dri_version;
+    __DRIversion   drm_version;
+    __DRIframebuffer  framebuffer;
+    int   fd = -1;
+    int   status;
+    drm_magic_t magic;
+    drmVersionPtr version;
+    int newlyopened;
+    char *driverName;
+    drm_handle_t  hFB;
+    int        junk;
+    __GLXDRIscreen *screen;
+    Bool isCapable;
+    size_t buffer_size;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    const __DRIconfig **driConfigs;
+
+    if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
+	!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
+	!isCapable) {
+	LogMessage(X_INFO,
+		   "AIGLX: Screen %d is not DRI capable\n", pScreen->myNum);
+	return NULL;
+    }
+
+    screen = calloc(1, sizeof *screen);
+    if (screen == NULL)
+      return NULL;
+
+    screen->base.destroy        = __glXDRIscreenDestroy;
+    screen->base.createContext  = __glXDRIscreenCreateContext;
+    screen->base.createDrawable = __glXDRIscreenCreateDrawable;
+    screen->base.swapInterval   = __glXDRIdrawableSwapInterval;
+    screen->base.pScreen       = pScreen;
+
+    __glXInitExtensionEnableBits(screen->glx_enable_bits);
+
+    /* DRI protocol version. */
+    dri_version.major = XF86DRI_MAJOR_VERSION;
+    dri_version.minor = XF86DRI_MINOR_VERSION;
+    dri_version.patch = XF86DRI_PATCH_VERSION;
+
+    if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) {
+	LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n");
+	goto handle_error;
+    }
+
+    fd = drmOpenOnce(NULL, BusID, &newlyopened);
+
+    if (fd < 0) {
+	LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n",
+		   strerror(-fd));
+	goto handle_error;
+    }
+
+    if (drmGetMagic(fd, &magic)) {
+	LogMessage(X_ERROR, "AIGLX error: drmGetMagic failed\n");
+	goto handle_error;
+    }
+
+    version = drmGetVersion(fd);
+    if (version) {
+	drm_version.major = version->version_major;
+	drm_version.minor = version->version_minor;
+	drm_version.patch = version->version_patchlevel;
+	drmFreeVersion(version);
+    }
+    else {
+	drm_version.major = -1;
+	drm_version.minor = -1;
+	drm_version.patch = -1;
+    }
+
+    if (newlyopened && !DRIAuthConnection(pScreen, magic)) {
+	LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n");
+	goto handle_error;
+    }
+
+    /* Get device name (like "tdfx") and the ddx version numbers.
+     * We'll check the version in each DRI driver's "createNewScreen"
+     * function. */
+    if (!DRIGetClientDriverName(pScreen,
+				&ddx_version.major,
+				&ddx_version.minor,
+				&ddx_version.patch,
+				&driverName)) {
+	LogMessage(X_ERROR, "AIGLX error: DRIGetClientDriverName failed\n");
+	goto handle_error;
+    }
+
+    screen->driver = glxProbeDriver(driverName,
+				    (void **)&screen->core,
+				    __DRI_CORE, __DRI_CORE_VERSION,
+				    (void **)&screen->legacy,
+				    __DRI_LEGACY, __DRI_LEGACY_VERSION);
+    if (screen->driver == NULL) {
+        goto handle_error;
+    }
+    
+    /*
+     * Get device-specific info.  pDevPriv will point to a struct
+     * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
+     * has information about the screen size, depth, pitch, ancilliary
+     * buffers, DRM mmap handles, etc.
+     */
+    if (!DRIGetDeviceInfo(pScreen, &hFB, &junk,
+			  &framebuffer.size, &framebuffer.stride,
+			  &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
+	LogMessage(X_ERROR, "AIGLX error: XF86DRIGetDeviceInfo failed\n");
+	goto handle_error;
+    }
+
+    framebuffer.width = pScreen->width;
+    framebuffer.height = pScreen->height;
+
+    /* Map the framebuffer region. */
+    status = drmMap(fd, hFB, framebuffer.size, 
+		    (drmAddressPtr)&framebuffer.base);
+    if (status != 0) {
+	LogMessage(X_ERROR, "AIGLX error: drmMap of framebuffer failed (%s)\n",
+		   strerror(-status));
+	goto handle_error;
+    }
+
+    /* Map the SAREA region.  Further mmap regions may be setup in
+     * each DRI driver's "createNewScreen" function.
+     */
+    status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+    if (status != 0) {
+	LogMessage(X_ERROR, "AIGLX error: drmMap of SAREA failed (%s)\n",
+		   strerror(-status));
+	goto handle_error;
+    }
+    
+    screen->driScreen =
+	(*screen->legacy->createNewScreen)(pScreen->myNum,
+					   &ddx_version,
+					   &dri_version,
+					   &drm_version,
+					   &framebuffer,
+					   pSAREA,
+					   fd,
+					   loader_extensions,
+					   &driConfigs,
+					   screen);
+
+    if (screen->driScreen == NULL) {
+	LogMessage(X_ERROR,
+		   "AIGLX error: Calling driver entry point failed\n");
+	goto handle_error;
+    }
+
+    screen->base.fbconfigs = glxConvertConfigs(screen->core,
+					       driConfigs, GLX_WINDOW_BIT);
+
+    initializeExtensions(screen);
+
+    DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
+			 &screen->texOffsetFinish);
+
+    __glXScreenInit(&screen->base, pScreen);
+
+    /* The first call simply determines the length of the extension string.
+     * This allows us to allocate some memory to hold the extension string,
+     * but it requires that we call __glXGetExtensionString a second time.
+     */
+    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+    if (buffer_size > 0) {
+	free(screen->base.GLXextensions);
+
+	screen->base.GLXextensions = xnfalloc(buffer_size);
+	(void) __glXGetExtensionString(screen->glx_enable_bits, 
+				       screen->base.GLXextensions);
+    }
+
+    __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer);
+
+    screen->enterVT = pScrn->EnterVT;
+    pScrn->EnterVT = glxDRIEnterVT;
+    screen->leaveVT = pScrn->LeaveVT;
+    pScrn->LeaveVT = glxDRILeaveVT;
+
+    LogMessage(X_INFO,
+	       "AIGLX: Loaded and initialized %s\n", driverName);
+
+    return &screen->base;
+
+ handle_error:
+    if (pSAREA != NULL)
+	drmUnmap(pSAREA, SAREA_MAX);
+
+    if (framebuffer.base != NULL)
+	drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+
+    if (fd >= 0)
+	drmCloseOnce(fd);
+
+    DRICloseConnection(pScreen);
+
+    if (screen->driver)
+        dlclose(screen->driver);
+
+    free(screen);
+
+    LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
+
+    return NULL;
+}
+
+_X_EXPORT __GLXprovider __glXDRIProvider = {
+    __glXDRIscreenProbe,
+    "DRI",
+    NULL
+};
-- 
cgit v1.2.3