xserver: Branch 'xorg-server-1.7-apple' - 18 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Sun Sep 27 10:39:15 PDT 2009


Rebased ref, commits from common ancestor:
commit 2fac63d8ddb69da9cc48ab3e5057af3de9084a2d
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sun Sep 27 09:48:43 2009 -0700

    Xi: Make CopyKeyClass X_HIDDEN to avoid ugly ifdef-fu

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f85705d..bfcb481 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -192,9 +192,6 @@ XIGetDevice(xEvent* xE)
  * This code is basically the old SwitchCoreKeyboard.
  */
 
-#ifndef XQUARTZ
-static
-#endif
 void
 CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 {
diff --git a/include/dix.h b/include/dix.h
index 49dfe37..b1edb6c 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -592,6 +592,7 @@ extern Bool IsKeyboardDevice(DeviceIntPtr dev);
 extern Bool IsPointerEvent(InternalEvent *event);
 extern Bool IsMaster(DeviceIntPtr dev);
 
+extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
 extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what);
 extern _X_HIDDEN int CoreKeyboardProc(DeviceIntPtr dev, int what);
 
commit 3b079e074485fd6434ab34cf130b4a2fcc1bfee5
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Sep 26 23:41:45 2009 -0700

    XQuartz: Stop checking version numbers of the bundle because CFBundleGetVersionNumber is gimpish
    (cherry picked from commit 9f5bdd89608ec12012592ff395b82e954fbb4da8)

diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index 7a557bd..fd831a8 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -96,20 +96,6 @@ static void set_x11_path() {
                 exit(3);
             }
 
-            ver = CFBundleGetVersionNumber(bundle);
-            if( !(ver >= 0x02308000 || (ver >= 0x02168000 && ver < 0x02208000))) {
-                CFStringRef versionStr = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
-                const char * versionCStr = "Unknown";
-
-                if(versionStr) 
-                    versionCStr = CFStringGetCStringPtr(versionStr, kCFStringEncodingMacRoman);
-
-                fprintf(stderr, "Xquartz: Could not find a new enough X11.app LSFindApplicationForInfo() returned\n");
-                fprintf(stderr, "         X11.app = %s\n", x11_path);
-                fprintf(stderr, "         Version = %s (%x), Expected Version > 2.3.0 or 2.1.6\n", versionCStr, (unsigned)ver);
-                exit(9);
-            }
-
             strlcat(x11_path, kX11AppBundlePath, sizeof(x11_path));
 #ifdef DEBUG
             fprintf(stderr, "Xquartz: X11.app = %s\n", x11_path);
commit fa480c3522d60aec5ccd6de8a0e0c2f3fb2fef5e
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Sep 26 22:52:39 2009 -0700

    XQuartz: Add pressure/tilt property labels

diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 8836782..30b8905 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -353,6 +353,9 @@ static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
 
             axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
             axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+            axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
+            axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
+            axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
 
             // Set button map.
             InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
commit ff486f5915ab16442e06696721e3898c263b9733
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Sep 26 22:48:49 2009 -0700

    XQuartz: Fix a brain-o array indexing problem
    
    /bop Peter

diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 5ad5392..8836782 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -290,8 +290,8 @@ static int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
 #define NAXES 2
 	// 7 buttons: left, right, middle, then four scroll wheel "buttons"
     CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7};
-    Atom btn_labels[NAXES] = {0};
-    Atom axes_labels[NBUTTONS] = {0};
+    Atom btn_labels[NBUTTONS] = {0};
+    Atom axes_labels[NAXES] = {0};
 
     switch (what) {
         case DEVICE_INIT:
@@ -340,8 +340,8 @@ static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
 #define NBUTTONS 3
 #define NAXES 5
     CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3};
-    Atom axes_labels[NAXES] = {0};
     Atom btn_labels[NBUTTONS] = {0};
+    Atom axes_labels[NAXES] = {0};
 
     switch (what) {
         case DEVICE_INIT:
commit a7674bcc0333c60d36354f39bc18c2f2e29197bc
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Sep 26 22:17:09 2009 -0700

    XQuartz: Nuke duplicate locks that make painful headaches

diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index 4abf4af..503383f 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -296,13 +296,11 @@ static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
 static void DarwinKeyboardSetDeviceKeyMap(KeySymsRec *keySyms, CARD8 *modmap) {
     DeviceIntPtr pDev;
 
-    pthread_mutex_lock(&keyInfo_mutex);
     for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
         if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
             XkbApplyMappingChange(pDev, keySyms, keySyms->minKeyCode,
                                   keySyms->maxKeyCode - keySyms->minKeyCode + 1,
                                   modmap, serverClient);
-    pthread_mutex_unlock(&keyInfo_mutex);
 }
 
 /*
commit 077d5b5b33f8072df2c42883cc790069c26ba926
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Sep 26 22:13:49 2009 -0700

    Xi: CopyKeyClass is not static for XQuartz

diff --git a/Xi/exevents.c b/Xi/exevents.c
index b0e0ede..f85705d 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -192,7 +192,10 @@ XIGetDevice(xEvent* xE)
  * This code is basically the old SwitchCoreKeyboard.
  */
 
-static void
+#ifndef XQUARTZ
+static
+#endif
+void
 CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 {
     KeyClassPtr mk = master->key;
commit 228f5db385aa01ae456927e7840bbf8311d95d4c
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Fri Aug 7 00:02:21 2009 -0700

    XQuartz: Use internal xshm header for new xextproto
    (cherry picked from commit 1755239330c0bdac820d88a3e06ff391d65f29be)
    (cherry picked from commit 697be460d0e555e2c75eed6889293650e02d423c)

diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 7129ac6..5ad5392 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -67,8 +67,7 @@
 #include <IOKit/hidsystem/IOHIDLib.h>
 
 #ifdef MITSHM
-#define _XSHM_SERVER_
-#include <X11/extensions/XShm.h>
+#include "shmint.h"
 #endif
 
 #include "darwin.h"
commit 01cd9c5fc1ad37605f0b2c8cfb6a5dfda7d9736d
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Sep 23 17:41:28 2009 -0700

    XQuartz: GLX capabilities: Allow 16bit accumulation buffers
    
    http://xquartz.macosforge.org/trac/ticket/308
    (cherry picked from commit e9e63a2118b76b6c31c4081fec08a99e4d796e22)

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 99b9eae..4306404 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -103,7 +103,7 @@ static void handleStencilModes(struct glCapabilitiesConfig *c, GLint smodes) {
 }
 
 static int handleColorAndAccumulation(struct glColorBufCapabilities *c, 
-				       GLint cmodes) {
+				       GLint cmodes, int forAccum) {
     int offset = 0;
         
     /*1*/
@@ -204,8 +204,9 @@ static int handleColorAndAccumulation(struct glColorBufCapabilities *c,
 	++offset;
     }
 
-#if 0
-    /* 
+    if(forAccum) {
+//#if 0
+    /* FIXME
      * Disable this path, because some part of libGL, X, or Xplugin 
      * doesn't work with sizes greater than 8.
      * When this is enabled and visuals are chosen using depths
@@ -274,7 +275,8 @@ static int handleColorAndAccumulation(struct glColorBufCapabilities *c,
 	c[offset].a = 16;
 	++offset;
     }
-#endif
+    }
+//#endif
 
     /* FIXME should we handle the floating point color modes, and if so, how? */
       
@@ -284,14 +286,14 @@ static int handleColorAndAccumulation(struct glColorBufCapabilities *c,
 
 static void handleColorModes(struct glCapabilitiesConfig *c, GLint cmodes) {
     c->total_color_buffers = handleColorAndAccumulation(c->color_buffers,
-							cmodes);
+							cmodes, 0);
     
     assert(c->total_color_buffers < GLCAPS_COLOR_BUFFERS);
 }
 
 static void handleAccumulationModes(struct glCapabilitiesConfig *c, GLint cmodes) {
     c->total_accum_buffers = handleColorAndAccumulation(c->accum_buffers,
-							cmodes);
+							cmodes, 1);
     assert(c->total_accum_buffers < GLCAPS_COLOR_BUFFERS);
 }
 
commit e5371c7fc895c51092bd5b2d303e4835c123bd5c
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Sat Sep 26 01:59:39 2009 +0200

    EXA: Extend mixed pixmaps scheme to allow driver PrepareAccess hook to fail.
    
    If the PrepareAccess hook fails, use the DownloadFromScreen hook to retrieve
    driver pixmap contents to a system RAM copy, perform software rendering on that
    and copy the results back using the UploadToScreen hook. Use the classic
    migration logic to minimize transfers (which as a bonus allows slightly
    cleaning up some of the existing mixed pixmap code).
    
    This enables things that weren't possible before with driver-allocated pixmap
    storage: If some (or all) GPU pixmap storage can't be mapped directly by the
    CPU, this can be handled between the PrepareAccess and
    DownloadFrom/UploadToScreen hooks, e.g.:
    
    * Radeon KMS on big endian machines can fail PrepareAccess if the pixmap
      requires byte-swapping and swap bytes in DownloadFrom/UploadToScreen.
    * Environments where GPU and CPU don't have a shared address space at all.
      Here the driver PrepareAccess hook will always fail and leave all transfers
      between GPU / CPU storage to the Download/From/UploadToScreen hooks.
    
    Drivers which can handle all pixmaps in the PrepareAccess hook should notice
    little if any difference.
    (cherry picked from commit 1818cbd70fc1f2e1487b4c678e67e28f1265c0ef)

diff --git a/exa/exa.c b/exa/exa.c
index 483e3b4..e264d44 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -286,11 +286,10 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
  * Returns TRUE if pixmap can be accessed offscreen.
  */
 Bool
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
 {
-    ScreenPtr pScreen = pDrawable->pScreen;
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv (pScreen);
-    PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
     ExaPixmapPriv(pPixmap);
     Bool offscreen;
     int i;
@@ -324,7 +323,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
 
     offscreen = exaPixmapIsOffscreen(pPixmap);
 
-    if (offscreen)
+    if (offscreen && pExaPixmap->fb_ptr)
 	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
     else
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
@@ -333,20 +332,10 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
     pExaScr->access[index].pixmap = pPixmap;
     pExaScr->access[index].count = 1;
 
-    if (!offscreen) {
-	/* Do we need to allocate our system buffer? */
-	if ((pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && (pExaScr->info->flags & EXA_MIXED_PIXMAPS)) {
-	    if (!pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap)) {
-		pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * pDrawable->height);
-		if (!pExaPixmap->sys_ptr)
-		    FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pDrawable->height);
-		pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
-	    }
-	}
+    if (!offscreen)
 	return FALSE;
-    }
 
-    exaWaitSync (pDrawable->pScreen);
+    exaWaitSync (pScreen);
 
     if (pExaScr->info->PrepareAccess == NULL)
 	return TRUE;
@@ -360,7 +349,8 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
     }
 
     if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
-	if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
+	if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED &&
+	    !(pExaScr->info->flags & EXA_MIXED_PIXMAPS))
 	    FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
 	exaMoveOutPixmap (pPixmap);
 
@@ -370,31 +360,6 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
     return TRUE;
 }
 
-void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
-{
-    PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
-    ExaScreenPriv(pPixmap->drawable.pScreen);
-
-    if (pExaScr->do_migration) {
-	ExaMigrationRec pixmaps[1];
-
-	if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
-	    pixmaps[0].as_dst = TRUE;
-	    pixmaps[0].as_src = FALSE;
-	} else {
-	    pixmaps[0].as_dst = FALSE;
-	    pixmaps[0].as_src = TRUE;
-	}
-	pixmaps[0].pPix = pPixmap;
-	pixmaps[0].pReg = pReg;
-
-	exaDoMigration(pixmaps, 1, FALSE);
-    }
-
-    ExaDoPrepareAccess(pDrawable, index);
-}
-
 /**
  * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
  *
@@ -404,7 +369,13 @@ exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
 void
 exaPrepareAccess(DrawablePtr pDrawable, int index)
 {
-    exaPrepareAccessReg(pDrawable, index, NULL);
+    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+    ExaScreenPriv(pDrawable->pScreen);
+
+    if (pExaScr->prepare_access_reg)
+	pExaScr->prepare_access_reg(pPixmap, index, NULL);
+    else
+	(void)ExaDoPrepareAccess(pPixmap, index);
 }
 
 /**
@@ -432,7 +403,6 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
 	if (pExaScr->access[i].pixmap == pPixmap) {
 	    if (--pExaScr->access[i].count > 0)
 		return;
-	    index = i;
 	    break;
 	}
     }
@@ -442,25 +412,25 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
 	EXA_FatalErrorDebug(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n",
 			     pPixmap));
 
-    pExaScr->access[index].pixmap = NULL;
+    pExaScr->access[i].pixmap = NULL;
 
     /* We always hide the devPrivate.ptr. */
     pPixmap->devPrivate.ptr = NULL;
 
-    if (pExaScr->info->FinishAccess == NULL)
-	return;
+    if (pExaScr->finish_access)
+	pExaScr->finish_access(pPixmap, index);
 
-    if (!exaPixmapIsOffscreen (pPixmap))
+    if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap))
 	return;
 
-    if (index >= EXA_PREPARE_AUX_DEST &&
+    if (i >= EXA_PREPARE_AUX_DEST &&
 	!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
 	ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
 	       "unsupported index EXA_PREPARE_AUX*\n");
 	return;
     }
 
-    (*pExaScr->info->FinishAccess) (pPixmap, index);
+    (*pExaScr->info->FinishAccess) (pPixmap, i);
 }
 
 /**
@@ -537,7 +507,7 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
      * For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed.
      * We want to signal that the pixmaps will be used as destination.
      */
-    ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+    ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST);
 
     return pPixmap;
 }
@@ -1071,6 +1041,8 @@ exaDriverInit (ScreenPtr		pScreen,
 		pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed;
 		pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
 		pExaScr->do_move_out_pixmap = NULL;
+		pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
+		pExaScr->finish_access = exaFinishAccess_mixed;
 	    } else {
 		wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
 		wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
@@ -1079,6 +1051,8 @@ exaDriverInit (ScreenPtr		pScreen,
 		pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver;
 		pExaScr->do_move_in_pixmap = NULL;
 		pExaScr->do_move_out_pixmap = NULL;
+		pExaScr->prepare_access_reg = NULL;
+		pExaScr->finish_access = NULL;
 	    }
 	} else {
 	    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
@@ -1088,6 +1062,8 @@ exaDriverInit (ScreenPtr		pScreen,
 	    pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic;
 	    pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
 	    pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
+	    pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
+	    pExaScr->finish_access = NULL;
 	}
 	if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
 	    LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index d8e1e86..0032f02 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -120,7 +120,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
     Bool need_sync = FALSE;
 
     /* Damaged bits are valid in current copy but invalid in other one */
-    if (exaPixmapIsOffscreen(pPixmap)) {
+    if (pExaPixmap->offscreen) {
 	REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
 		     damage);
 	REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
@@ -225,7 +225,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 				    pExaPixmap->sys_pitch))
 	{
 	    if (!access_prepared) {
-		ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
+		ExaDoPrepareAccess(pPixmap, fallback_index);
 		access_prepared = TRUE;
 	    }
 	    exaMemcpyBox (pPixmap, pBox,
@@ -263,7 +263,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
  * the framebuffer  memory copy to the system memory copy.  Both areas must be
  * allocated.
  */
-static void
+void
 exaCopyDirtyToSys (ExaMigrationPtr migrate)
 {
     PixmapPtr pPixmap = migrate->pPix;
@@ -281,7 +281,7 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
  * the system memory copy to the framebuffer memory copy.  Both areas must be
  * allocated.
  */
-static void
+void
 exaCopyDirtyToFb (ExaMigrationPtr migrate)
 {
     PixmapPtr pPixmap = migrate->pPix;
@@ -545,7 +545,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
     pExaPixmap->offscreen = TRUE;
     pPixmap->devKind = pExaPixmap->fb_pitch;
 
-    if (!ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC))
+    if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
 	goto skip;
 
     while (nbox--) {
@@ -718,3 +718,23 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
 	}
     }
 }
+
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg)
+{
+    ExaMigrationRec pixmaps[1];
+
+    if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+	pixmaps[0].as_dst = TRUE;
+	pixmaps[0].as_src = FALSE;
+    } else {
+	pixmaps[0].as_dst = FALSE;
+	pixmaps[0].as_src = TRUE;
+    }
+    pixmaps[0].pPix = pPixmap;
+    pixmaps[0].pReg = pReg;
+
+    exaDoMigration(pixmaps, 1, FALSE);
+
+    (void)ExaDoPrepareAccess(pPixmap, index);
+}
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index d1ee987..f42c9c2 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -31,55 +31,16 @@
 #include "exa_priv.h"
 #include "exa.h"
 
-static void
-exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch)
-{
-    ExaPixmapPriv(pPixmap);
-    RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
-    GCPtr pGC = GetScratchGC (pPixmap->drawable.depth,
-		pPixmap->drawable.pScreen);
-    int nbox, cpp = pPixmap->drawable.bitsPerPixel / 8;
-    DamagePtr backup = pExaPixmap->pDamage;
-    BoxPtr pbox;
-    CARD8 *src2;
-
-    /* We don't want damage optimisations. */
-    pExaPixmap->pDamage = NULL;
-    ValidateGC (&pPixmap->drawable, pGC);
-
-    pbox = REGION_RECTS(damage);
-    nbox = REGION_NUM_RECTS(damage);
-
-    while (nbox--) {
-	src2 = src + pbox->y1 * src_pitch + pbox->x1 * cpp;
-
-	ExaCheckPutImage(&pPixmap->drawable, pGC,
-	    pPixmap->drawable.depth, pbox->x1, pbox->y1,
-	    pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 0,
-	    ZPixmap, (char*) src2);
-
-	pbox++;
-    }
-
-    FreeScratchGC (pGC);
-    pExaPixmap->pDamage = backup;
-}
-
 void
 exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
 {
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPriv(pScreen);
     ExaPixmapPriv(pPixmap);
-    RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
-    void *sys_buffer = pExaPixmap->sys_ptr;
     int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
     int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
     int usage_hint = pPixmap->usage_hint;
-    int sys_pitch = pExaPixmap->sys_pitch;
-    int paddedWidth = sys_pitch;
-    int nbox;
-    BoxPtr pbox;
+    int paddedWidth = pExaPixmap->sys_pitch;
 
     /* Already done. */
     if (pExaPixmap->driverPriv)
@@ -105,50 +66,8 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
     if (!pExaPixmap->driverPriv)
 	return;
 
-    pExaPixmap->offscreen = TRUE;
-    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL;
-    pExaPixmap->sys_pitch = pPixmap->devKind = 0;
-
-    pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
     (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
 				paddedWidth, NULL);
-
-    /* scratch pixmaps */
-    if (!w || !h)
-	goto finish;
-
-    /* we do not malloc memory by default. */
-    if (!sys_buffer)
-	goto finish;
-
-    if (!pExaScr->info->UploadToScreen)
-	goto fallback;
-
-    pbox = REGION_RECTS(damage);
-    nbox = REGION_NUM_RECTS(damage);
-
-    while (nbox--) {
-	if (!pExaScr->info->UploadToScreen(pPixmap, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
-		pbox->y2 - pbox->y1, (char *) (sys_buffer) + pbox->y1 * sys_pitch + pbox->x1 * (bpp / 8), sys_pitch))
-	    goto fallback;
-
-	pbox++;
-    }
-
-    goto finish;
-
-fallback:
-    exaUploadFallback(pPixmap, sys_buffer, sys_pitch);
-
-finish:
-    free(sys_buffer);
-
-    /* We no longer need this. */
-    if (pExaPixmap->pDamage) {
-	DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
-	DamageDestroy(pExaPixmap->pDamage);
-	pExaPixmap->pDamage = NULL;
-    }
 }
 
 void
@@ -175,8 +94,16 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
     for (i = 0; i < npixmaps; i++) {
 	PixmapPtr pPixmap = pixmaps[i].pPix;
 	ExaPixmapPriv(pPixmap);
+
 	if (!pExaPixmap->driverPriv)
 	    exaCreateDriverPixmap_mixed(pPixmap);
+
+	if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+	    pPixmap->devKind = pExaPixmap->fb_pitch;
+	    exaCopyDirtyToFb(pixmaps + i);
+	}
+
+	pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
     }
 }
 
@@ -192,3 +119,91 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
 
     exaDoMigration(pixmaps, 1, TRUE);
 }
+
+/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
+ * use the DownloadFromScreen hook to retrieve contents to a copy in system
+ * memory, perform software rendering on that and move back the results with the
+ * UploadToScreen hook (see exaFinishAccess_mixed).
+ */
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
+{
+    if (!ExaDoPrepareAccess(pPixmap, index)) {
+	ExaPixmapPriv(pPixmap);
+	Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
+	ExaMigrationRec pixmaps[1];
+
+	/* Do we need to allocate our system buffer? */
+	if (!pExaPixmap->sys_ptr) {
+	    pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
+					 pPixmap->drawable.height);
+	    if (!pExaPixmap->sys_ptr)
+		FatalError("EXA: malloc failed for size %d bytes\n",
+			   pExaPixmap->sys_pitch * pPixmap->drawable.height);
+	}
+
+	if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+	    pixmaps[0].as_dst = TRUE;
+	    pixmaps[0].as_src = FALSE;
+	} else {
+	    pixmaps[0].as_dst = FALSE;
+	    pixmaps[0].as_src = TRUE;
+	}
+	pixmaps[0].pPix = pPixmap;
+	pixmaps[0].pReg = pReg;
+
+	if (!pExaPixmap->pDamage && (is_offscreen || !exaPixmapIsPinned(pPixmap))) {
+	    Bool as_dst = pixmaps[0].as_dst;
+
+	    /* Set up damage tracking */
+	    pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+					       TRUE, pPixmap->drawable.pScreen,
+					       pPixmap);
+
+	    DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+	    /* This ensures that pending damage reflects the current operation. */
+	    /* This is used by exa to optimize migration. */
+	    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+
+	    if (is_offscreen) {
+		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
+			       pPixmap->drawable.height);
+
+		/* We don't know which region of the destination will be damaged,
+		 * have to assume all of it
+		 */
+		if (as_dst) {
+		    pixmaps[0].as_dst = FALSE;
+		    pixmaps[0].as_src = TRUE;
+		    pixmaps[0].pReg = NULL;
+		}
+		pPixmap->devKind = pExaPixmap->fb_pitch;
+		exaCopyDirtyToSys(pixmaps);
+	    }
+
+	    if (as_dst)
+		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
+			       pPixmap->drawable.height);
+	} else if (is_offscreen) {
+	    pPixmap->devKind = pExaPixmap->fb_pitch;
+	    exaCopyDirtyToSys(pixmaps);
+	}
+
+	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+	pPixmap->devKind = pExaPixmap->sys_pitch;
+	pExaPixmap->offscreen = FALSE;
+    }
+}
+
+/* Move back results of software rendering on system memory copy of mixed driver
+ * pixmap (see exaPrepareAccessReg_mixed).
+ */
+void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
+{
+    ExaPixmapPriv(pPixmap);
+
+    if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+	DamageRegionProcessPending(&pPixmap->drawable);
+	exaMoveInPixmap_mixed(pPixmap);
+    }
+}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 6aa73f2..167ffa9 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -32,8 +32,6 @@
 #include "exa.h"
 
 /* This file holds the driver allocated pixmaps + better initial placement code.
- * A pinned pixmap implies one that is either driver based already or otherwise altered.
- * Proper care is taken to free the initially allocated buffer.
  */
 
 static _X_INLINE void*
@@ -46,9 +44,6 @@ ExaGetPixmapAddress(PixmapPtr p)
 
 /**
  * exaCreatePixmap() creates a new pixmap.
- *
- * Pixmaps are always marked as pinned, unless the pixmap can still be transfered to a
- * driver pixmaps.
  */
 PixmapPtr
 exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
@@ -85,7 +80,6 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     pExaPixmap->sys_pitch = paddedWidth;
 
     pExaPixmap->area = NULL;
-    pExaPixmap->offscreen = FALSE;
     pExaPixmap->fb_ptr = NULL;
     pExaPixmap->pDamage = NULL;
 
@@ -93,36 +87,15 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     exaSetAccelBlock(pExaScr, pExaPixmap,
 	w, h, bpp);
 
-    /* Avoid freeing sys_ptr. */
-    pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
-
     (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
 				    paddedWidth, NULL);
 
-    /* We want to be able to transfer the pixmap to driver memory later on. */
-    pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
     /* A scratch pixmap will become a driver pixmap right away. */
     if (!w || !h) {
 	exaCreateDriverPixmap_mixed(pPixmap);
-    } else {
-	/* Set up damage tracking */
-	pExaPixmap->pDamage = DamageCreate (NULL, NULL,
-					    DamageReportNone, TRUE,
-					    pScreen, pPixmap);
-
-	if (pExaPixmap->pDamage == NULL) {
-	    swap(pExaScr, pScreen, DestroyPixmap);
-	    pScreen->DestroyPixmap (pPixmap);
-	    swap(pExaScr, pScreen, DestroyPixmap);
-	    return NULL;
-	}
-
-	DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
-	/* This ensures that pending damage reflects the current operation. */
-	/* This is used by exa to optimize migration. */
-	DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
-    }
+	pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
+    } else
+	pExaPixmap->offscreen = FALSE;
 
     return pPixmap;
 }
@@ -134,7 +107,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ExaScreenPrivPtr pExaScr;
     ExaPixmapPrivPtr pExaPixmap;
-    Bool ret;
+    Bool ret, is_offscreen;
 
     if (!pPixmap)
         return FALSE;
@@ -142,26 +115,23 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
     pExaScr = ExaGetScreenPriv(pScreen);
     pExaPixmap = ExaGetPixmapPriv(pPixmap);
 
-    if (pExaPixmap) {
-	if (!exaPixmapIsPinned(pPixmap)) {
-	    free(pExaPixmap->sys_ptr);
-	    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL;
-	    pExaPixmap->sys_pitch = pPixmap->devKind = 0;
-
-	    /* We no longer need this. */
+    if (pPixData) {
+	if (pExaPixmap->driverPriv) {
 	    if (pExaPixmap->pDamage) {
 		DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
 		DamageDestroy(pExaPixmap->pDamage);
 		pExaPixmap->pDamage = NULL;
 	    }
-	}
 
-        if (pPixData)
-            pExaPixmap->sys_ptr = pPixData;
+	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+	    pExaPixmap->driverPriv = NULL;
+	}
 
-        if (devKind > 0)
-            pExaPixmap->sys_pitch = devKind;
+	pExaPixmap->offscreen = FALSE;
+	pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+    }
 
+    if (pExaPixmap->driverPriv) {
         if (width > 0 && height > 0 && bitsPerPixel > 0) {
             exaSetFbPitch(pExaScr, pExaPixmap,
                           width, height, bitsPerPixel);
@@ -169,9 +139,15 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
             exaSetAccelBlock(pExaScr, pExaPixmap,
                              width, height, bitsPerPixel);
         }
+    }
 
-	/* Anything can happen, don't try to predict it all. */
-	pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+    is_offscreen = exaPixmapIsOffscreen(pPixmap);
+    if (is_offscreen) {
+	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+	pPixmap->devKind = pExaPixmap->fb_pitch;
+    } else {
+	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+	pPixmap->devKind = pExaPixmap->sys_pitch;
     }
 
     /* Only pass driver pixmaps to the driver. */
@@ -182,10 +158,6 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
 	 * If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap.
 	 * We need to store the pointer, because PrepareAccess won't be called.
 	 */
-	if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
-	    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
-	    pExaPixmap->sys_pitch = pPixmap->devKind;
-	}
 	if (ret == TRUE)
 	    goto out;
     }
@@ -196,6 +168,13 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
     swap(pExaScr, pScreen, ModifyPixmapHeader);
 
 out:
+    if (is_offscreen) {
+	pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
+	pExaPixmap->fb_pitch = pPixmap->devKind;
+    } else {
+	pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+	pExaPixmap->sys_pitch = pPixmap->devKind;
+    }
     /* Always NULL this, we don't want lingering pointers. */
     pPixmap->devPrivate.ptr = NULL;
 
@@ -215,10 +194,14 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
 
 	if (pExaPixmap->driverPriv)
 	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
-	else if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap))
-	    free(pExaPixmap->sys_ptr);
 	pExaPixmap->driverPriv = NULL;
-	pExaPixmap->sys_ptr = NULL;
+
+	if (pExaPixmap->pDamage) {
+	    if (pExaPixmap->sys_ptr)
+		free(pExaPixmap->sys_ptr);
+	    pExaPixmap->sys_ptr = NULL;
+	    pExaPixmap->pDamage = NULL;
+	}
     }
 
     swap(pExaScr, pScreen, DestroyPixmap);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 869cf17..1aec8e9 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -176,6 +176,8 @@ typedef struct {
     Bool (*pixmap_is_offscreen) (PixmapPtr pPixmap);
     void (*do_move_in_pixmap) (PixmapPtr pPixmap);
     void (*do_move_out_pixmap) (PixmapPtr pPixmap);
+    void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
+    void (*finish_access)(PixmapPtr pPixmap, int index);
 
     Bool			 swappedOut;
     enum ExaMigrationHeuristic	 migration;
@@ -511,10 +513,7 @@ ExaOffscreenFini (ScreenPtr pScreen);
 
 /* exa.c */
 Bool
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
-
-void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
 
 void
 exaPrepareAccess(DrawablePtr pDrawable, int index);
@@ -609,6 +608,12 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
 void
 exaMoveInPixmap_mixed(PixmapPtr pPixmap);
 
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+void
+exaFinishAccess_mixed(PixmapPtr pPixmap, int index);
+
 /* exa_render.c */
 Bool
 exaOpReadsDestination (CARD8 op);
@@ -665,6 +670,12 @@ exaGlyphs (CARD8	op,
 
 /* exa_migration_classic.c */
 void
+exaCopyDirtyToSys (ExaMigrationPtr migrate);
+
+void
+exaCopyDirtyToFb (ExaMigrationPtr migrate);
+
+void
 exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
 
 void
@@ -676,4 +687,7 @@ exaMoveOutPixmap_classic (PixmapPtr pPixmap);
 void
 exaMoveInPixmap_classic (PixmapPtr pPixmap);
 
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
 #endif /* EXAPRIV_H */
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index f4700ad..c8f0172 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -101,16 +101,19 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 		 int x, int y, int w, int h, int leftPad, int format,
 		 char *bits)
 {
-    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
+    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+    ExaPixmapPriv(pPixmap);
+    ExaScreenPriv(pDrawable->pScreen);
 
     EXA_GC_PROLOGUE(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
-    if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+    if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
+	exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
 			      pGC->alu, pGC->clientClipType))
 	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     else
-	exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
-			     DamagePendingRegion(pExaPixmap->pDamage) : NULL);
+	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+				    DamagePendingRegion(pExaPixmap->pDamage));
     pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
     EXA_GC_EPILOGUE(pGC);
@@ -323,9 +326,6 @@ void
 ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 		unsigned int format, unsigned long planeMask, char *d)
 {
-    BoxRec Box;
-    RegionRec Reg;
-    int xoff, yoff;
     ScreenPtr pScreen = pDrawable->pScreen;
     PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
     ExaScreenPriv(pScreen);
@@ -333,16 +333,24 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
     EXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
 
-    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+    if (pExaScr->prepare_access_reg) {
+	int xoff, yoff;
+	BoxRec Box;
+	RegionRec Reg;
+
+	exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+	Box.x1 = pDrawable->y + x + xoff;
+	Box.y1 = pDrawable->y + y + yoff;
+	Box.x2 = Box.x1 + w;
+	Box.y2 = Box.y1 + h;
 
-    Box.x1 = pDrawable->y + x + xoff;
-    Box.y1 = pDrawable->y + y + yoff;
-    Box.x2 = Box.x1 + w;
-    Box.y2 = Box.y1 + h;
+	REGION_INIT(pScreen, &Reg, &Box, 1);
 
-    REGION_INIT(pScreen, &Reg, &Box, 1);
+	pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &Reg);
+    } else
+	exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
 
-    exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
     swap(pExaScr, pScreen, GetImage);
     pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
     swap(pExaScr, pScreen, GetImage);
@@ -401,23 +409,23 @@ ExaCheckComposite (CARD8      op,
     if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
 	exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
 
-    if (!exaOpReadsDestination(op)) {
+    if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) {
+	PixmapPtr pDstPix;
+
 	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
 				       xSrc, ySrc, xMask, yMask, xDst, yDst,
 				       width, height))
 	    goto skip;
 
-	exaGetDrawableDeltas (pDst->pDrawable,
-			      exaGetDrawablePixmap(pDst->pDrawable),
-			      &xoff, &yoff);
-
+	pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+	exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
 	REGION_TRANSLATE(pScreen, &region, xoff, yoff);
 
 	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
-	    exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST,
-				&region);
+	    pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+					EXA_PREPARE_AUX_DEST, &region);
 
-	exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
+	pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, &region);
     } else {
 	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
 	    exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
commit cecd484fbb3db273472d0bf0ec45d8604ff0cde2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Sep 22 20:34:54 2009 +1000

    Require libXext >= 1.0.99.4
    
    Reported-by: Tilman Sauerbeck
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 9fa73be9fa543a686ea35c861084f5af37d44caa)

diff --git a/configure.ac b/configure.ac
index 40cd017..469c374 100644
--- a/configure.ac
+++ b/configure.ac
@@ -738,6 +738,8 @@ dnl Core modules for most extensions, et al.
 REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.11] [fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xextproto >= 7.0.99.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] fontsproto [inputproto >= 1.9.99.902] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau [pixman-1 >= 0.15.20]"
 
+LIBXEXT="xext >= 1.0.99.4"
+
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
 dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
 dnl API.
@@ -1360,7 +1362,7 @@ fi
 
 dnl Xnest DDX
 
-PKG_CHECK_MODULES(XNESTMODULES, [xfont xext x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no])
+PKG_CHECK_MODULES(XNESTMODULES, [xfont $LIBXEXT x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no])
 AC_MSG_CHECKING([whether to build Xnest DDX])
 if test "x$XNEST" = xauto; then
 	XNEST="$have_xnest"
@@ -1775,7 +1777,7 @@ AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
 dnl DMX DDX
 
 PKG_CHECK_MODULES([DMXMODULES],
-    [xmuu xext x11 xrender xfixes xfont xi >= 1.2.99.1 $DMXPROTO xau $XDMCP_MODULES],
+    [xmuu $LIBXEXT x11 xrender xfixes xfont xi >= 1.2.99.1 $DMXPROTO xau $XDMCP_MODULES],
     [have_dmx=yes], [have_dmx=no])
 AC_MSG_CHECKING([whether to build Xdmx DDX])
 if test "x$DMX" = xauto; then
@@ -1810,17 +1812,17 @@ dnl Linux sources in DMX require <linux/keyboard.h>
 	PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11])
 	AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
 	AC_SUBST(XDMXCONFIG_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [dmx xext x11])
+	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [dmx $LIBXEXT x11])
 	AC_SUBST(DMXEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [dmx xmu xext x11])
+	PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [dmx xmu $LIBXEXT x11])
 	AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [dmx xi xext x11])
+	PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [dmx xi $LIBXEXT x11])
 	AC_SUBST(DMXXIEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [xtst xext x11])
+	PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [xtst $LIBXEXT x11])
 	AC_SUBST(XTSTEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres xext x11])
+	PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres $LIBXEXT x11])
 	AC_SUBST(XRESEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([X11EXAMPLES_DEP], [xext x11])
+	PKG_CHECK_MODULES([X11EXAMPLES_DEP], [$LIBXEXT x11])
 	AC_SUBST(X11EXAMPLES_DEP_LIBS)
 fi
 AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes])
@@ -1889,7 +1891,7 @@ if test "$KDRIVE" = yes; then
        XSDL_INCS="`sdl-config --cflags` $XSERVER_CFLAGS"
     fi
 
-    XEPHYR_REQUIRED_LIBS="x11 xext xfont xau xdmcp"
+    XEPHYR_REQUIRED_LIBS="x11 $LIBXEXT xfont xau xdmcp"
     if test "x$XV" = xyes; then
         XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
     fi
commit f188fabfe264dfec1950c168e2d9c22f13797b93
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 23 11:43:27 2009 +1000

    kdrive: plug two memory leaks when freeing the KdKeyboard/Pointer.
    
    xkbRules, xkbModel and xkbLayout are strdup'd in KdNewKeyboard, need to be
    freed.
    
    The ephyr driver strdups the name on top of the already allocated
    kdrive-assigned name. Memory must be freed beforehand.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit a9c274df5c37cb4ece6449e934342d8ff8e61705)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 296284a..254fcbc 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1074,6 +1074,8 @@ MouseInit (KdPointerInfo *pi)
     ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
     pi->nAxes = 3;
     pi->nButtons = 32;
+    if (pi->name)
+        xfree(pi->name);
     pi->name = strdup("Xephyr virtual mouse");
     ephyrMouse = pi;
     return Success;
@@ -1123,6 +1125,8 @@ EphyrKeyboardInit (KdKeyboardInfo *ki)
   }
   ki->minScanCode = ephyrKeySyms.minKeyCode;
   ki->maxScanCode = ephyrKeySyms.maxKeyCode;
+  if (ki->name)
+      xfree(ki->name);
   ki->name = strdup("Xephyr virtual keyboard");
   ephyrKbd = ki;
   return Success;
diff --git a/hw/kdrive/src/kinfo.c b/hw/kdrive/src/kinfo.c
index cb64613..4551fd7 100644
--- a/hw/kdrive/src/kinfo.c
+++ b/hw/kdrive/src/kinfo.c
@@ -166,6 +166,12 @@ KdFreeKeyboard(KdKeyboardInfo *ki)
         xfree(ki->name);
     if (ki->path)
         xfree(ki->path);
+    if (ki->xkbRules)
+        xfree(ki->xkbRules);
+    if (ki->xkbModel)
+        xfree(ki->xkbModel);
+    if (ki->xkbLayout)
+        xfree(ki->xkbLayout);
     ki->next = NULL;
     xfree(ki);
 }
commit 48ab48a6ce12605c7353b45dff4e3a4338b9132e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 23 11:44:12 2009 +1000

    dix: plug memory leak in DeviceEnterLeaveEvents.
    
    'event' must be freed before exiting.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit fd913136732ff14a0484ca28f60ac1fbf49be81d)

diff --git a/dix/events.c b/dix/events.c
index a79cf6d..d60b8a5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4414,10 +4414,12 @@ DeviceEnterLeaveEvent(
                         filter, grab);
     } else {
         if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
-            return;
+            goto out;
         DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
                               NullGrab);
     }
+
+out:
     xfree(event);
 }
 
commit 9e39491166eb4540bbc72e963e673c976301e936
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 24 14:05:52 2009 +1000

    Xi: fix length calculation for ValuatorState in QueryDeviceState reply.
    
    The length field needs to include the bytes required for the valuators
    (INT32) as well.
    
    The reply length has the right value and since the valuator state is always
    last, clients didn't notice the wrong offset.
    
    Tested-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 6ee796e9bb4e46782b50a69c7b4fa5b49576f139)

diff --git a/Xi/queryst.c b/Xi/queryst.c
index 60ec32e..2ba1edb 100644
--- a/Xi/queryst.c
+++ b/Xi/queryst.c
@@ -147,7 +147,7 @@ ProcXQueryDeviceState(ClientPtr client)
     if (v != NULL) {
 	tv = (xValuatorState *) buf;
 	tv->class = ValuatorClass;
-	tv->length = sizeof(xValuatorState);
+	tv->length = sizeof(xValuatorState) + v->numAxes * 4;
 	tv->num_valuators = v->numAxes;
 	tv->mode = v->mode;
 	buf += sizeof(xValuatorState);
commit a9e2f7ac15f426560ac01689ec66f2db32424884
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 23 12:32:44 2009 +1000

    configure: fix up tslib check once again.
    
    This patch addresses two issues:
    The check for HAVE_TSLIB = xauto can never be true, the check has been
    corrected to TSLIB = xauto.
    
    Pre-pkgconfig versions of tslib fail to be found, this patch restores the
    additional AC_CHECK_LIB. However, the pgk-config check must happen before
    AC_CHECK_LIB, as AC_CHECK_LIB does not seem to honour the LD_LIBRARY_PATH.
    Thus, if tslib is installed outside of the default paths, AC_CHECK_LIB
    fails.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked--by: Daniel Stone <daniel at fooishbar.org>
    (cherry picked from commit 3b5bbb149d4c932d9624336f5cbe9fe71c87bea3)

diff --git a/configure.ac b/configure.ac
index db5325e..40cd017 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1861,7 +1861,11 @@ if test "$KDRIVE" = yes; then
 
 
     PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"])
-    if test "x$HAVE_TSLIB" = xauto; then
+    if test "x$HAVE_TSLIB" = xno; then
+        AC_CHECK_LIB(ts, ts_open, [HAVE_TSLIB="yes"])
+    fi
+
+    if test "xTSLIB" = xauto; then
         TSLIB="$HAVE_TSLIB"
     fi
 
commit 1f74cfdeacb88b466d8f2005af191db30dde2a86
Author: Thomas Jaeger <thjaeger at gmail.com>
Date:   Tue Sep 22 20:16:21 2009 -0400

    dix: report XI1 axis values correctly if first_valuator != 0
    
    Signed-off-by: Thomas Jaeger <ThJaeger at gmail.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5402f18d9c3f7ba19cc05b3a814e3a9e94c8d551)

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index d91ba67..e25f3ee 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -352,17 +352,17 @@ getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
         xv->device_state = state;
         switch (xv->num_valuators) {
         case 6:
-            xv->valuator5 = ev->valuators.data[i + 5];
+            xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
         case 5:
-            xv->valuator4 = ev->valuators.data[i + 4];
+            xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
         case 4:
-            xv->valuator3 = ev->valuators.data[i + 3];
+            xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
         case 3:
-            xv->valuator2 = ev->valuators.data[i + 2];
+            xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
         case 2:
-            xv->valuator1 = ev->valuators.data[i + 1];
+            xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
         case 1:
-            xv->valuator0 = ev->valuators.data[i + 0];
+            xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
         }
 
         if (i + 6 < num_valuators)
commit 8867c60782909816826054ed0587094e58eb39e6
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Wed Sep 23 13:10:05 2009 +0200

    render: Don't add b8g8r8x8 format for depth 24.
    
    The components are required to be packed in the bottom of the pixel, so this
    format can't fit in depth 24.
    
    Also fix up a comment for the addition of BGRA formats.
    (cherry picked from commit ce1fe8ddb4a4dbe6cfd909e5b1b73b459d742bec)

diff --git a/render/picture.c b/render/picture.c
index a367077..e1a2972 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -223,9 +223,8 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
 	    b = Ones (pVisual->blueMask);
 	    type = PICT_TYPE_OTHER;
 	    /*
-	     * Current rendering code supports only two direct formats,
+	     * Current rendering code supports only three direct formats,
 	     * fields must be packed together at the bottom of the pixel
-	     * and must be either RGB or BGR
 	     */
 	    if (pVisual->offsetBlue == 0 &&
 		pVisual->offsetGreen == b &&
@@ -322,8 +321,6 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
 				      PICT_x8r8g8b8, pDepth->depth);
 		nformats = addFormat (formats, nformats,
 				      PICT_x8b8g8r8, pDepth->depth);
-		nformats = addFormat (formats, nformats,
-				      PICT_b8g8r8x8, pDepth->depth);
 	    }
 	    if (pDepth->depth >= 30)
 	    {
commit ac1490b651a251407e1bbc98e3ccd265a9e491b5
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Wed Sep 23 08:24:06 2009 +0200

    EXA: Fix some issues pointed out by clang.
    
    Remove dead variables, fix use of uninitialized values, that kind of thing.
    (cherry picked from commit 096f21bb7a1217443d8a03529b1a2938518eb24f)

diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index d621ccf..bf097c3 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -701,7 +701,6 @@ exaGlyphs (CARD8 	 op,
 	   GlyphListPtr	 list,
 	   GlyphPtr	*glyphs)
 {
-    PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = 0;
     PicturePtr  pMask = NULL;
     ScreenPtr   pScreen = pDst->pDrawable->pScreen;
@@ -803,7 +802,6 @@ exaGlyphs (CARD8 	 op,
 	while (n--)
 	{
 	    glyph = *glyphs++;
-	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
 
 	    if (glyph->info.width > 0 && glyph->info.height > 0)
 	    {
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 01f87ba..6aa73f2 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -57,7 +57,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     PixmapPtr pPixmap;
     ExaPixmapPrivPtr	pExaPixmap;
     int bpp;
-    size_t paddedWidth, datasize;
+    size_t paddedWidth;
     ExaScreenPriv(pScreen);
 
     if (w > 32767 || h > 32767)
@@ -79,8 +79,6 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     if (paddedWidth / 4 > 32767 || h > 32767)
         return NullPixmap;
 
-    datasize = h * paddedWidth;
-
     /* We will allocate the system pixmap later if needed. */
     pPixmap->devPrivate.ptr = NULL;
     pExaPixmap->sys_ptr = NULL;
diff --git a/exa/exa_render.c b/exa/exa_render.c
index d469301..1c18566 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -266,6 +266,10 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
+    if (pSrc->pDrawable) {
+	xSrc += pSrc->pDrawable->x;
+	ySrc += pSrc->pDrawable->y;
+    }
 
     if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
 				   xSrc, ySrc, 0, 0, xDst, yDst,
@@ -277,9 +281,6 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
     REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
 
     if (pSrc->pDrawable) {
-	xSrc += pSrc->pDrawable->x;
-	ySrc += pSrc->pDrawable->y;
-
 	pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
 	pixel = exaGetPixmapFirstPixel (pSrcPix);
     } else
@@ -340,7 +341,8 @@ exaTryDriverCompositeRects(CARD8	       op,
 			   ExaCompositeRectPtr rects)
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
-    int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
+    int src_off_x = 0, src_off_y = 0, mask_off_x = 0, mask_off_y = 0;
+    int dst_off_x, dst_off_y;
     PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
     ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
 
@@ -656,7 +658,7 @@ exaTryDriverComposite(CARD8		op,
      */
     if (pDstExaPix->accel_blocked ||
 	(pSrcExaPix && pSrcExaPix->accel_blocked) ||
-	(pMask && (pMaskExaPix->accel_blocked)))
+	(pMaskExaPix && (pMaskExaPix->accel_blocked)))
     {
 	return -1;
     }
commit 6b656c3498fa1bdbf93b2951b27cc8ff00e65990
Author: Simon Thum <simon.thum at gmx.de>
Date:   Mon Sep 21 15:23:27 2009 +0200

    dix: move bounds check before access
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 824a09d856a5f750694e11d2fd2faaa3de705eaa)

diff --git a/dix/getevents.c b/dix/getevents.c
index 7ddf88b..5224d31 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -578,12 +578,13 @@ GetMaximumEventsNum(void) {
 static void
 clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
 {
-    AxisInfoPtr axis = pDev->valuator->axes + axisNum;
-    /* InitValuatoraAxisStruct ensures that (min < max). */
+    AxisInfoPtr axis;
 
     if (axisNum >= pDev->valuator->numAxes)
         return;
 
+    axis = pDev->valuator->axes + axisNum;
+
     /* If a value range is defined, clip. If not, do nothing */
     if (axis->max_value <= axis->min_value)
         return;


More information about the xorg-commit mailing list