Update gl_API.xml with OpenGL 2.0 functions, regenerate derived files.
[mesa.git] / src / glx / mini / miniglx.c
index 43889964a5c0445915ab1e01f68de73391274af3..d4b295086325733a186597b0d3c6195bd246bcf7 100644 (file)
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/types.h>
+#include <sys/time.h>    /* for gettimeofday */
 #include <linux/kd.h>
 #include <linux/vt.h>
 
 #include "miniglxP.h"
-#include "dri.h"
+#include "dri_util.h"
 
+#include "imports.h"
+#include "glcontextmodes.h"
 #include "glapi.h"
-#include "xf86drm.h"
+
+#include "pciaccess.h"
+
+static GLboolean __glXCreateContextWithConfig(__DRInativeDisplay *dpy,
+        int screen, int fbconfigID, void *contextID,
+        drm_context_t *hHWContext);
+
+static GLboolean __glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn,
+        __DRIid draw, unsigned int * index, unsigned int * stamp,
+        int * x, int * y, int * width, int * height,
+        int * numClipRects, drm_clip_rect_t ** pClipRects,
+        int * backX, int * backY,
+        int * numBackClipRects, drm_clip_rect_t ** pBackClipRects);
+
+static __DRIscreen * __glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn);
+
+static GLboolean __glXWindowExists(__DRInativeDisplay *dpy, __DRIid draw);
+
+static int __glXGetUST( int64_t * ust );
+
+static GLboolean __glXGetMscRate(__DRInativeDisplay * dpy, __DRIid drawable,
+    int32_t * numerator, int32_t * denominator);
+
+static GLboolean xf86DRI_DestroyContext(__DRInativeDisplay *dpy, int screen,
+    __DRIid context_id );
+
+static GLboolean xf86DRI_CreateDrawable(__DRInativeDisplay *dpy, int screen,
+    __DRIid drawable, drm_drawable_t *hHWDrawable );
+
+static GLboolean xf86DRI_DestroyDrawable(__DRInativeDisplay *dpy, int screen,
+    __DRIid drawable);
+
+
+/** Wrapper around either malloc() */
+void *
+_mesa_malloc(size_t bytes)
+{
+   return malloc(bytes);
+}
+
+/** Wrapper around either calloc() */
+void *
+_mesa_calloc(size_t bytes)
+{
+   return calloc(1, bytes);
+}
+
+/** Wrapper around either free() */
+void
+_mesa_free(void *ptr)
+{
+   free(ptr);
+}
 
 
 /**
@@ -383,9 +438,18 @@ SetupFBDev( Display *dpy )
    width = dpy->driverContext.shared.virtualWidth;
    height = dpy->driverContext.shared.virtualHeight;
    
+   if (width==832)
+       width=800;
+#if 0
    /* Bump size up to next supported mode.
     */
-   if (width <= 800 && height <= 600) {
+   if (width <= 720 && height <= 480) { 
+      width = 720; height = 480; 
+   } 
+   else if (width <= 960 && height <= 540) {
+      width = 960; height = 540; 
+   }  
+   else if (width <= 800 && height <= 600) {
       width = 800; height = 600; 
    }  
    else if (width <= 1024 && height <= 768) { 
@@ -397,10 +461,8 @@ SetupFBDev( Display *dpy )
    else if (width <= 1280 && height <= 1024) { 
       width = 1280; height = 1024; 
    } 
+#endif
 
-
-   dpy->driverContext.shared.virtualHeight = height;
-   dpy->driverContext.shared.virtualWidth = width;
    dpy->driverContext.shared.fbStride = width * (dpy->driverContext.bpp / 8);
    
    /* set the depth, resolution, etc */
@@ -408,7 +470,7 @@ SetupFBDev( Display *dpy )
    dpy->VarInfo.bits_per_pixel = dpy->driverContext.bpp;
    dpy->VarInfo.xres_virtual = dpy->driverContext.shared.virtualWidth;
    dpy->VarInfo.yres_virtual = dpy->driverContext.shared.virtualHeight;
-   dpy->VarInfo.xres = width;
+   dpy->VarInfo.xres = dpy->driverContext.shared.Width;
    dpy->VarInfo.yres = height;
    dpy->VarInfo.xoffset = 0;
    dpy->VarInfo.yoffset = 0;
@@ -445,6 +507,8 @@ SetupFBDev( Display *dpy )
       return 0;
    }
 
+   /* These should be calculated with the gtf.c program, and then we could
+      remove all this... AlanH. */
    if (dpy->VarInfo.xres == 1280 && 
        dpy->VarInfo.yres == 1024) {
       /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
@@ -470,12 +534,32 @@ SetupFBDev( Display *dpy )
    else if (dpy->VarInfo.xres == 800 &&
            dpy->VarInfo.yres == 600) {
       /* timing values taken from /etc/fb.modes (800x600 @ 75Hz) */
-      dpy->VarInfo.pixclock = 20203;
-      dpy->VarInfo.left_margin = 160;
+      dpy->VarInfo.pixclock = 27778;
+      dpy->VarInfo.left_margin = 128;
+      dpy->VarInfo.right_margin = 24;
+      dpy->VarInfo.upper_margin = 22;
+      dpy->VarInfo.lower_margin = 1;
+      dpy->VarInfo.hsync_len = 72;
+      dpy->VarInfo.vsync_len = 2;
+   }
+   else if (dpy->VarInfo.xres == 720 &&
+           dpy->VarInfo.yres == 480) {
+      dpy->VarInfo.pixclock = 37202;
+      dpy->VarInfo.left_margin = 88;
       dpy->VarInfo.right_margin = 16;
-      dpy->VarInfo.upper_margin = 21;
+      dpy->VarInfo.upper_margin = 14;
       dpy->VarInfo.lower_margin = 1;
-      dpy->VarInfo.hsync_len = 80;
+      dpy->VarInfo.hsync_len = 72;
+      dpy->VarInfo.vsync_len = 3;
+   }
+   else if (dpy->VarInfo.xres == 960 &&
+           dpy->VarInfo.yres == 540) {
+      dpy->VarInfo.pixclock = 24273;
+      dpy->VarInfo.left_margin = 128;
+      dpy->VarInfo.right_margin = 32;
+      dpy->VarInfo.upper_margin = 16;
+      dpy->VarInfo.lower_margin = 1;
+      dpy->VarInfo.hsync_len = 96;
       dpy->VarInfo.vsync_len = 3;
    }
    else if (dpy->VarInfo.xres == 768 &&
@@ -663,11 +747,11 @@ CloseFBDev( Display *dpy )
  * \internal
  * Returns the MiniGLXDisplayRec::driScreen attribute.
  */
-__DRIscreen *
-__glXFindDRIScreen(Display *dpy, int scrn)
+static __DRIscreen *
+__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn)
 {
    (void) scrn;
-   return dpy->driScreen;
+   return &((Display*)dpy)->driScreen;
 }
 
 /**
@@ -680,10 +764,11 @@ __glXFindDRIScreen(Display *dpy, int scrn)
  * Since Mini GLX only supports one window, compares the specified drawable with
  * the MiniGLXDisplayRec::TheWindow attribute.
  */
-Bool
-__glXWindowExists(Display *dpy, GLXDrawable draw)
+static GLboolean
+__glXWindowExists(__DRInativeDisplay *dpy, __DRIid draw)
 {
-   if (dpy->TheWindow == draw)
+   const Display * const display = (Display*)dpy;
+   if (display->TheWindow == (Window) draw)
       return True;
    else
       return False;
@@ -794,6 +879,8 @@ static int __read_config_file( Display *dpy )
    dpy->driverContext.cpp = 4;
    dpy->rotateMode = 0;
    dpy->driverContext.agpmode = 1;
+   dpy->driverContext.isPCI = 0;
+   dpy->driverContext.colorTiling = 0;
 
    fname = getenv("MINIGLX_CONF");
    if (!fname) fname = "/etc/miniglx.conf";
@@ -863,6 +950,12 @@ static int __read_config_file( Display *dpy )
          if (sscanf(val, "%d", &dpy->driverContext.agpmode) != 1)
             fprintf(stderr, "malformed agpmode: %s\n", opt);
       }
+      else if (strcmp(opt, "isPCI") == 0) {
+        dpy->driverContext.isPCI = atoi(val) ? 1 : 0;
+      }
+      else if (strcmp(opt, "colorTiling") == 0) {
+        dpy->driverContext.colorTiling = atoi(val) ? 1 : 0;
+      }
    }
 
    fclose(file);
@@ -873,6 +966,19 @@ static int __read_config_file( Display *dpy )
    return 1;
 }
 
+/**
+ * Versioned name of the expected \c __driCreateNewScreen function.
+ * 
+ * The version of the last incompatible loader/driver inteface change is
+ * appended to the name of the \c __driCreateNewScreen function.  This
+ * prevents loaders from trying to load drivers that are too old.
+ * 
+ * \todo
+ * Create a macro or something so that this is automatically updated.
+ */
+static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
+
+
 static int InitDriver( Display *dpy )
 {
    /*
@@ -884,7 +990,7 @@ static int InitDriver( Display *dpy )
    if (!dpy->dlHandle) {
       fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName,
              dlerror());
-      return GL_FALSE;
+      goto failed;
    }
 
    /* Pull in Mini GLX specific hooks:
@@ -894,22 +1000,27 @@ static int InitDriver( Display *dpy )
    if (!dpy->driver) {
       fprintf(stderr, "Couldn't find __driDriver in %s\n",
               dpy->clientDriverName);
-      dlclose(dpy->dlHandle);
-      return GL_FALSE;
+      goto failed;
    }
 
    /* Pull in standard DRI client-side driver hooks:
     */
-   dpy->createScreen = (driCreateScreenFunc*) dlsym(dpy->dlHandle,
-                                                "__driCreateScreen");
-   if (!dpy->createScreen) {
-      fprintf(stderr, "Couldn't find __driCreateScreen in %s\n",
+   dpy->createNewScreen = (PFNCREATENEWSCREENFUNC)
+           dlsym(dpy->dlHandle, createNewScreenName);
+   if (!dpy->createNewScreen) {
+      fprintf(stderr, "Couldn't find %s in %s\n", createNewScreenName,
               dpy->clientDriverName);
-      dlclose(dpy->dlHandle);
-      return GL_FALSE;
+      goto failed;
    }
 
    return GL_TRUE;
+
+failed:
+   if (dpy->dlHandle) {
+       dlclose(dpy->dlHandle);
+       dpy->dlHandle = 0;
+   }
+   return GL_FALSE;
 }
 
 
@@ -947,6 +1058,8 @@ __miniglx_StartServer( const char *display_name )
    Display *dpy;
    int use_vt = 0;
 
+   pci_system_init();
+
    dpy = (Display *)calloc(1, sizeof(Display));
    if (!dpy)
       return NULL;
@@ -973,10 +1086,6 @@ __miniglx_StartServer( const char *display_name )
       return NULL;
    }
 
-   /* Ask the driver for a list of supported configs:
-   */
-   dpy->driver->initContextModes( &dpy->driverContext, &dpy->numModes, &dpy->modes );
-
    /* Perform the initialization normally done in the X server 
     */
    if (!dpy->driver->initFBDev( &dpy->driverContext )) {
@@ -1014,6 +1123,206 @@ __miniglx_StartServer( const char *display_name )
 }
 
 
+/**
+ * Implement \c __DRIinterfaceMethods::getProcAddress.
+ */
+static __DRIfuncPtr get_proc_address( const char * proc_name )
+{
+    (void) proc_name;
+    return NULL;
+}
+
+
+/**
+ * Table of functions exported by the loader to the driver.
+ */
+static const __DRIinterfaceMethods interface_methods = {
+    get_proc_address,
+
+    _gl_context_modes_create,
+    _gl_context_modes_destroy,
+      
+    __glXFindDRIScreen,
+    __glXWindowExists,
+      
+    __glXCreateContextWithConfig,
+    xf86DRI_DestroyContext,
+
+    xf86DRI_CreateDrawable,
+    xf86DRI_DestroyDrawable,
+    __glXGetDrawableInfo,
+
+    __glXGetUST,
+    __glXGetMscRate,
+};
+
+
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc)
+{
+    void *psp = NULL;
+    drm_handle_t hSAREA;
+    drmAddress pSAREA;
+    const char *BusID;
+    int   i;
+    __DRIversion   ddx_version;
+    __DRIversion   dri_version;
+    __DRIversion   drm_version;
+    __DRIframebuffer  framebuffer;
+    int   fd = -1;
+    int   status;
+    const char * err_msg;
+    const char * err_extra;
+    drmVersionPtr version;
+    drm_handle_t  hFB;
+    drm_magic_t magic;
+
+
+    hSAREA = dpy->driverContext.shared.hSAREA;
+    BusID = dpy->driverContext.pciBusID;
+
+    fd = drmOpen(NULL, BusID);
+
+    err_msg = "open DRM";
+    err_extra = strerror( -fd );
+
+    if (fd < 0) goto done;
+
+    err_msg = "drmGetMagic";
+    err_extra = NULL;
+
+    if (drmGetMagic(fd, &magic)) goto done;
+    
+    dpy->authorized = False;
+    send_char_msg( dpy, 0, _Authorize );
+    send_msg( dpy, 0, &magic, sizeof(magic));
+    
+    /* force net buffer flush */
+    while (!dpy->authorized)
+      handle_fd_events( dpy, 0 );
+
+    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;
+    }
+
+    /*
+     * Get device name (like "tdfx") and the ddx version numbers.
+     * We'll check the version in each DRI driver's "createScreen"
+     * function.
+     */
+    ddx_version.major = -1;
+    ddx_version.minor = 0;
+    ddx_version.patch = 0;
+
+    /*
+     * Get the DRI X extension version.
+     */
+    dri_version.major = 4;
+    dri_version.minor = 0;
+    dri_version.patch = 0;
+
+    /*
+     * 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.
+     */
+    hFB = dpy->driverContext.shared.hFrameBuffer;
+    framebuffer.size = dpy->driverContext.shared.fbSize;
+    framebuffer.stride = dpy->driverContext.shared.fbStride;
+    framebuffer.dev_priv_size = dpy->driverContext.driverClientMsgSize;
+    framebuffer.dev_priv = dpy->driverContext.driverClientMsg;
+    framebuffer.width = dpy->driverContext.shared.virtualWidth;
+    framebuffer.height = dpy->driverContext.shared.virtualHeight;
+
+    /*
+     * Map the framebuffer region.
+     */
+    status = drmMap(fd, hFB, framebuffer.size, 
+            (drmAddressPtr)&framebuffer.base);
+
+    err_msg = "drmMap of framebuffer";
+    err_extra = strerror( -status );
+
+    if ( status != 0 ) goto done;
+
+    /*
+     * Map the SAREA region.  Further mmap regions may be setup in
+     * each DRI driver's "createScreen" function.
+     */
+    status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+
+    err_msg = "drmMap of sarea";
+    err_extra = strerror( -status );
+
+    if ( status == 0 ) {
+        err_msg = "InitDriver";
+        err_extra = NULL;
+        psp = dpy->createNewScreen(dpy, scrn, psc, NULL,
+                & ddx_version,
+                & dri_version,
+                & drm_version,
+                & framebuffer,
+                pSAREA,
+                fd,
+                20050727,
+               & interface_methods,
+                (__GLcontextModes **) &dpy->driver_modes);
+
+       /* fill in dummy visual ids */
+       {
+         __GLcontextModes *temp;
+         temp = (__GLcontextModes *)dpy->driver_modes;
+         i = 1;
+         while (temp)
+         {
+           temp->visualID = i++;
+           temp=temp->next;
+         }
+       }
+    }
+    
+done:
+    if ( psp == NULL ) {
+        if ( pSAREA != MAP_FAILED ) {
+            (void)drmUnmap(pSAREA, SAREA_MAX);
+        }
+
+        if ( framebuffer.base != MAP_FAILED ) {
+            (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+        }
+
+        if ( framebuffer.dev_priv != NULL ) {
+            free(framebuffer.dev_priv);
+        }
+
+        if ( fd >= 0 ) {
+            (void)drmClose(fd);
+        }
+
+        if ( err_extra != NULL ) {
+            fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
+                    err_extra);
+        }
+        else {
+            fprintf(stderr, "libGL error: %s failed\n", err_msg );
+        }
+
+        fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
+    }
+
+    return psp;
+}
+
 /**
  * \brief Initialize the graphics system.
  * 
@@ -1072,10 +1381,6 @@ XOpenDisplay( const char *display_name )
       return NULL;
    }
 
-   /* Ask the driver for a list of supported configs:
-   */
-   dpy->driver->initContextModes( &dpy->driverContext, &dpy->numModes, &dpy->modes );
-   
    /* Perform the client-side initialization.  
     *
     * Clearly there is a limit of one on the number of windows in
@@ -1083,9 +1388,8 @@ XOpenDisplay( const char *display_name )
     *
     * Need to shut down DRM and free DRI data in XDestroyWindow(), too.
     */
-   dpy->driScreen = (*dpy->createScreen)(dpy->driver,
-                                        &dpy->driverContext);
-   if (!dpy->driScreen) {
+   dpy->driScreen.private = CallCreateNewScreen(dpy, 0, &dpy->driScreen);
+   if (!dpy->driScreen.private) {
       fprintf(stderr, "%s: __driCreateScreen failed\n", __FUNCTION__);
       dlclose(dpy->dlHandle);
       free(dpy);
@@ -1124,7 +1428,7 @@ XCloseDisplay( Display *dpy )
 
    /* As this is done in XOpenDisplay, need to undo it here:
     */
-   (*dpy->driScreen->destroyScreen)(dpy->driScreen);
+   dpy->driScreen.destroyScreen(dpy, 0, dpy->driScreen.private);
 
    __miniglx_close_connections( dpy );
 
@@ -1187,6 +1491,8 @@ XCreateWindow( Display *dpy, Window parent, int x, int y,
                Visual *visual, unsigned long valuemask,
                XSetWindowAttributes *attributes )
 {
+   const int empty_attribute_list[1] = { None };
+
    Window win;
 
    /* ignored */
@@ -1252,11 +1558,10 @@ XCreateWindow( Display *dpy, Window parent, int x, int y,
       win->curBottom = win->frontBottom;
    }
 
-   win->driDrawable = dpy->driScreen->createDrawable(dpy->driScreen, 
-                                                    width, height, 
-                                                    dpy->clientID, visual->mode);
+   dpy->driScreen.createNewDrawable(dpy, visual->mode, (int) win,
+           &win->driDrawable, GLX_WINDOW_BIT, empty_attribute_list);
 
-   if (!win->driDrawable) {
+   if (!win->driDrawable.private) {
       fprintf(stderr, "%s: dri.createDrawable failed\n", __FUNCTION__);
       free(win);
       return NULL;
@@ -1293,7 +1598,7 @@ XDestroyWindow( Display *display, Window win )
       XUnmapWindow( display, win );
 
       /* Destroy the drawable. */
-      (*win->driDrawable->destroyDrawable)(win->driDrawable);
+      win->driDrawable.destroyDrawable(display, win->driDrawable.private);
       free(win);
       
       /* unlink window from display */
@@ -1397,49 +1702,105 @@ XFree( void *data )
 XVisualInfo *
 XGetVisualInfo( Display *dpy, long vinfo_mask, XVisualInfo *vinfo_template, int *nitens_return )
 {
+   const __GLcontextModes *mode;
    XVisualInfo *results;
    Visual *visResults;
-   int i, n;
+   int i, n=0;
 
-   ASSERT(vinfo_mask == VisualScreenMask);
+   //   ASSERT(vinfo_mask == VisualScreenMask);
    ASSERT(vinfo_template.screen == 0);
 
-   n = dpy->numModes;
-   results = (XVisualInfo *)calloc(1, n * sizeof(XVisualInfo));
-   if (!results) {
-      *nitens_return = 0;
-      return NULL;
-   }
-
-   visResults = (Visual *)calloc(1, n * sizeof(Visual));
-   if (!results) {
-      free(results);
-      *nitens_return = 0;
-      return NULL;
-   }
+   if (vinfo_mask == VisualIDMask)
+   {
+     for ( mode = dpy->driver_modes ; mode != NULL ; mode= mode->next )
+       if (mode->visualID == vinfo_template->visualid)
+        n=1;
 
-   for (i = 0; i < n; i++) {
-      visResults[i].mode = dpy->modes + i;
-      visResults[i].visInfo = results + i;
-      visResults[i].dpy = dpy;
+     if (n==0)
+       return NULL;
+     
+     results = (XVisualInfo *)calloc(1, n * sizeof(XVisualInfo));
+     if (!results) {
+       *nitens_return = 0;
+       return NULL;
+     }
+     
+     visResults = (Visual *)calloc(1, n * sizeof(Visual));
+     if (!results) {
+       free(results);
+       *nitens_return = 0;
+       return NULL;
+     }
 
-      if (dpy->driverContext.bpp == 32)
+     for ( mode = dpy->driver_modes ; mode != NULL ; mode= mode->next )
+       if (mode->visualID == vinfo_template->visualid)
+       {
+        visResults[0].mode=mode;
+        visResults[0].visInfo = results;
+        visResults[0].dpy = dpy;
+        if (dpy->driverContext.bpp == 32)
+          visResults[0].pixelFormat = PF_B8G8R8A8; /* XXX: FIX ME */
+        else
+          visResults[0].pixelFormat = PF_B5G6R5; /* XXX: FIX ME */
+       
+        results[0].visual = visResults;
+        results[0].visualid = mode->visualID;
+#if defined(__cplusplus) || defined(c_plusplus)
+        results[0].c_class = TrueColor;
+#else
+        results[0].class = TrueColor;
+#endif
+        results[0].depth = mode->redBits +
+          mode->redBits +
+          mode->redBits +
+          mode->redBits;
+        results[0].bits_per_rgb = dpy->driverContext.bpp;
+        
+       }
+     
+   }
+   else // if (vinfo_mask == VisualScreenMask)
+   {
+     n = 0;
+     for ( mode = dpy->driver_modes ; mode != NULL ; mode = mode->next )
+       n++;
+     
+     results = (XVisualInfo *)calloc(1, n * sizeof(XVisualInfo));
+     if (!results) {
+       *nitens_return = 0;
+       return NULL;
+     }
+     
+     visResults = (Visual *)calloc(1, n * sizeof(Visual));
+     if (!results) {
+       free(results);
+       *nitens_return = 0;
+       return NULL;
+     }
+     
+     for ( mode = dpy->driver_modes, i = 0 ; mode != NULL ; mode = mode->next, i++ ) {
+       visResults[i].mode = mode;
+       visResults[i].visInfo = results + i;
+       visResults[i].dpy = dpy;
+       
+       if (dpy->driverContext.bpp == 32)
         visResults[i].pixelFormat = PF_B8G8R8A8; /* XXX: FIX ME */
-      else
+       else
         visResults[i].pixelFormat = PF_B5G6R5; /* XXX: FIX ME */
-
-      results[i].visual = visResults + i;
-      results[i].visualid = i;
+       
+       results[i].visual = visResults + i;
+       results[i].visualid = mode->visualID;
 #if defined(__cplusplus) || defined(c_plusplus)
-      results[i].c_class = TrueColor;
+       results[i].c_class = TrueColor;
 #else
-      results[i].class = TrueColor;
+       results[i].class = TrueColor;
 #endif
-      results[i].depth = dpy->modes[i].redBits +
-                         dpy->modes[i].redBits +
-                         dpy->modes[i].redBits +
-                         dpy->modes[i].redBits;
-      results[i].bits_per_rgb = dpy->driverContext.bpp;
+       results[i].depth = mode->redBits +
+        mode->redBits +
+        mode->redBits +
+        mode->redBits;
+       results[i].bits_per_rgb = dpy->driverContext.bpp;
+     }
    }
    *nitens_return = n;
    return results;
@@ -1500,6 +1861,7 @@ XGetVisualInfo( Display *dpy, long vinfo_mask, XVisualInfo *vinfo_template, int
 XVisualInfo*
 glXChooseVisual( Display *dpy, int screen, int *attribList )
 {
+   const __GLcontextModes *mode;
    Visual *vis;
    XVisualInfo *visInfo;
    const int *attrib;
@@ -1507,7 +1869,7 @@ glXChooseVisual( Display *dpy, int screen, int *attribList )
    GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
    GLint indexBits = 0, depthBits = 0, stencilBits = 0;
    GLint numSamples = 0;
-   int i;
+   int i=0;
 
    /*
     * XXX in the future, <screen> might be interpreted as a VT
@@ -1600,10 +1962,10 @@ glXChooseVisual( Display *dpy, int screen, int *attribList )
    (void) blueBits;
    (void) alphaBits;
    (void) stereoFlag;
-   for (i = 0; i < dpy->numModes; i++) {
-      const __GLcontextModes *mode = dpy->modes + i;
+   for ( mode = dpy->driver_modes ; mode != NULL ; mode = mode->next ) {
+     i++;
       if (mode->rgbMode == rgbFlag &&
-         (mode->redBits+mode->greenBits+mode->blueBits+mode->alphaBits) == dpy->driverContext.bpp &&
+          mode->doubleBufferMode == dbFlag &&
           mode->redBits >= redBits &&
           mode->greenBits >= greenBits &&
           mode->blueBits >= blueBits &&
@@ -1749,14 +2111,15 @@ glXCreateContext( Display *dpy, XVisualInfo *vis,
    ctx->vid = vis->visualid;
  
    if (shareList)
-      sharePriv = shareList->driContext;
+      sharePriv = shareList->driContext.private;
    else
       sharePriv = NULL;
-   
-   ctx->driContext = (*dpy->driScreen->createContext)(dpy->driScreen, 
-                                                     vis->visual->mode,
-                                                     sharePriv);
-   if (!ctx->driContext) {
+  
+   ctx->driContext.mode = vis->visual->mode;
+   ctx->driContext.private = dpy->driScreen.createNewContext(dpy, vis->visual->mode,
+           GLX_WINDOW_BIT, sharePriv, &ctx->driContext);
+
+   if (!ctx->driContext.private) {
       free(ctx);
       return NULL;
    }
@@ -1783,10 +2146,10 @@ glXDestroyContext( Display *dpy, GLXContext ctx )
    if (ctx) {
       if (glxctx == ctx) {
          /* destroying current context */
-         (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0);
+         ctx->driContext.bindContext(dpy, 0, 0, 0, 0);
         CurrentContext = 0;
       }
-      (*ctx->driContext->destroyContext)(ctx->driContext);
+      ctx->driContext.destroyContext(dpy, 0, ctx->driContext.private);
       free(ctx);
    }
 }
@@ -1826,17 +2189,20 @@ glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx)
       GLXDrawable oldDrawable = glXGetCurrentDrawable();
       /* unbind old */
       if (oldContext) {
-         (*oldContext->driContext->unbindContext)(oldDrawable->driDrawable, oldContext->driContext);
+         oldContext->driContext.unbindContext(dpy, 0,
+                 (__DRIid) oldDrawable, (__DRIid) oldDrawable,
+                 &oldContext->driContext);
       }
       /* bind new */
       CurrentContext = ctx;
-      (*ctx->driContext->bindContext)(dpy->driScreen, drawable->driDrawable, ctx->driContext);
+      ctx->driContext.bindContext(dpy, 0, (__DRIid) drawable,
+              (__DRIid) drawable, &ctx->driContext);
       ctx->drawBuffer = drawable;
       ctx->curBuffer = drawable;
    }
    else if (ctx && dpy) {
       /* unbind */
-      (*ctx->driContext->bindContext)(dpy->driScreen, 0, 0);
+      ctx->driContext.bindContext(dpy, 0, 0, 0, 0);
    }
    else if (dpy) {
       CurrentContext = 0;      /* kw:  this seems to be intended??? */
@@ -1866,7 +2232,7 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable )
    if (!dpy || !drawable)
       return;
 
-   (*drawable->driDrawable->swapBuffers)(drawable->driDrawable);
+   drawable->driDrawable.swapBuffers(dpy, drawable->driDrawable.private);
 }
 
 
@@ -1907,6 +2273,96 @@ glXGetCurrentDrawable( void )
 }
 
 
+static GLboolean
+__glXCreateContextWithConfig(__DRInativeDisplay *dpy, int screen,
+        int fbconfigID, void *contextID, drm_context_t *hHWContext)
+{
+    __DRIscreen *pDRIScreen;
+    __DRIscreenPrivate *psp;
+
+    pDRIScreen = __glXFindDRIScreen(dpy, screen);
+    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+        return GL_FALSE;
+    }
+
+    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+
+    if (psp->fd) {
+        if (drmCreateContext(psp->fd, hHWContext)) {
+            fprintf(stderr, ">>> drmCreateContext failed\n");
+            return GL_FALSE;
+        }
+        *(void**)contextID = (void*) *hHWContext;
+    }
+
+    return GL_TRUE;
+}
+
+
+static GLboolean
+__glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn,
+        __DRIid draw, unsigned int * index, unsigned int * stamp,
+        int * x, int * y, int * width, int * height,
+        int * numClipRects, drm_clip_rect_t ** pClipRects,
+        int * backX, int * backY,
+        int * numBackClipRects, drm_clip_rect_t ** pBackClipRects)
+{
+    GLXDrawable drawable = (GLXDrawable) draw;
+    drm_clip_rect_t * cliprect;
+    Display* display = (Display*)dpy;
+    __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)CurrentContext->driContext.private;
+    if (drawable == 0) {
+        return GL_FALSE;
+    }
+
+    cliprect = (drm_clip_rect_t*) _mesa_malloc(sizeof(drm_clip_rect_t));
+    cliprect->x1 = drawable->x;
+    cliprect->y1 = drawable->y;
+    cliprect->x2 = drawable->x + drawable->w;
+    cliprect->y2 = drawable->y + drawable->h;
+    
+    /* the drawable index is by client id */
+    *index = display->clientID;
+
+    *stamp = pcp->driScreenPriv->pSAREA->drawableTable[display->clientID].stamp;
+    *x = drawable->x;
+    *y = drawable->y;
+    *width = drawable->w;
+    *height = drawable->h;
+    *numClipRects = 1;
+    *pClipRects = cliprect;
+    
+    *backX = drawable->x;
+    *backY = drawable->y;
+    *numBackClipRects = 0;
+    *pBackClipRects = 0;
+
+    return GL_TRUE;
+}
+
+
+static GLboolean
+xf86DRI_DestroyContext(__DRInativeDisplay *dpy, int screen, __DRIid context_id )
+{
+    return GL_TRUE;
+}
+
+
+static GLboolean
+xf86DRI_CreateDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable,
+        drm_drawable_t *hHWDrawable )
+{
+    return GL_TRUE;
+}
+
+
+static GLboolean
+xf86DRI_DestroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
+{
+    return GL_TRUE;
+}
+
+
 /**
  * \brief Query function address.
  *
@@ -1927,8 +2383,7 @@ glXGetCurrentDrawable( void )
  * Returns the function address by looking up its name in a static (name,
  * address) pair list.
  */
-const void *
-glXGetProcAddress( const GLubyte *procName )
+void (*glXGetProcAddress(const GLubyte *procname))( void ) 
 {
    struct name_address {
       const char *name;
@@ -1960,11 +2415,11 @@ glXGetProcAddress( const GLubyte *procName )
    };
    const struct name_address *entry;
    for (entry = functions; entry->name; entry++) {
-      if (strcmp(entry->name, (const char *) procName) == 0) {
+      if (strcmp(entry->name, (const char *) procname) == 0) {
          return entry->func;
       }
    }
-   return _glapi_get_proc_address((const char *) procName);
+   return _glapi_get_proc_address((const char *) procname);
 }
 
 
@@ -2036,5 +2491,77 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
    return config.visInfo;
 }
 
+void *glXAllocateMemoryMESA(Display *dpy, int scrn,
+                            size_t size, float readFreq,
+                            float writeFreq, float priority)
+{
+    if (dpy->driScreen.private && dpy->driScreen.allocateMemory) {
+       return (*dpy->driScreen.allocateMemory)( dpy, scrn, size,
+                                                readFreq, writeFreq,
+                                                priority );
+    }
+
+    return NULL;
+}
+
+void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
+{
+    if (dpy->driScreen.private && dpy->driScreen.freeMemory) {
+       (*dpy->driScreen.freeMemory)( dpy, scrn, pointer );
+    }
+}
 
+GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
+                               const void *pointer )
+{
+    if (dpy->driScreen.private && dpy->driScreen.memoryOffset) {
+       return (*dpy->driScreen.memoryOffset)( dpy, scrn, pointer );
+    }
+
+    return 0;
+}
+
+
+/**
+ * Get the unadjusted system time (UST).  Currently, the UST is measured in
+ * microseconds since Epoc.  The actual resolution of the UST may vary from
+ * system to system, and the units may vary from release to release.
+ * Drivers should not call this function directly.  They should instead use
+ * \c glXGetProcAddress to obtain a pointer to the function.
+ *
+ * \param ust Location to store the 64-bit UST
+ * \returns Zero on success or a negative errno value on failure.
+ *
+ * \note
+ * This function was copied directly from src/glx/x11/glxcmds.c.
+ */
+static int __glXGetUST( int64_t * ust )
+{
+    struct timeval  tv;
+    
+    if ( ust == NULL ) {
+       return -EFAULT;
+    }
+
+    if ( gettimeofday( & tv, NULL ) == 0 ) {
+       ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
+       return 0;
+    } else {
+       return -errno;
+    }
+}
+
+
+/**
+ * 
+ * \bug
+ * This needs to be implemented for miniGlx.
+ */
+static GLboolean __glXGetMscRate(__DRInativeDisplay * dpy, __DRIid drawable,
+                                int32_t * numerator, int32_t * denominator)
+{
+    *numerator = 0;
+    *denominator = 0;
+    return False;
+}
 /*@}*/