xserver: Branch 'xorg-server-1.5-apple' - 2 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Tue Feb 24 22:51:36 PST 2009


 configure.ac                 |    2 
 hw/xquartz/GL/indirect.c     |  713 ++++++-------------------------------------
 hw/xquartz/xpr/Makefile.am   |    2 
 hw/xquartz/xpr/appledri.c    |   78 ++++
 hw/xquartz/xpr/appledri.h    |   21 +
 hw/xquartz/xpr/appledristr.h |   76 ++++
 hw/xquartz/xpr/dri.c         |  393 ++++++++++++++++++-----
 hw/xquartz/xpr/dri.h         |   12 
 hw/xquartz/xpr/driWrap.c     |  547 ++++++++++++++++++++++++++++++++
 hw/xquartz/xpr/driWrap.h     |   31 +
 10 files changed, 1180 insertions(+), 695 deletions(-)

New commits:
commit 09b52385674484dcd08c5bd85c8bd13dca56590a
Author: Jeremy Huddleston <jeremy at yuffie.local>
Date:   Tue Feb 24 22:44:55 2009 -0800

    1.5.3-apple4

diff --git a/configure.ac b/configure.ac
index 3fba842..90be871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.5.3-apple3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.5.3-apple4, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="24 February 2009"
 REMEMBER_REMEMBER="The Twentyfourth of February"
 AC_CONFIG_SRCDIR([Makefile.am])
commit 9f04b10deaf8d2ffee216092f29935263aaf5ad1
Author: Jeremy Huddleston <jeremy at yuffie.local>
Date:   Tue Feb 24 22:43:47 2009 -0800

    XQuartz: Update GLX code from George's efforts on the 1.6 branch

diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 5ab7ecd..9b54b0c 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -65,7 +65,6 @@
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/CGLContext.h>
 
-// X11 and X11's glx
 #include <GL/gl.h>
 #include <GL/glxproto.h>
 #include <windowstr.h>
@@ -86,16 +85,13 @@
 
 #include "capabilities.h"
 
-#include <dispatch.h>
-#define GLAPIENTRYP *
 typedef unsigned long long GLuint64EXT;
 typedef long long GLint64EXT;
+#include <dispatch.h>
 #include <Xplugin.h>
 #include <glapi.h>
 #include <glapitable.h>
 
-// ggs: needed to call back to glx with visual configs
-extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **configprivs);
 __GLXprovider * GlxGetDRISWrastProvider (void);
 
 // Write debugging output, or not
@@ -113,15 +109,6 @@ void warn_func(void * p1, char *format, ...);
 static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen);
 static __GLXdrawable * __glXAquaScreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, __GLXconfig *conf);
 
-static Bool glAquaInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
-                              int *nvisualp, int *ndepthp,
-                              int *rootDepthp, VisualID *defaultVisp,
-                              unsigned long sizes, int bitsPerRGB);
-
-static void glAquaSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
-                                   void **privates);
-
-static void glAquaResetExtension(void);
 static void __glXAquaContextDestroy(__GLXcontext *baseContext);
 static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext);
 static int __glXAquaContextLoseCurrent(__GLXcontext *baseContext);
@@ -131,16 +118,16 @@ static int __glXAquaContextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, un
 static CGLPixelFormatObj makeFormat(__GLXconfig *conf);
 
 __GLXprovider __glXDRISWRastProvider = {
-  __glXAquaScreenProbe,
-  "Core OpenGL",
+    __glXAquaScreenProbe,
+    "Core OpenGL",
     NULL
 };
 
 __GLXprovider *
 GlxGetDRISWRastProvider (void)
 {
-  GLAQUA_DEBUG_MSG("GlxGetDRISWRastProvider\n");
-  return &__glXDRISWRastProvider;
+    GLAQUA_DEBUG_MSG("GlxGetDRISWRastProvider\n");
+    return &__glXDRISWRastProvider;
 }
 
 typedef struct __GLXAquaScreen   __GLXAquaScreen;
@@ -151,11 +138,8 @@ struct __GLXAquaScreen {
     __GLXscreen base;
     int index;
     int num_vis;
-    //__GLcontextModes *modes;
 };
 
-static __GLXAquaScreen glAquaScreens[MAXSCREENS];
-
 struct __GLXAquaContext {
     __GLXcontext base;
     CGLContextObj ctx;
@@ -168,71 +152,60 @@ struct __GLXAquaDrawable {
     __GLXdrawable base;
     DrawablePtr pDraw;
     xp_surface_id sid;
+    __GLXAquaContext *context;
 };
 
+
 static __GLXcontext *
 __glXAquaScreenCreateContext(__GLXscreen *screen,
 			     __GLXconfig *conf,
 			     __GLXcontext *baseShareContext)
 {
-  __GLXAquaContext *context;
-  __GLXAquaContext *shareContext = (__GLXAquaContext *) baseShareContext;
-  CGLError gl_err;
+    __GLXAquaContext *context;
+    __GLXAquaContext *shareContext = (__GLXAquaContext *) baseShareContext;
+    CGLError gl_err;
   
-  GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n");
-
-  context = xalloc (sizeof (__GLXAquaContext));
-
-  if (context == NULL)
-      return NULL;
-
-  memset(context, 0, sizeof *context);
-
-  context->base.pGlxScreen = screen;
-
-  context->base.destroy        = __glXAquaContextDestroy;
-  context->base.makeCurrent    = __glXAquaContextMakeCurrent;
-  context->base.loseCurrent    = __glXAquaContextLoseCurrent;
-  context->base.copy           = __glXAquaContextCopy;
-  context->base.forceCurrent   = __glXAquaContextForceCurrent;
-  /*FIXME verify that the context->base is fully initialized. */
-
-  context->pixelFormat = makeFormat(conf);
+    GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n");
+    
+    context = xcalloc(1, sizeof (__GLXAquaContext));
+    
+    if (context == NULL)
+	return NULL;
 
-  if (!context->pixelFormat) {
+    memset(context, 0, sizeof *context);
+    
+    context->base.pGlxScreen = screen;
+    
+    context->base.destroy        = __glXAquaContextDestroy;
+    context->base.makeCurrent    = __glXAquaContextMakeCurrent;
+    context->base.loseCurrent    = __glXAquaContextLoseCurrent;
+    context->base.copy           = __glXAquaContextCopy;
+    context->base.forceCurrent   = __glXAquaContextForceCurrent;
+    /*FIXME verify that the context->base is fully initialized. */
+    
+    context->pixelFormat = makeFormat(conf);
+    
+    if (!context->pixelFormat) {
         xfree(context);
         return NULL;
-  }
-
-  context->ctx = NULL;
-  gl_err = CGLCreateContext(context->pixelFormat,
-                            shareContext ? shareContext->ctx : NULL,
-                            &context->ctx);
-
-  if (gl_err != 0) {
-      ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err));
-      CGLDestroyPixelFormat(context->pixelFormat);
-      xfree(context);
-      return NULL;
-  }
+    }
 
-  setup_dispatch_table();
-  GLAQUA_DEBUG_MSG("glAquaCreateContext done\n");
+    context->ctx = NULL;
+    gl_err = CGLCreateContext(context->pixelFormat,
+			      shareContext ? shareContext->ctx : NULL,
+			      &context->ctx);
     
-  return &context->base;
-}
-
-/* Nothing seems to use these anymore... */
-static __GLXextensionInfo __glDDXExtensionInfo = {
-    GL_CORE_APPLE,
-    glAquaResetExtension,
-    glAquaInitVisuals,
-    glAquaSetVisualConfigs
-};
-
-void *__glXglDDXExtensionInfo(void) {
-  GLAQUA_DEBUG_MSG("glXAglDDXExtensionInfo\n");
-    return &__glDDXExtensionInfo;
+    if (gl_err != 0) {
+	ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err));
+	CGLDestroyPixelFormat(context->pixelFormat);
+	xfree(context);
+	return NULL;
+    }
+    
+    setup_dispatch_table();
+    GLAQUA_DEBUG_MSG("glAquaCreateContext done\n");
+    
+    return &context->base;
 }
 
 /* maps from surface id -> list of __GLcontext */
@@ -242,7 +215,7 @@ static void __glXAquaContextDestroy(__GLXcontext *baseContext) {
     x_list *lst;
 
     __GLXAquaContext *context = (__GLXAquaContext *) baseContext;
-
+    
     GLAQUA_DEBUG_MSG("glAquaContextDestroy (ctx 0x%x)\n",
                      (unsigned int) baseContext);
     if (context != NULL) {
@@ -283,33 +256,33 @@ static void surface_notify(void *_arg, void *data) {
     __GLXAquaDrawable *draw = (__GLXAquaDrawable *)data;
     __GLXAquaContext *context;
     x_list *lst;
-	if(_arg == NULL || data == NULL) {
-		ErrorF("surface_notify called with bad params");
-		return;
-	}
+    if(_arg == NULL || data == NULL) {
+	    ErrorF("surface_notify called with bad params");
+	    return;
+    }
 	
     GLAQUA_DEBUG_MSG("surface_notify(%p, %p)\n", _arg, data);
     switch (arg->kind) {
     case AppleDRISurfaceNotifyDestroyed:
         if (surface_hash != NULL)
             x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(arg->id));
-	        draw->base.pDraw = NULL;
-			draw->sid = 0;
+	draw->base.pDraw = NULL;
+	draw->sid = 0;
         break;
 
     case AppleDRISurfaceNotifyChanged:
         if (surface_hash != NULL) {
             lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(arg->id), NULL);
             for (; lst != NULL; lst = lst->next)
-            {
+		{
                 context = lst->data;
                 xp_update_gl_context(context->ctx);
             }
         }
         break;
-	default:
-		ErrorF("surface_notify: unknown kind %d\n", arg->kind);
-		break;
+    default:
+	ErrorF("surface_notify: unknown kind %d\n", arg->kind);
+	break;
     }
 }
 
@@ -324,7 +297,7 @@ static BOOL attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) {
     pDraw = draw->base.pDraw;
 
     if(NULL == pDraw) {
-	ErrorF("%s:attach() pDraw is NULL!\n", __FILE__);
+	ErrorF("%s:%s() pDraw is NULL!\n", __FILE__, __func__);
 	return TRUE;
     }
 
@@ -363,10 +336,14 @@ static BOOL attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) {
             x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst);
         }
 	
+	
+
         GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", (unsigned int) pDraw->id,
                          (unsigned int) draw->sid);
     } 
 
+    draw->context = context;
+
     return FALSE;
 }
 
@@ -442,27 +419,31 @@ static int __glXAquaContextForceCurrent(__GLXcontext *baseContext)
 
 /* Drawing surface notification callbacks */
 
-static GLboolean __glXAquaDrawableResize(__GLXdrawable *base)  {
-    GLAQUA_DEBUG_MSG("unimplemented glAquaDrawableResize\n");
-    return GL_TRUE;
-}
-
 static GLboolean __glXAquaDrawableSwapBuffers(__GLXdrawable *base) {
-    CGLError gl_err;
-    __GLXAquaContext * drawableCtx;
+    CGLError err;
+    __GLXAquaDrawable *drawable;
+ 
     //    GLAQUA_DEBUG_MSG("glAquaDrawableSwapBuffers(%p)\n",base);
 	
     if(!base) {
-	ErrorF("glXAquaDrawbleSwapBuffers passed NULL\n");
+	ErrorF("%s passed NULL\n", __func__);
 	return GL_FALSE;
     }
 
-    drawableCtx = (__GLXAquaContext *)base->drawGlxc;
-    
-    if (drawableCtx != NULL && drawableCtx->ctx != NULL) {
-        gl_err = CGLFlushDrawable(drawableCtx->ctx);
-        if (gl_err != 0)
-            ErrorF("CGLFlushDrawable error: %s\n", CGLErrorString(gl_err));
+    drawable = (__GLXAquaDrawable *)base;
+
+    if(NULL == drawable->context) {
+	ErrorF("%s called with a NULL->context for drawable %p!\n",
+	       __func__, (void *)drawable);
+	return GL_FALSE;
+    }
+
+    err = CGLFlushDrawable(drawable->context->ctx);
+
+    if(kCGLNoError != err) {
+	ErrorF("CGLFlushDrawable error: %s in %s\n", CGLErrorString(err),
+	       __func__);
+	return GL_FALSE;
     }
 
     return GL_TRUE;
@@ -526,482 +507,6 @@ static CGLPixelFormatObj makeFormat(__GLXconfig *conf) {
     return fobj;
 }
 
-// Originally copied from Mesa
-
-static int                 numConfigs     = 0;
-static __GLXvisualConfig  *visualConfigs  = NULL;
-static void              **visualPrivates = NULL;
-
-/*
- * In the case the driver defines no GLX visuals we'll use these.
- * Note that for TrueColor and DirectColor visuals, bufferSize is the 
- * sum of redSize, greenSize, blueSize and alphaSize, which may be larger 
- * than the nplanes/rootDepth of the server's X11 visuals
- */
-#define NUM_FALLBACK_CONFIGS 5
-static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
-  /* [0] = RGB, double buffered, Z */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [1] = RGB, double buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-    16, 16, 16, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 8,      /* rgba sizes */
-    -1, -1, -1, -1,     /* rgba masks */
-    16, 16, 16, 16,     /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    True,               /* rgba */
-    -1, -1, -1, 8,      /* rgba sizes */
-    -1, -1, -1, -1,     /* rgba masks */
-    16, 16, 16, 16,     /* rgba accum sizes */
-    False,              /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    8,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-  /* [4] = CI, double buffered, Z */
-  {
-    -1,                 /* vid */
-    -1,                 /* class */
-    False,              /* rgba? (false = color index) */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    True,               /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE,           /* visualRating */
-    GLX_NONE,           /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-  },
-};
-
-static __GLXvisualConfig NullConfig = {
-    -1,                 /* vid */
-    -1,                 /* class */
-    False,              /* rgba */
-    -1, -1, -1, 0,      /* rgba sizes */
-    -1, -1, -1, 0,      /* rgba masks */
-     0,  0,  0, 0,      /* rgba accum sizes */
-    False,              /* doubleBuffer */
-    False,              /* stereo */
-    -1,                 /* bufferSize */
-    16,                 /* depthSize */
-    0,                  /* stencilSize */
-    0,                  /* auxBuffers */
-    0,                  /* level */
-    GLX_NONE_EXT,       /* visualRating */
-    0,                  /* transparentPixel */
-    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
-    0                   /* transparentIndex */
-};
-
-
-static inline int count_bits(uint32_t x)
-{
-    x = x - ((x >> 1) & 0x55555555);
-    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
-    x = (x + (x >> 4)) & 0x0f0f0f0f;
-    x = x + (x >> 8);
-    x = x + (x >> 16);
-    return x & 63;
-}
-
-
-static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
-                         VisualID *defaultVisp,
-                         int ndepth, DepthPtr pdepth,
-                         int rootDepth)
-{
-#if 0
-    int numRGBconfigs;
-    int numCIconfigs;
-    int numVisuals = *nvisualp;
-    int numNewVisuals;
-    int numNewConfigs;
-    VisualPtr pVisual = *visualp;
-    VisualPtr pVisualNew = NULL;
-    VisualID *orig_vid = NULL;
-    __GLcontextModes *modes;
-    __GLXvisualConfig *pNewVisualConfigs = NULL;
-    void **glXVisualPriv;
-    void **pNewVisualPriv;
-    int found_default;
-    int i, j, k;
-
-    GLAQUA_DEBUG_MSG("init_visuals\n");
-
-    if (numConfigs > 0)
-        numNewConfigs = numConfigs;
-    else
-        numNewConfigs = NUM_FALLBACK_CONFIGS;
-
-    /* Alloc space for the list of new GLX visuals */
-    pNewVisualConfigs = (__GLXvisualConfig *)
-                     malloc(numNewConfigs * sizeof(__GLXvisualConfig));
-    if (!pNewVisualConfigs) {
-        return FALSE;
-    }
-
-    /* Alloc space for the list of new GLX visual privates */
-    pNewVisualPriv = (void **) malloc(numNewConfigs * sizeof(void *));
-    if (!pNewVisualPriv) {
-        free(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /*
-    ** If SetVisualConfigs was not called, then use default GLX
-    ** visual configs.
-    */
-    if (numConfigs == 0) {
-        memcpy(pNewVisualConfigs, FallbackConfigs,
-               NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
-        memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
-    }
-    else {
-        /* copy driver's visual config info */
-        for (i = 0; i < numConfigs; i++) {
-            pNewVisualConfigs[i] = visualConfigs[i];
-            pNewVisualPriv[i] = visualPrivates[i];
-        }
-    }
-
-    /* Count the number of RGB and CI visual configs */
-    numRGBconfigs = 0;
-    numCIconfigs = 0;
-    for (i = 0; i < numNewConfigs; i++) {
-        if (pNewVisualConfigs[i].rgba)
-            numRGBconfigs++;
-        else
-            numCIconfigs++;
-    }
-
-    /* Count the total number of visuals to compute */
-    numNewVisuals = 0;
-    for (i = 0; i < numVisuals; i++) {
-        int count;
-
-        count = ((pVisual[i].class == TrueColor ||
-                  pVisual[i].class == DirectColor)
-                ? numRGBconfigs : numCIconfigs);
-        if (count == 0)
-            count = 1;          /* preserve the existing visual */
-
-        numNewVisuals += count;
-    }
-
-    /* Reset variables for use with the next screen/driver's visual configs */
-    visualConfigs = NULL;
-    numConfigs = 0;
-
-    /* Alloc temp space for the list of orig VisualIDs for each new visual */
-    orig_vid = (VisualID *)malloc(numNewVisuals * sizeof(VisualID));
-    if (!orig_vid) {
-        free(pNewVisualPriv);
-        free(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Alloc space for the list of glXVisuals */
-    modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
-    if (modes == NULL) {
-        free(orig_vid);
-        free(pNewVisualPriv);
-        free(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Alloc space for the list of glXVisualPrivates */
-    glXVisualPriv = (void **)malloc(numNewVisuals * sizeof(void *));
-    if (!glXVisualPriv) {
-        _gl_context_modes_destroy( modes );
-        free(orig_vid);
-        free(pNewVisualPriv);
-        free(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Alloc space for the new list of the X server's visuals */
-    pVisualNew = (VisualPtr)malloc(numNewVisuals * sizeof(VisualRec));
-    if (!pVisualNew) {
-        free(glXVisualPriv);
-        _gl_context_modes_destroy( modes );
-        free(orig_vid);
-        free(pNewVisualPriv);
-        free(pNewVisualConfigs);
-        return FALSE;
-    }
-
-    /* Initialize the new visuals */
-    found_default = FALSE;
-    glAquaScreens[screenInfo.numScreens-1].modes = modes;
-    for (i = j = 0; i < numVisuals; i++) {
-        int is_rgb = (pVisual[i].class == TrueColor ||
-                      pVisual[i].class == DirectColor);
-
-        if (!is_rgb)
-        {
-            /* We don't support non-rgb visuals for GL. But we don't
-               want to remove them either, so just pass them through
-               with null glX configs */
-
-            pVisualNew[j] = pVisual[i];
-            pVisualNew[j].vid = FakeClientID(0);
-
-            /* Check for the default visual */
-            if (!found_default && pVisual[i].vid == *defaultVisp) {
-                *defaultVisp = pVisualNew[j].vid;
-                found_default = TRUE;
-            }
-
-            /* Save the old VisualID */
-            orig_vid[j] = pVisual[i].vid;
-
-            /* Initialize the glXVisual */
-            _gl_copy_visual_to_context_mode( modes, & NullConfig );
-            modes->visualID = pVisualNew[j].vid;
-
-            j++;
-
-            continue;
-        }
-
-        for (k = 0; k < numNewConfigs; k++) {
-            if (pNewVisualConfigs[k].rgba != is_rgb)
-                continue;
-
-            assert( modes != NULL );
-
-            /* Initialize the new visual */
-            pVisualNew[j] = pVisual[i];
-            pVisualNew[j].vid = FakeClientID(0);
-
-            /* Check for the default visual */
-            if (!found_default && pVisual[i].vid == *defaultVisp) {
-                *defaultVisp = pVisualNew[j].vid;
-                found_default = TRUE;
-            }
-
-            /* Save the old VisualID */
-            orig_vid[j] = pVisual[i].vid;
-
-            /* Initialize the glXVisual */
-            _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
-            modes->visualID = pVisualNew[j].vid;
-
-            /*
-             * If the class is -1, then assume the X visual information
-             * is identical to what GLX needs, and take them from the X
-             * visual.  NOTE: if class != -1, then all other fields MUST
-             * be initialized.
-             */
-            if (modes->visualType == GLX_NONE) {
-                modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
-                modes->redBits    = count_bits(pVisual[i].redMask);
-                modes->greenBits  = count_bits(pVisual[i].greenMask);
-                modes->blueBits   = count_bits(pVisual[i].blueMask);
-                modes->alphaBits  = modes->alphaBits;
-                modes->redMask    = pVisual[i].redMask;
-                modes->greenMask  = pVisual[i].greenMask;
-                modes->blueMask   = pVisual[i].blueMask;
-                modes->alphaMask  = modes->alphaMask;
-                modes->rgbBits = (is_rgb)
-                    ? (modes->redBits + modes->greenBits +
-                       modes->blueBits + modes->alphaBits)
-                    : rootDepth;
-            }
-
-            /* Save the device-dependent private for this visual */
-            glXVisualPriv[j] = pNewVisualPriv[k];
-
-            j++;
-            modes = modes->next;
-        }
-    }
-
-    assert(j <= numNewVisuals);
-
-    /* Save the GLX visuals in the screen structure */
-    glAquaScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
-    //    glAquaScreens[screenInfo.numScreens-1].priv = glXVisualPriv;
-
-    /* set up depth's VisualIDs */
-    for (i = 0; i < ndepth; i++) {
-        int numVids = 0;
-        VisualID *pVids = NULL;
-        int k, n = 0;
-
-        /* Count the new number of VisualIDs at this depth */
-        for (j = 0; j < pdepth[i].numVids; j++)
-            for (k = 0; k < numNewVisuals; k++)
-            if (pdepth[i].vids[j] == orig_vid[k])
-                numVids++;
-
-        /* Allocate a new list of VisualIDs for this depth */
-        pVids = (VisualID *)malloc(numVids * sizeof(VisualID));
-
-        /* Initialize the new list of VisualIDs for this depth */
-        for (j = 0; j < pdepth[i].numVids; j++)
-            for (k = 0; k < numNewVisuals; k++)
-            if (pdepth[i].vids[j] == orig_vid[k])
-                pVids[n++] = pVisualNew[k].vid;
-
-        /* Update this depth's list of VisualIDs */
-        free(pdepth[i].vids);
-        pdepth[i].vids = pVids;
-        pdepth[i].numVids = numVids;
-    }
-
-    /* Update the X server's visuals */
-    *nvisualp = numNewVisuals;
-    *visualp = pVisualNew;
-
-    /* Free the old list of the X server's visuals */
-    free(pVisual);
-
-    /* Clean up temporary allocations */
-    free(orig_vid);
-    free(pNewVisualPriv);
-    free(pNewVisualConfigs);
-
-    /* Free the private list created by DDX HW driver */
-    if (visualPrivates)
-        free(visualPrivates);
-    visualPrivates = NULL;
-
-    return TRUE;
-#endif
-    return FALSE;
-}
-
-static void glAquaSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
-                                   void **privates)
-{
-#if 0
-    GLAQUA_DEBUG_MSG("glAquaSetVisualConfigs\n");
-
-    numConfigs = nconfigs;
-    visualConfigs = configs;
-    visualPrivates = privates;
-#endif
-}
-
-
-static Bool glAquaInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
-                              int *nvisualp, int *ndepthp,
-                              int *rootDepthp, VisualID *defaultVisp,
-                              unsigned long sizes, int bitsPerRGB)
-{
-    GLAQUA_DEBUG_MSG("glAquaInitVisuals\n");
-    
-    /*
-     * setup the visuals supported by this particular screen.
-     */
-    return init_visuals(nvisualp, visualp, defaultVisp,
-                        *ndepthp, *depthp, *rootDepthp);
-}
-
-#if 0
-static void fixup_visuals(int screen)
-{
-    ScreenPtr pScreen = screenInfo.screens[screen];
-    glAquaScreenRec *pScr = &glAquaScreens[screen];
-    int j;
-    __GLcontextModes *modes;
-
-    GLAQUA_DEBUG_MSG("fixup_visuals\n");
-
-    for ( modes = pScr->modes ; modes != NULL ; modes = modes->next ) {
-        const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
-        const int nplanes = (modes->rgbBits - modes->alphaBits);
-        const VisualPtr pVis = pScreen->visuals;
-
-        /* Find a visual that matches the GLX visual's class and size */
-        for (j = 0; j < pScreen->numVisuals; j++) {
-            if (pVis[j].class == vis_class &&
-            pVis[j].nplanes == nplanes) {
-
-            /* Fixup the masks */
-            modes->redMask   = pVis[j].redMask;
-            modes->greenMask = pVis[j].greenMask;
-            modes->blueMask  = pVis[j].blueMask;
-
-            /* Recalc the sizes */
-            modes->redBits   = count_bits(modes->redMask);
-            modes->greenBits = count_bits(modes->greenMask);
-            modes->blueBits  = count_bits(modes->blueMask);
-            }
-        }
-    }
-}
-#endif
 static void __glXAquaScreenDestroy(__GLXscreen *screen) {
 
     GLAQUA_DEBUG_MSG("glXAquaScreenDestroy(%p)\n", screen);
@@ -1143,21 +648,37 @@ static __GLXconfig *CreateConfigs(int *numConfigsPtr, int screenNumber) {
 					    c->samples = conf->multisample_samples;
 					}
 
+					/* 
+					 * The Apple libGL supports GLXPixmaps and 
+					 * GLXPbuffers in direct mode.
+					 */
 					/* SGIX_fbconfig / GLX 1.3 */
-					c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
+					c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT
+					    | GLX_PBUFFER_BIT;
 					c->renderType = GLX_RGBA_BIT;
 					c->xRenderable = GL_TRUE;
 					c->fbconfigID = -1;
 					
-					/*TODO add querying code to capabilities.c for the Pbuffer maximums.
-					 *I'm not sure we can even use CGL for Pbuffers yet...
-					 */
 					/* SGIX_pbuffer / GLX 1.3 */
-					c->maxPbufferWidth = 0;
-					c->maxPbufferHeight = 0;
-					c->maxPbufferPixels = 0;
+					
+					/* 
+					 * The CGL layer provides a way of retrieving
+					 * the maximum pbuffer width/height, but only
+					 * if we create a context and call glGetIntegerv.
+					 * 
+					 * The following values are from a test program
+					 * that does so.
+					 */
+					c->maxPbufferWidth = 8192;
+					c->maxPbufferHeight = 8192;
+					c->maxPbufferPixels = /*Do we need this?*/ 0;
+					/* 
+					 * There is no introspection for this sort of thing
+					 * with CGL.  What should we do realistically?
+					 */
 					c->optimalPbufferWidth = 0;
 					c->optimalPbufferHeight = 0;
+					
 					c->visualSelectGroup = 0;
 					
 					c->swapMethod = GLX_SWAP_UNDEFINED_OML;
@@ -1203,7 +724,8 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) {
     if (pScreen == NULL) 
 	return NULL;
 
-    screen = xalloc(sizeof *screen);
+    screen = xcalloc(1, sizeof *screen);
+
     if(NULL == screen)
 	return NULL;
     
@@ -1218,17 +740,13 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) {
     screen->base.fbconfigs = CreateConfigs(&screen->base.numFBConfigs, 
 					   pScreen->myNum);
     
-    /* This seems odd, but visuals is a __GLXconfig too. */
-    screen->base.visuals = screen->base.fbconfigs;
-    screen->base.numVisuals = screen->base.numFBConfigs;
- 
-    GlxSetVisualConfig(GLX_ALL_VISUALS);
+    /* This is set by __glXScreenInit: */
+    screen->base.visuals = NULL;
+    /* This is to be initialized prior to the call to __glXScreenInit: */
+    screen->base.numVisuals = 0;
 
     __glXScreenInit(&screen->base, pScreen);
 
-    /* __glXScreenInit initializes these, so the order here is important, if we need these... */
-    //  screen->base.GLextensions = "";
-    // screen->base.GLXvendor = "Apple";
     screen->base.GLXversion = xstrdup("1.4");
     screen->base.GLXextensions = xstrdup("GLX_SGIX_fbconfig "
 					 "GLX_SGIS_multisample "
@@ -1279,8 +797,6 @@ __glXAquaScreenCreateDrawable(__GLXscreen *screen,
 			      __GLXconfig *conf) {
   __GLXAquaDrawable *glxPriv;
 
-  GLAQUA_DEBUG_MSG("glAquaScreenCreateDrawable(%p,%p,%d,%p)\n", context, pDraw, drawId, modes);
-
   glxPriv = xalloc(sizeof *glxPriv);
 
   if(glxPriv == NULL)
@@ -1294,19 +810,16 @@ __glXAquaScreenCreateDrawable(__GLXscreen *screen,
   }
 
   glxPriv->base.destroy       = __glXAquaDrawableDestroy;
-  glxPriv->base.resize        = __glXAquaDrawableResize;
   glxPriv->base.swapBuffers   = __glXAquaDrawableSwapBuffers;
   glxPriv->base.copySubBuffer = NULL; /* __glXAquaDrawableCopySubBuffer; */
 
+  glxPriv->pDraw = pDraw;
+  glxPriv->sid = 0;
+  glxPriv->context = NULL;
+  
   return &glxPriv->base;
 }
 
-static void glAquaResetExtension(void)
-{
-    GLAQUA_DEBUG_MSG("glAquaResetExtension\n");
-    CGLSetOption(kCGLGOResetLibrary, GL_TRUE);
-}
-
 // Extra goodies for glx
 
 GLuint __glFloorLog2(GLuint val)
diff --git a/hw/xquartz/xpr/Makefile.am b/hw/xquartz/xpr/Makefile.am
index e74580f..ba7b258 100644
--- a/hw/xquartz/xpr/Makefile.am
+++ b/hw/xquartz/xpr/Makefile.am
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
 libXquartzXpr_la_SOURCES = \
 	appledri.c \
 	dri.c \
+	driWrap.c \
 	xprAppleWM.c \
 	xprCursor.c \
 	xprEvent.c \
@@ -20,6 +21,7 @@ libXquartzXpr_la_SOURCES = \
 
 EXTRA_DIST = \
 	dri.h \
+	driWrap.h \
 	dristruct.h \
 	appledri.h \
 	appledristr.h \
diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c
index 3667c0d..7873bf2 100644
--- a/hw/xquartz/xpr/appledri.c
+++ b/hw/xquartz/xpr/appledri.c
@@ -2,7 +2,7 @@
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2002, 2009 Apple Computer, Inc.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -64,6 +64,7 @@ static DISPATCH_PROC(ProcAppleDRIDispatch);
 static DISPATCH_PROC(SProcAppleDRIDispatch);
 
 static void AppleDRIResetProc(ExtensionEntry* extEntry);
+static int ProcAppleDRICreatePixmap(ClientPtr client);
 
 static unsigned char DRIReqCode = 0;
 static int DRIEventBase = 0;
@@ -274,6 +275,76 @@ ProcAppleDRIDestroySurface(
     return (client->noClientException);
 }
 
+static int
+ProcAppleDRICreatePixmap(ClientPtr client)
+{
+    REQUEST(xAppleDRICreatePixmapReq);
+    DrawablePtr pDrawable;
+    int rc;
+    char path[PATH_MAX];
+    xAppleDRICreatePixmapReply rep;
+    int width, height, pitch, bpp;
+    void *ptr;
+
+    REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
+
+    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+                           DixReadAccess);
+
+    if(rc != Success)
+        return rc;
+    
+    if(!DRICreatePixmap(screenInfo.screens[stuff->screen],
+                              (Drawable)stuff->drawable,
+                              pDrawable,
+			      path, PATH_MAX)) {
+        return BadValue;
+    }
+
+    if(!DRIGetPixmapData(pDrawable, &width, &height,
+			 &pitch, &bpp, &ptr)) {
+	return BadValue;
+    } 
+	
+    rep.stringLength = strlen(path) + 1;
+		
+    /* No need for swapping, because this only runs if LocalClient is true. */
+    rep.type = X_Reply;
+    rep.length = sizeof(rep) + rep.stringLength;
+    rep.sequenceNumber = client->sequence;
+    rep.width = width;
+    rep.height = height;
+    rep.pitch = pitch;
+    rep.bpp = bpp;
+    rep.size = pitch * height;
+
+    if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
+	ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); 
+    
+    WriteReplyToClient(client, sizeof(rep), &rep);
+    (void)WriteToClient(client, rep.stringLength, path);
+
+    return (client->noClientException);
+}
+
+static int
+ProcAppleDRIDestroyPixmap(ClientPtr client)
+{
+    DrawablePtr pDrawable;
+    int rc;
+    REQUEST(xAppleDRIDestroyPixmapReq);
+    REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
+
+    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+			    DixReadAccess);
+
+    if(rc != Success)
+	return rc;
+    
+    DRIDestroyPixmap(pDrawable);
+
+    return (client->noClientException);
+}
 
 /* dispatch */
 
@@ -303,6 +374,11 @@ ProcAppleDRIDispatch (
         return ProcAppleDRICreateSurface(client);
     case X_AppleDRIDestroySurface:
         return ProcAppleDRIDestroySurface(client);
+    case X_AppleDRICreatePixmap:
+	return ProcAppleDRICreatePixmap(client);
+    case X_AppleDRIDestroyPixmap:
+	return ProcAppleDRIDestroyPixmap(client);
+
     default:
         return BadRequest;
     }
diff --git a/hw/xquartz/xpr/appledri.h b/hw/xquartz/xpr/appledri.h
index c4e43be..36964c6 100644
--- a/hw/xquartz/xpr/appledri.h
+++ b/hw/xquartz/xpr/appledri.h
@@ -1,8 +1,9 @@
+/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.7 2000/12/07 20:26:02 dawes Exp $ */
 /**************************************************************************
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2002, 2008, 2009 Apple Computer, Inc.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -45,6 +46,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define X_AppleDRICreateSurface			2
 #define X_AppleDRIDestroySurface		3
 #define X_AppleDRIAuthConnection                4
+#define X_AppleDRICreateSharedBuffer            5
+#define X_AppleDRISwapBuffers                   6
+#define X_AppleDRICreatePixmap                  7
+#define X_AppleDRIDestroyPixmap                 8
+
 /* Requests up to and including 18 were used in a previous version */
 
 /* Events */
@@ -99,8 +105,19 @@ Bool XAppleDRIDestroySurface (Display *dpy, int screen, Drawable drawable);
 
 Bool XAppleDRISynchronizeSurfaces (Display *dpy);
 
+Bool XAppleDRICreateSharedBuffer(Display *dpy, int screen, Drawable drawable,
+				 Bool doubleSwap, char *path, size_t pathlen,
+				 int *width, int *height);
+
+Bool XAppleDRISwapBuffers(Display *dpy, int screen, Drawable drawable);
+
+Bool XAppleDRICreatePixmap(Display *dpy, int screen, Drawable drawable,
+			   int *width, int *height, int *pitch, int *bpp,
+			   size_t *size, char *bufname, size_t bufnamesize);
+
+Bool XAppleDRIDestroyPixmap(Display *dpy, Pixmap pixmap);
+
 _XFUNCPROTOEND
 
 #endif /* _APPLEDRI_SERVER_ */
 #endif /* _APPLEDRI_H_ */
-
diff --git a/hw/xquartz/xpr/appledristr.h b/hw/xquartz/xpr/appledristr.h
index c6ad17b..a3844f0 100644
--- a/hw/xquartz/xpr/appledristr.h
+++ b/hw/xquartz/xpr/appledristr.h
@@ -2,7 +2,7 @@
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2002, 2008, 2009 Apple Computer, Inc.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -153,13 +153,85 @@ typedef struct _AppleDRINotify {
 	BYTE	type;		/* always eventBase + event type */
 	BYTE	kind;
 	CARD16	sequenceNumber B16;
-	Time	time B32;	/* time of change */
+	CARD32	time B32;	/* time of change */
 	CARD32	pad1 B32;
 	CARD32	arg B32;
 	CARD32	pad3 B32;
 } xAppleDRINotifyEvent;
 #define sz_xAppleDRINotifyEvent	20
 
+
+typedef struct {
+    CARD8 reqType;
+    CARD8 driReqType;
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+    BOOL doubleSwap;
+    CARD8 pad1, pad2, pad3;
+} xAppleDRICreateSharedBufferReq;
+
+#define sz_xAppleDRICreateSharedBufferReq 16
+
+typedef struct {
+    BYTE type;
+    BYTE data1;
+    CARD16 sequenceNumber B16;
+    CARD32 length B32;
+    CARD32 stringLength B32; /* 0 on error */
+    CARD32 width B32;
+    CARD32 height B32;
+    CARD32 pad1 B32;
+    CARD32 pad2 B32;
+    CARD32 pad3 B32;
+} xAppleDRICreateSharedBufferReply;
+
+#define sz_xAppleDRICreateSharedBufferReply 32
+
+typedef struct {
+    CARD8 reqType;
+    CARD8 driReqType;
+    CARD16 length B16;
+    CARD32 screen B32;
+    CARD32 drawable B32;
+} xAppleDRISwapBuffersReq;
+
+#define sz_xAppleDRISwapBuffersReq 12
+
+typedef struct {
+    CARD8 reqType; /*1*/
+    CARD8 driReqType; /*2*/
+    CARD16 length B16; /*4*/
+    CARD32 screen B32; /*8*/
+    CARD32 drawable B32; /*12*/
+} xAppleDRICreatePixmapReq;
+
+#define sz_xAppleDRICreatePixmapReq 12
+
+typedef struct {
+    BYTE type; /*1*/
+    BOOL pad1; /*2*/
+    CARD16 sequenceNumber B16; /*4*/
+    CARD32 length B32; /*8*/
+    CARD32 width B32; /*12*/
+    CARD32 height B32; /*16*/
+    CARD32 pitch B32; /*20*/
+    CARD32 bpp B32; /*24*/
+    CARD32 size B32; /*28*/
+    CARD32 stringLength B32; /*32*/
+} xAppleDRICreatePixmapReply;
+
+#define sz_xAppleDRICreatePixmapReply 32
+
+typedef struct {
+    CARD8 reqType; /*1*/
+    CARD8 driReqType; /*2*/
+    CARD16 length B16; /*4*/
+    CARD32 drawable B32; /*8*/
+} xAppleDRIDestroyPixmapReq;
+
+#define sz_xAppleDRIDestroyPixmapReq 8
+
 #ifdef _APPLEDRI_SERVER_
 
 void AppleDRISendEvent (
diff --git a/hw/xquartz/xpr/dri.c b/hw/xquartz/xpr/dri.c
index 591568e..3a758e5 100644
--- a/hw/xquartz/xpr/dri.c
+++ b/hw/xquartz/xpr/dri.c
@@ -2,7 +2,7 @@
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
 Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2002, 2009 Apple Computer, Inc.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -50,6 +50,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NEED_EVENTS
 #include <X11/X.h>
 #include <X11/Xproto.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include "misc.h"
 #include "dixstruct.h"
 #include "extnsionst.h"
@@ -68,17 +72,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "rootless.h"
 #include "x-hash.h"
 #include "x-hook.h"
+#include "driWrap.h"
 
 #include <AvailabilityMacros.h>
 
-static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKey;
-static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKey;
-static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKey;
+static int DRIScreenPrivKeyIndex;
+static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex;
+static int DRIWindowPrivKeyIndex;
+static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex;
+static int DRIPixmapPrivKeyIndex;
+static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKeyIndex;
+static int DRIPixmapBufferPrivKeyIndex;
+static DevPrivateKey DRIPixmapBufferPrivKey = &DRIPixmapBufferPrivKeyIndex;
 
 static RESTYPE DRIDrawablePrivResType;
 
 static x_hash_table *surface_hash;      /* maps surface ids -> drawablePrivs */
 
+static Bool DRIFreePixmapImp(DrawablePtr pDrawable);
+
 /* FIXME: don't hardcode this? */
 #define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist"
 
@@ -87,6 +99,18 @@ static x_hash_table *surface_hash;      /* maps surface ids -> drawablePrivs */
 #define CG_REQUIRED_MINOR 157
 #define CG_REQUIRED_MICRO 11
 
+typedef struct {
+    DrawablePtr pDrawable;
+    int refCount;
+    int bytesPerPixel;
+    int width;
+    int height;
+    char shmPath[PATH_MAX];
+    int fd; /* From shm_open (for now) */
+    size_t length; /* length of buffer */
+    void *buffer;       
+} DRIPixmapBuffer, *DRIPixmapBufferPtr;
+
 /* Returns version as major.minor.micro in 10.10.10 fixed form */
 static unsigned int
 get_cg_version (void)
@@ -238,7 +262,7 @@ DRIFinishScreenInit(ScreenPtr pScreen)
 
     //    ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
 
-    return TRUE;
+    return DRIWrapInit(pScreen);
 }
 
 void
@@ -343,6 +367,112 @@ DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
     xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
 }
 
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
+    DRIDrawablePrivPtr pDRIDrawablePriv;
+    xp_window_id wid = 0;
+
+    *widPtr = 0;
+
+    pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+    if (pDRIDrawablePriv == NULL) {
+	xp_error err;
+	xp_window_changes wc;
+	
+	/* allocate a DRI Window Private record */
+	if (!(pDRIDrawablePriv = xalloc(sizeof(*pDRIDrawablePriv)))) {
+	    return NULL;
+	}
+	
+	pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
+	pDRIDrawablePriv->pScreen = pScreen;
+	pDRIDrawablePriv->refCount = 0;
+	pDRIDrawablePriv->drawableIndex = -1;
+	pDRIDrawablePriv->notifiers = NULL;
+	
+	/* find the physical window */
+	wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
+
+	if (wid == 0) {
+	    xfree(pDRIDrawablePriv);
+	    return NULL;
+	}
+	
+	/* allocate the physical surface */
+	err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
+
+	if (err != Success) {
+	    xfree(pDRIDrawablePriv);
+	    return NULL;
+	}
+
+	/* Make it visible */
+	wc.stack_mode = XP_MAPPED_ABOVE;
+	wc.sibling = 0;
+	err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
+
+	if (err != Success) {
+	    xp_destroy_surface(pDRIDrawablePriv->sid);
+	    xfree(pDRIDrawablePriv);
+	    return NULL;
+	}
+
+	/* save private off of preallocated index */
+	dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
+		      pDRIDrawablePriv);
+    }
+
+    *widPtr = wid;
+
+    return pDRIDrawablePriv;
+}
+
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
+    DRIDrawablePrivPtr pDRIDrawablePriv;
+     
+    pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
+
+    if (pDRIDrawablePriv == NULL) {
+	xp_error err;
+
+	/* allocate a DRI Window Private record */
+	if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) {
+	    return NULL;
+	}
+	
+	pDRIDrawablePriv->pDraw = (DrawablePtr)pPix;
+	pDRIDrawablePriv->pScreen = pScreen;
+	pDRIDrawablePriv->refCount = 0;
+	pDRIDrawablePriv->drawableIndex = -1;
+	pDRIDrawablePriv->notifiers = NULL;
+	
+	/* Passing a null window id to Xplugin in 10.3+ asks for
+	   an accelerated offscreen surface. */
+	
+	err = xp_create_surface(0, &pDRIDrawablePriv->sid);
+	if (err != Success) {
+	    xfree(pDRIDrawablePriv);
+	    return NULL;
+	}
+
+	/* 
+	 * The DRIUpdateSurface will be called to resize the surface
+	 * after this function, if the export is successful.
+	 */
+
+	/* save private off of preallocated index */
+	dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
+		      pDRIDrawablePriv);
+    }
+    
+    return pDRIDrawablePriv;
+}
+
+
 Bool
 DRICreateSurface(ScreenPtr pScreen, Drawable id,
                  DrawablePtr pDrawable, xp_client_id client_id,
@@ -350,112 +480,62 @@ DRICreateSurface(ScreenPtr pScreen, Drawable id,
                  void (*notify) (void *arg, void *data), void *notify_data)
 {
     DRIScreenPrivPtr    pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-    DRIDrawablePrivPtr  pDRIDrawablePriv;
     xp_window_id        wid = 0;
+    DRIDrawablePrivPtr  pDRIDrawablePriv;
 
     if (pDrawable->type == DRAWABLE_WINDOW) {
-        WindowPtr pWin = (WindowPtr)pDrawable;
-
-        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-        if (pDRIDrawablePriv == NULL) {
-            xp_error err;
-            xp_window_changes wc;
-
-            /* allocate a DRI Window Private record */
-            if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
-                return FALSE;
-            }
-
-            pDRIDrawablePriv->pDraw = pDrawable;
-            pDRIDrawablePriv->pScreen = pScreen;
-            pDRIDrawablePriv->refCount = 0;
-            pDRIDrawablePriv->drawableIndex = -1;
-            pDRIDrawablePriv->notifiers = NULL;
+	pDRIDrawablePriv = CreateSurfaceForWindow(pScreen, 
+						  (WindowPtr)pDrawable, &wid);
 
-            /* find the physical window */
-            wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
-            if (wid == 0) {
-                xfree(pDRIDrawablePriv);
-                return FALSE;
-            }
-
-            /* allocate the physical surface */
-            err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
-            if (err != Success) {
-                xfree(pDRIDrawablePriv);
-                return FALSE;
-            }
-
-            /* Make it visible */
-            wc.stack_mode = XP_MAPPED_ABOVE;
-            wc.sibling = 0;
-            err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
-            if (err != Success)
-            {
-                xp_destroy_surface(pDRIDrawablePriv->sid);
-                xfree(pDRIDrawablePriv);
-                return FALSE;
-            }
-
-            /* save private off of preallocated index */
-	    dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
-			  pDRIDrawablePriv);
-        }
+	if(NULL == pDRIDrawablePriv)
+	    return FALSE; /*error*/
     }
-
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
     else if (pDrawable->type == DRAWABLE_PIXMAP) {
-        PixmapPtr pPix = (PixmapPtr)pDrawable;
-
-        pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
-        if (pDRIDrawablePriv == NULL) {
-            xp_error err;
-
-            /* allocate a DRI Window Private record */
-            if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) {
-                return FALSE;
-            }
-
-            pDRIDrawablePriv->pDraw = pDrawable;
-            pDRIDrawablePriv->pScreen = pScreen;
-            pDRIDrawablePriv->refCount = 0;
-            pDRIDrawablePriv->drawableIndex = -1;
-            pDRIDrawablePriv->notifiers = NULL;
-
-            /* Passing a null window id to Xplugin in 10.3+ asks for
-               an accelerated offscreen surface. */
+	pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen, 
+						  (PixmapPtr)pDrawable);
 
-            err = xp_create_surface(0, &pDRIDrawablePriv->sid);
-            if (err != Success) {
-                xfree(pDRIDrawablePriv);
-                return FALSE;
-            }
-
-            /* save private off of preallocated index */
-	    dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
-			  pDRIDrawablePriv);
-        }
+	if(NULL == pDRIDrawablePriv)
+	    return FALSE; /*error*/
     }
 #endif
-
     else { /* for GLX 1.3, a PBuffer */
         /* NOT_DONE */
         return FALSE;
     }
-
+    
+    
     /* Finish initialization of new surfaces */
     if (pDRIDrawablePriv->refCount == 0) {
         unsigned int key[2] = {0};
         xp_error err;
 
         /* try to give the client access to the surface */
-        if (client_id != 0 && wid != 0)
-        {
+        if (client_id != 0) {
+	    /*
+	     * Xplugin accepts a 0 wid if the surface id is offscreen, such 
+	     * as for a pixmap.
+	     */
             err = xp_export_surface(wid, pDRIDrawablePriv->sid,
                                     client_id, key);
             if (err != Success) {
                 xp_destroy_surface(pDRIDrawablePriv->sid);
                 xfree(pDRIDrawablePriv);
+		
+		/* 
+		 * Now set the dix privates to NULL that were previously set.
+		 * This prevents reusing an invalid pointer.
+		 */
+		if(pDrawable->type == DRAWABLE_WINDOW) {
+		    WindowPtr pWin = (WindowPtr)pDrawable;
+		    
+		    dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+		} else if(pDrawable->type == DRAWABLE_PIXMAP) {
+		    PixmapPtr pPix = (PixmapPtr)pDrawable;
+		    
+		    dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+		}
+		
                 return FALSE;
             }
         }
@@ -541,8 +621,9 @@ DRIDrawablePrivDelete(pointer pResource, XID id)
         pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
     }
 
-    if (pDRIDrawablePriv == NULL)
-        return FALSE;
+    if (pDRIDrawablePriv == NULL) {
+	return DRIFreePixmapImp(pDrawable);
+    }
 
     if (pDRIDrawablePriv->drawableIndex != -1) {
         /* release drawable table entry */
@@ -735,3 +816,139 @@ DRISurfaceNotify(xp_surface_id id, int kind)
                            DRIDrawablePrivResType, FALSE);
     }
 }
+
+Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id,
+		     DrawablePtr pDrawable, char *path,
+		     size_t pathmax) 
+{
+    DRIPixmapBufferPtr shared;
+    PixmapPtr pPix;
+    
+    if(pDrawable->type != DRAWABLE_PIXMAP)
+	return FALSE;
+
+    pPix = (PixmapPtr)pDrawable;
+
+    shared = xalloc(sizeof(*shared));
+    if(NULL == shared) {
+        FatalError("failed to allocate DRIPixmapBuffer in %s\n", __func__);
+    }
+        
+    shared->pDrawable = pDrawable;
+    shared->refCount = 1;
+
+    if(pDrawable->bitsPerPixel >= 24) {
+	shared->bytesPerPixel = 4;
+    } else if(pDrawable->bitsPerPixel <= 16) {
+	shared->bytesPerPixel = 2;
+    }
+    
+    shared->width = pDrawable->width;
+    shared->height = pDrawable->height;
+    
+    if(-1 == snprintf(shared->shmPath, sizeof(shared->shmPath),
+                      "%d_0x%lx", getpid(),
+                      (unsigned long)id)) {
+        FatalError("buffer overflow in %s\n", __func__);
+    }
+    
+    shared->fd = shm_open(shared->shmPath, 
+                          O_RDWR | O_EXCL | O_CREAT, 
+                          S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
+    
+    if(-1 == shared->fd) {
+	xfree(shared);
+        return FALSE;
+    }   
+    
+    shared->length = shared->width * shared->height * shared->bytesPerPixel;
+    
+    if(-1 == ftruncate(shared->fd, shared->length)) {
+	ErrorF("failed to ftruncate (extend) file.");
+	shm_unlink(shared->shmPath);
+	close(shared->fd);
+	xfree(shared);
+	return FALSE;
+    }
+
+    shared->buffer = mmap(NULL, shared->length,
+                          PROT_READ | PROT_WRITE,
+                          MAP_FILE | MAP_SHARED, shared->fd, 0);
+    
+    if(MAP_FAILED == shared->buffer) {
+	ErrorF("failed to mmap shared memory.");
+	shm_unlink(shared->shmPath);
+	close(shared->fd);
+	xfree(shared);
+	return FALSE;
+    }
+    
+    strncpy(path, shared->shmPath, pathmax);
+    path[pathmax - 1] = '\0';
+    
+    dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared);
+
+    AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+
+    return TRUE;
+}
+
+
+Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height,
+		      int *pitch, int *bpp, void **ptr) {
+    PixmapPtr pPix;
+    DRIPixmapBufferPtr shared;
+
+    if(pDrawable->type != DRAWABLE_PIXMAP)
+	return FALSE;
+
+    pPix = (PixmapPtr)pDrawable;
+
+    shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+    if(NULL == shared)
+	return FALSE;
+
+    assert(pDrawable->width == shared->width);
+    assert(pDrawable->height == shared->height);
+    
+    *width = shared->width;
+    *height = shared->height;
+    *bpp = shared->bytesPerPixel;
+    *pitch = shared->width * shared->bytesPerPixel;
+    *ptr = shared->buffer;    
+
+    return TRUE;
+}
+
+static Bool
+DRIFreePixmapImp(DrawablePtr pDrawable) {
+    DRIPixmapBufferPtr shared;
+    PixmapPtr pPix;
+
+    if(pDrawable->type != DRAWABLE_PIXMAP)
+	return FALSE;
+
+    pPix = (PixmapPtr)pDrawable;
+
+    shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+    if(NULL == shared)
+	return FALSE;
+
+    close(shared->fd);
+    munmap(shared->buffer, shared->length);
+    shm_unlink(shared->shmPath);
+    xfree(shared);
+
+    dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL);
+
+    return TRUE;
+}
+
+void 
+DRIDestroyPixmap(DrawablePtr pDrawable) {
+    if(DRIFreePixmapImp(pDrawable))
+	FreeResourceByType(pDrawable->id, DRIDrawablePrivResType, FALSE);
+
+}
diff --git a/hw/xquartz/xpr/dri.h b/hw/xquartz/xpr/dri.h
index 8bb2e9e..48fea36 100644
--- a/hw/xquartz/xpr/dri.h
+++ b/hw/xquartz/xpr/dri.h
@@ -1,7 +1,7 @@
 /**************************************************************************
 
 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2002, 2009 Apple Computer, Inc.
 All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
@@ -125,4 +125,14 @@ extern void DRIQueryVersion(int *majorVersion,
                             int *minorVersion,
                             int *patchVersion);
 
+extern Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id,
+			    DrawablePtr pDrawable, char *path,
+			    size_t pathmax);
+
+extern Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height,
+			     int *pitch, int *bpp, void **ptr);
+
+
+extern void DRIDestroyPixmap(DrawablePtr pDrawable);
+
 #endif
diff --git a/hw/xquartz/xpr/driWrap.c b/hw/xquartz/xpr/driWrap.c
new file mode 100644
index 0000000..8c57fd4
--- /dev/null
+++ b/hw/xquartz/xpr/driWrap.c
@@ -0,0 +1,547 @@
+/*
+Copyright (c) 2009 Apple Computer, Inc.
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stddef.h>
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "dixfontstr.h"
+#include "mivalidate.h"
+#include "driWrap.h"
+#include "dri.h"
+
+#include <OpenGL/OpenGL.h>
+
+typedef struct {
+    GCOps *originalOps;
+    GCOps *driOps;
+} DRIGCRec;
+
+typedef struct {
+    GCOps *originalOps;
+    CreateGCProcPtr CreateGC;
+} DRIWrapScreenRec;
+
+typedef struct {
+    Bool didSave;
+    int devKind;
+    DevUnion devPrivate;
+} DRISavedDrawableState;
+
+static int driGCKeyIndex;
+static DevPrivateKey driGCKey = &driGCKeyIndex;
+
+static int driWrapScreenKeyIndex;
+static DevPrivateKey driWrapScreenKey = &driWrapScreenKeyIndex;
+
+static GCOps driGCOps;
+
+#define wrap(priv, real, member, func) { \
+	priv->member = real->member; \
+	real->member = func; \
+    }
+
+#define unwrap(priv, real, member) { \
+	real->member = priv->member; \
+    }
+
+static DRIGCRec *
+DRIGetGCPriv(GCPtr pGC) {
+    return dixLookupPrivate(&pGC->devPrivates, driGCKey);
+}
+
+static void
+DRIUnwrapGC(GCPtr pGC) {
+    DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
+
+    pGC->ops = pGCPriv->originalOps;
+}
+
+static void 
+DRIWrapGC(GCPtr pGC) {
+    DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
+    
+    pGC->ops = pGCPriv->driOps;
+}
+
+static void
+DRISurfaceSetDrawable(DrawablePtr pDraw, 
+				  DRISavedDrawableState *saved) {
+    saved->didSave = FALSE;
+    
+    if(pDraw->type == DRAWABLE_PIXMAP) {
+	int pitch, width, height, bpp;
+	void *buffer;
+
+	if(DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp, &buffer)) {
+	    PixmapPtr pPix = (PixmapPtr)pDraw;
+
+	    saved->devKind = pPix->devKind;
+	    saved->devPrivate.ptr = pPix->devPrivate.ptr;
+	    saved->didSave = TRUE;
+
+	    pPix->devKind = pitch;
+	    pPix->devPrivate.ptr = buffer;
+	}
+    }
+}
+
+static void
+DRISurfaceRestoreDrawable(DrawablePtr pDraw,
+				      DRISavedDrawableState *saved) {
+    PixmapPtr pPix = (PixmapPtr)pDraw;
+
+    if(!saved->didSave) 
+	return;
+
+    pPix->devKind = saved->devKind;
+    pPix->devPrivate.ptr = saved->devPrivate.ptr;
+}
+
+static void
+DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
+			 DDXPointPtr pptInit, int *pwidthInit, 
+			 int sorted) {
+    DRISavedDrawableState saved;
+
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
+    
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
+			DDXPointPtr pptInit, int *pwidthInit,
+			int nspans, int sorted) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+    
+    pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted);
+
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPutImage(DrawablePtr dst, GCPtr pGC,
+			int depth, int x, int y, int w, int h,
+			int leftPad, int format, char *pBits) {
+    DRISavedDrawableState saved;
+
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+   
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static RegionPtr
+DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
+			     int srcx, int srcy, int w, int h,
+			     int dstx, int dsty) {
+    RegionPtr pReg;
+    DRISavedDrawableState pSrcSaved, dstSaved;
+    
+    DRISurfaceSetDrawable(pSrc, &pSrcSaved);
+    DRISurfaceSetDrawable(dst, &dstSaved);
+      
+    DRIUnwrapGC(pGC);
+
+    pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
+
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
+    DRISurfaceRestoreDrawable(dst, &dstSaved);     
+
+    return pReg;
+}
+
+static RegionPtr
+DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst,
+			     GCPtr pGC, int srcx, int srcy,
+			     int w, int h, int dstx, int dsty,
+			     unsigned long plane) {
+    RegionPtr pReg;
+    DRISavedDrawableState pSrcSaved, dstSaved;
+
+    DRISurfaceSetDrawable(pSrc, &pSrcSaved);
+    DRISurfaceSetDrawable(dst, &dstSaved);
+
+
+    DRIUnwrapGC(pGC);
+    
+    pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty,
+			       plane);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
+    DRISurfaceRestoreDrawable(dst, &dstSaved);
+
+    return pReg;
+}
+
+static void
+DRIPolyPoint(DrawablePtr dst, GCPtr pGC,
+			 int mode, int npt, DDXPointPtr pptInit) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+    
+    DRIUnwrapGC(pGC);
+    
+    pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
+
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolylines(DrawablePtr dst, GCPtr pGC,
+			 int mode, int npt, DDXPointPtr pptInit) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+	
+    pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
+
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolySegment(DrawablePtr dst, GCPtr pGC,
+			   int nseg, xSegment *pSeg) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyRectangle(DrawablePtr dst, GCPtr pGC,
+                                  int nRects, xRectangle *pRects) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+    
+    DRIUnwrapGC(pGC);
+ 
+    pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
+   
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+static void
+DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) {
+    DRISavedDrawableState saved;
+      
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+    
+    pGC->ops->PolyArc(dst, pGC, narcs, parcs);
+
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIFillPolygon(DrawablePtr dst, GCPtr pGC,
+			   int shape, int mode, int count,
+			   DDXPointPtr pptInit) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+      
+    DRIUnwrapGC(pGC);
+    
+    pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
+
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyFillRect(DrawablePtr dst, GCPtr pGC,
+			    int nRectsInit, xRectangle *pRectsInit) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyFillArc(DrawablePtr dst, GCPtr pGC,
+			   int narcsInit, xArc *parcsInit) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static int
+DRIPolyText8(DrawablePtr dst, GCPtr pGC,
+			int x, int y, int count, char *chars) {
+    int ret;
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+    
+    ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
+    
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+
+    return ret;
+}
+
+static int
+DRIPolyText16(DrawablePtr dst, GCPtr pGC,
+			 int x, int y, int count, unsigned short *chars) {
+    int ret;
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+    
+    ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
+
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+
+    return ret;
+}
+
+static void
+DRIImageText8(DrawablePtr dst, GCPtr pGC,
+			  int x, int y, int count, char *chars) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+    
+    pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
+
+    DRIWrapGC(pGC);
+    
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIImageText16(DrawablePtr dst, GCPtr pGC,
+			   int x, int y, int count, unsigned short *chars) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
+			     int x, int y, unsigned int nglyphInit,
+			     CharInfoPtr *ppciInit, pointer unused) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
+			    int x, int y, unsigned int nglyph,
+			    CharInfoPtr *ppci, pointer pglyphBase) {
+    DRISavedDrawableState saved;
+    
+    DRISurfaceSetDrawable(dst, &saved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
+			  int dx, int dy, int xOrg, int yOrg) {
+    DRISavedDrawableState bitMapSaved, dstSaved;
+        
+    DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved);
+    DRISurfaceSetDrawable(dst, &dstSaved);
+
+    DRIUnwrapGC(pGC);
+
+    pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
+    
+    DRIWrapGC(pGC);
+
+    DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved);
+    DRISurfaceRestoreDrawable(dst, &dstSaved);
+}
+
+
+static GCOps driGCOps = {
+    DRIFillSpans,
+    DRISetSpans,
+    DRIPutImage,
+    DRICopyArea,
+    DRICopyPlane,
+    DRIPolyPoint,
+    DRIPolylines,
+    DRIPolySegment,
+    DRIPolyRectangle,
+    DRIPolyArc,
+    DRIFillPolygon,
+    DRIPolyFillRect,
+    DRIPolyFillArc,
+    DRIPolyText8,
+    DRIPolyText16,
+    DRIImageText8,
+    DRIImageText16,
+    DRIImageGlyphBlt,
+    DRIPolyGlyphBlt,
+    DRIPushPixels
+};
+
+
+static Bool
+DRICreateGC(GCPtr pGC) {
+    ScreenPtr pScreen = pGC->pScreen;
+    DRIWrapScreenRec *pScreenPriv;
+    DRIGCRec *pGCPriv;
+    Bool ret;
+
+    pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey);
+    
+    pGCPriv = DRIGetGCPriv(pGC);
+
+    unwrap(pScreenPriv, pScreen, CreateGC);
+    ret = pScreen->CreateGC(pGC);
+
+    if(ret) {
+	pGCPriv->originalOps = pGC->ops;
+	pGC->ops = &driGCOps;
+	pGCPriv->driOps = &driGCOps;
+    }
+
+    wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC);
+    
+    return ret;
+}
+
+
+/* Return false if an error occurred. */
+Bool 
+DRIWrapInit(ScreenPtr pScreen) {
+    DRIWrapScreenRec *pScreenPriv;
+
+    if(!dixRequestPrivate(driGCKey, sizeof(DRIGCRec)))
+	return FALSE;
+
+    if(!dixRequestPrivate(driWrapScreenKey, sizeof(DRIWrapScreenRec)))
+	return FALSE;
+    
+    pScreenPriv = xalloc(sizeof(*pScreenPriv));
+
+    if(NULL == pScreenPriv)
+	return FALSE;
+
+    pScreenPriv->CreateGC = pScreen->CreateGC;
+    pScreen->CreateGC = DRICreateGC;
+    
+    dixSetPrivate(&pScreen->devPrivates, driWrapScreenKey, pScreenPriv);
+        
+    return TRUE;
+}
diff --git a/hw/xquartz/xpr/driWrap.h b/hw/xquartz/xpr/driWrap.h
new file mode 100644
index 0000000..d31d5dd
--- /dev/null
+++ b/hw/xquartz/xpr/driWrap.h
@@ -0,0 +1,31 @@
+/*
+Copyright (c) 2009 Apple Computer, Inc.
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+*/
+
+#ifndef DRIWRAP_H
+#include "scrnintstr.h"
+
+Bool DRIWrapInit(ScreenPtr pScreen);
+
+#endif /*DRIWRAP_H*/


More information about the xorg-commit mailing list