[Xquartz-changes] xserver: Branch 'server-1.7-apple' - 9 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Wed Apr 21 08:37:08 PDT 2010


Rebased ref, commits from common ancestor:
commit bfb4bc102c407c8a0fc3155f747bd9ac779f537e
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sun Jan 31 01:38:53 2010 -0800

    fb: Revert fb changes that broke XQuartz
    
    http://bugs.freedesktop.org/show_bug.cgi?id=26124
    
    Revert "Fix source pictures getting random transforms after 2d6a8f668342a5190cdf43b5."
    Revert "fb: backport fb changes from master for src window operations."
    
    This reverts commit 66b6e2fd49fdc650703e56aa176a902e4921251c.
    This reverts commit 2d6a8f668342a5190cdf43b5d385f592d10f5900.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at freedesktop.org>

diff --git a/fb/fb.h b/fb/fb.h
index 8b2839a..37de71e 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -700,41 +700,38 @@ typedef struct {
 #define __fbPixOffXPix(pPix)	(__fbPixDrawableX(pPix))
 #define __fbPixOffYPix(pPix)	(__fbPixDrawableY(pPix))
 
-#define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) {			\
-    if ((pDrawable)->type != DRAWABLE_PIXMAP) { 				\
-	(pixmap) = fbGetWindowPixmap(pDrawable);				\
-	(xoff) = __fbPixOffXWin(pixmap); 					\
-	(yoff) = __fbPixOffYWin(pixmap); 					\
-    } else { 									\
-	(pixmap) = (PixmapPtr) (pDrawable);					\
-	(xoff) = __fbPixOffXPix(pixmap); 					\
-	(yoff) = __fbPixOffYPix(pixmap); 					\
-    } 										\
-    fbPrepareAccess(pDrawable); 						\
-}
-
-#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) {			\
-    (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; 			       	\
-    (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);	\
-    (bpp) = (pixmap)->drawable.bitsPerPixel;  (void)(bpp); 			\
-}
-
-#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) {			\
-    (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; 			       	\
-    (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);	\
-    (bpp) = (pixmap)->drawable.bitsPerPixel;  (void)(bpp); 			\
-}
-
-#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { 		\
-    PixmapPtr   _pPix; 								\
-    fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); 				\
-    fbGetPixmapBitsData(_pPix, pointer, stride, bpp);				\
+#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
+    PixmapPtr   _pPix; \
+    if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
+	_pPix = fbGetWindowPixmap(pDrawable); \
+	(xoff) = __fbPixOffXWin(_pPix); \
+	(yoff) = __fbPixOffYWin(_pPix); \
+    } else { \
+	_pPix = (PixmapPtr) (pDrawable); \
+	(xoff) = __fbPixOffXPix(_pPix); \
+	(yoff) = __fbPixOffYPix(_pPix); \
+    } \
+    fbPrepareAccess(pDrawable); \
+    (pointer) = (FbBits *) _pPix->devPrivate.ptr; \
+    (stride) = ((int) _pPix->devKind) / sizeof (FbBits); (void)(stride); \
+    (bpp) = _pPix->drawable.bitsPerPixel;  (void)(bpp); \
 }
 
-#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { 	\
-    PixmapPtr   _pPix; 								\
-    fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff);				\
-    fbGetPixmapStipData(_pPix, pointer, stride, bpp);				\
+#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
+    PixmapPtr   _pPix; \
+    if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
+	_pPix = fbGetWindowPixmap(pDrawable); \
+	(xoff) = __fbPixOffXWin(_pPix); \
+	(yoff) = __fbPixOffYWin(_pPix); \
+    } else { \
+	_pPix = (PixmapPtr) (pDrawable); \
+	(xoff) = __fbPixOffXPix(_pPix); \
+	(yoff) = __fbPixOffYPix(_pPix); \
+    } \
+    fbPrepareAccess(pDrawable); \
+    (pointer) = (FbStip *) _pPix->devPrivate.ptr; \
+    (stride) = ((int) _pPix->devKind) / sizeof (FbStip); (void)(stride); \
+    (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \
 }
 
 /*
@@ -2082,16 +2079,9 @@ fbFillRegionSolid (DrawablePtr	pDrawable,
 		   FbBits	xor);
 
 extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr	pict,
-		 Bool		has_clip,
-		 Bool		is_src);
-
-extern _X_EXPORT pixman_image_t *
-image_from_pict_18 (PicturePtr	pict,
-		 Bool		has_clip,
-		 int		*xoff,
-		 int		*yoff);
-
+image_from_pict (PicturePtr pict,
+		 Bool       has_clip,
+		 Bool       is_src);
 extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
 
 #endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index c046bae..8fdaa58 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -158,24 +158,19 @@ fbComposite (CARD8      op,
 	     CARD16     height)
 {
     pixman_image_t *src, *mask, *dest;
-    int src_xoff, src_yoff;
-    int msk_xoff, msk_yoff;
-    int dst_xoff, dst_yoff;
     
-    miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
+    miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
     if (pMask)
-	miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
+	miCompositeSourceValidate (pMask, xMask, yMask, width, height);
     
-    src = image_from_pict_18 (pSrc, FALSE, &src_xoff, &src_yoff);
-    mask = image_from_pict_18 (pMask, FALSE, &msk_xoff, &msk_yoff);
-    dest = image_from_pict_18 (pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict (pSrc, TRUE, TRUE);
+    mask = image_from_pict (pMask, TRUE, TRUE);
+    dest = image_from_pict (pDst, TRUE, FALSE);
 
     if (src && dest && !(pMask && !mask))
     {
 	pixman_image_composite (op, src, mask, dest,
-				xSrc + src_xoff, ySrc + src_yoff,
-				xMask + msk_xoff, yMask + msk_yoff,
-				xDst + dst_xoff, yDst + dst_yoff,
+				xSrc, ySrc, xMask, yMask, xDst, yDst,
 				width, height);
     }
 
@@ -275,22 +270,22 @@ create_conical_gradient_image (PictGradient *gradient)
 
 static pixman_image_t *
 create_bits_picture (PicturePtr pict,
-		     Bool       has_clip,
-		     int	*xoff,
-		     int	*yoff)
+		     Bool       has_clip)
 {
-    PixmapPtr pixmap;
     FbBits *bits;
     FbStride stride;
-    int bpp;
+    int bpp, xoff, yoff;
     pixman_image_t *image;
     
-    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
-    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+
+    bits = (FbBits*)((CARD8*)bits +
+		     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
+		     (pict->pDrawable->x + xoff) * (bpp / 8));
 
     image = pixman_image_create_bits (
 	pict->format,
-	pixmap->drawable.width, pixmap->drawable.height,
+	pict->pDrawable->width, pict->pDrawable->height,
 	(uint32_t *)bits, stride * sizeof (FbStride));
     
     
@@ -316,52 +311,30 @@ create_bits_picture (PicturePtr pict,
 	if (pict->clientClipType != CT_NONE)
 	    pixman_image_set_has_client_clip (image, TRUE);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
+	pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
 
 	pixman_image_set_clip_region (image, pict->pCompositeClip);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
+	pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
     }
     
     /* Indexed table */
     if (pict->pFormat->index.devPrivate)
 	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
 
-    /* Add in drawable origin to position within the image */
-    *xoff += pict->pDrawable->x;
-    *yoff += pict->pDrawable->y;
-
     return image;
 }
 
 static void
-set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+set_image_properties (pixman_image_t *image, PicturePtr pict)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
     
     if (pict->transform)
     {
-	/* For source images, adjust the transform to account
-	 * for the drawable offset within the pixman image,
-	 * then set the offset to 0 as it will be used
-	 * to compute positions within the transformed image.
-	 */
-	if (!has_clip) {
-	    struct pixman_transform	adjusted;
-
-	    adjusted = *pict->transform;
-	    pixman_transform_translate(&adjusted,
-				       NULL,
-				       pixman_int_to_fixed(*xoff),
-				       pixman_int_to_fixed(*yoff));
-	    pixman_image_set_transform (image, &adjusted);
-	    *xoff = 0;
-	    *yoff = 0;
-	} else
-	    pixman_image_set_transform (image, pict->transform);
+	pixman_image_set_transform (
+	    image, (pixman_transform_t *)pict->transform);
     }
     
     switch (pict->repeatType)
@@ -388,8 +361,7 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
     
     if (pict->alphaMap)
     {
-	int alpha_xoff, alpha_yoff;
-	pixman_image_t *alpha_map = image_from_pict_18 (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff);
+	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE, TRUE);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -421,9 +393,10 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
     pixman_image_set_source_clipping (image, TRUE);
 }
 
-
 pixman_image_t *
-image_from_pict_18 (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+image_from_pict (PicturePtr pict,
+		 Bool has_clip,
+		 Bool is_src)
 {
     pixman_image_t *image = NULL;
 
@@ -432,7 +405,7 @@ image_from_pict_18 (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 
     if (pict->pDrawable)
     {
-	image = create_bits_picture (pict, has_clip, xoff, yoff);
+	image = create_bits_picture (pict, has_clip);
     }
     else if (pict->pSourcePict)
     {
@@ -453,22 +426,14 @@ image_from_pict_18 (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 	    else if (sp->type == SourcePictTypeConical)
 		image = create_conical_gradient_image (gradient);
 	}
-	*xoff = *yoff = 0;
     }
     
     if (image)
-	set_image_properties (image, pict, has_clip, xoff, yoff);
+	set_image_properties (image, pict);
     
     return image;
 }
 
-pixman_image_t *
-image_from_pict (PicturePtr pict, Bool has_clip, Bool is_src)
-{
-    int xoff = 0, yoff = 0;
-    return image_from_pict_18(pict, has_clip, &xoff, &yoff);
-}
-
 void
 free_pixman_pict (PicturePtr pict, pixman_image_t *image)
 {
@@ -498,4 +463,3 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
 
     return TRUE;
 }
-
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 5b5aeae..b1e1eff 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -40,8 +40,7 @@ fbAddTraps (PicturePtr	pPicture,
 	    int		ntrap,
 	    xTrap	*traps)
 {
-    int image_xoff, image_yoff;
-    pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &image_xoff, &image_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE);
 
     if (!image)
 	return;
@@ -57,8 +56,7 @@ fbRasterizeTrapezoid (PicturePtr    pPicture,
 		      int	    x_off,
 		      int	    y_off)
 {
-    int	mask_xoff, mask_yoff;
-    pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &mask_xoff, &mask_yoff);
+    pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE);
 
     if (!image)
 	return;
diff --git a/fb/wfbrename.h b/fb/wfbrename.h
index e9cdca8..73ee510 100644
--- a/fb/wfbrename.h
+++ b/fb/wfbrename.h
@@ -187,5 +187,4 @@
 #define fbZeroSegment wfbZeroSegment
 #define free_pixman_pict wfb_free_pixman_pict
 #define image_from_pict wfb_image_from_pict
-#define image_from_pict_18 wfb_image_from_pict_18
 #define composeFunctions wfbComposeFunctions
commit 7815b02e8d9636b6abbe1f7cb555a1069db2d59f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 21 11:47:24 2010 +1000

    Revert "mi: don't thrash resources when displaying the software cursor across screens"
    
    This commit leads to a segfault on the very first XTS test case.
    
    Backtrace:
    0: /opt/xorg/bin/Xorg (xorg_backtrace+0x3b) [0x80a33db]
    1: /opt/xorg/bin/Xorg (0x8048000+0x62a75) [0x80aaa75]
    2: (vdso) (__kernel_rt_sigreturn+0x0) [0x5d140c]
    3: /lib/libc.so.6 (0x9bb000+0x73579) [0xa2e579]
    4: /lib/libc.so.6 (realloc+0xe0) [0xa2e830]
    5: /opt/xorg/bin/Xorg (Xrealloc+0x33) [0x80a3f33]
    6: /opt/xorg/bin/Xorg (0x8048000+0x1ab79) [0x8062b79]
    7: /opt/xorg/bin/Xorg (0x8048000+0x1ac4e) [0x8062c4e]
    8: /opt/xorg/bin/Xorg (RegisterExtensionNames+0x2ce) [0x8062fbe]
    9: /opt/xorg/bin/Xorg (AddExtension+0x19a) [0x807bd7a]
    10: /opt/xorg//lib/xorg/modules/extensions/libextmod.so (0x728000+0x1169a)
    [0x73969a]
    11: /opt/xorg/bin/Xorg (InitExtensions+0x85) [0x80c0eb5]
    12: /opt/xorg/bin/Xorg (0x8048000+0x1a51d) [0x806251d]
    13: /lib/libc.so.6 (__libc_start_main+0xe6) [0x9d1bb6]
    14: /opt/xorg/bin/Xorg (0x8048000+0x1a2a1) [0x80622a1]
    Segmentation fault at address 0x10b2d5f8
    
    valgrind output:
    ==5069== Invalid read of size 4
    ==5069==    at 0x80F928D: FreePicture (picture.c:1531)
    ==5069==    by 0x818DDEF: miDCDeviceCleanup (midispcur.c:867)
    ==5069==    by 0x81B97F0: miSpriteDeviceCursorCleanup (misprite.c:968)
    ==5069==    by 0x80995FA: miPointerDeviceCleanup (mipointer.c:292)
    ==5069==    by 0x807973E: CloseDevice (devices.c:840)
    ==5069==    by 0x80799B6: CloseDownDevices (devices.c:933)
    ==5069==    by 0x8062705: main (main.c:309)
    ==5069==  Address 0x4cce844 is 12 bytes inside a block of size 84 free'd
    ==5069==    at 0x40057F6: free (vg_replace_malloc.c:325)
    ==5069==    by 0x80A3DE0: Xfree (utils.c:1154)
    ==5069==    by 0x80F9332: FreePicture (picture.c:1576)
    ==5069==    by 0x80FBB4B: PictureDestroyWindow (picture.c:69)
    ==5069==    by 0x810B1A3: damageDestroyWindow (damage.c:1840)
    ==5069==    by 0x80864F1: FreeWindowResources (window.c:846)
    ==5069==    by 0x8086812: DeleteWindow (window.c:925)
    ==5069==    by 0x806B53E: FreeClientResources (resource.c:806)
    ==5069==    by 0x806B60F: FreeAllResources (resource.c:823)
    ==5069==    by 0x80626E4: main (main.c:299)
    ==5069==
    ==5069== Invalid write of size 4
    ==5069==    at 0x80F9295: FreePicture (picture.c:1531)
    ==5069==    by 0x818DDEF: miDCDeviceCleanup (midispcur.c:867)
    ==5069==    by 0x81B97F0: miSpriteDeviceCursorCleanup (misprite.c:968)
    ==5069==    by 0x80995FA: miPointerDeviceCleanup (mipointer.c:292)
    ==5069==    by 0x807973E: CloseDevice (devices.c:840)
    ==5069==    by 0x80799B6: CloseDownDevices (devices.c:933)
    ==5069==    by 0x8062705: main (main.c:309)
    ==5069==  Address 0x4cce844 is 12 bytes inside a block of size 84 free'd
    ==5069==    at 0x40057F6: free (vg_replace_malloc.c:325)
    ==5069==    by 0x80A3DE0: Xfree (utils.c:1154)
    ==5069==    by 0x80F9332: FreePicture (picture.c:1576)
    ==5069==    by 0x80FBB4B: PictureDestroyWindow (picture.c:69)
    ==5069==    by 0x810B1A3: damageDestroyWindow (damage.c:1840)
    ==5069==    by 0x80864F1: FreeWindowResources (window.c:846)
    ==5069==    by 0x8086812: DeleteWindow (window.c:925)
    ==5069==    by 0x806B53E: FreeClientResources (resource.c:806)
    ==5069==    by 0x806B60F: FreeAllResources (resource.c:823)
    ==5069==    by 0x80626E4: main (main.c:299)
    
    XTS test case: Xproto pAllocColor
    
    This reverts commit 00b8b7ad61b6f818271fb4d1e383113170309d72.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/midispcur.c b/mi/midispcur.c
index 3a31b74..55d65d5 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -59,9 +59,9 @@ static DevPrivateKey miDCScreenKey = &miDCScreenKeyIndex;
 
 static Bool	miDCCloseScreen(int index, ScreenPtr pScreen);
 
-/* per device per-screen private data */
-static int miDCSpriteKeyIndex[MAXSCREENS];
-static DevPrivateKey miDCSpriteKey = miDCSpriteKeyIndex;
+/* per device private data */
+static int miDCSpriteKeyIndex;
+static DevPrivateKey miDCSpriteKey = &miDCSpriteKeyIndex;
 
 typedef struct {
     GCPtr	    pSourceGC, pMaskGC;
@@ -75,10 +75,10 @@ typedef struct {
 #endif
 } miDCBufferRec, *miDCBufferPtr;
 
-#define MIDCBUFFER(dev, screen) \
+#define MIDCBUFFER(dev) \
  ((DevHasCursor(dev)) ? \
-  (miDCBufferPtr)dixLookupPrivate(&dev->devPrivates, miDCSpriteKey + (screen)->myNum) : \
-  (miDCBufferPtr)dixLookupPrivate(&dev->u.master->devPrivates, miDCSpriteKey + (screen)->myNum))
+  (miDCBufferPtr)dixLookupPrivate(&dev->devPrivates, miDCSpriteKey) : \
+  (miDCBufferPtr)dixLookupPrivate(&dev->u.master->devPrivates, miDCSpriteKey))
 
 /* 
  * The core pointer buffer will point to the index of the virtual core pointer
@@ -158,6 +158,10 @@ miDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
     return TRUE;
 }
 
+#define tossGC(gc)  (gc ? FreeGC (gc, (GContext) 0) : 0)
+#define tossPix(pix)	(pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
+#define tossPict(pict)	(pict ? FreePicture (pict, 0) : 0)
+
 static Bool
 miDCCloseScreen (int index, ScreenPtr pScreen)
 {
@@ -179,6 +183,7 @@ miDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 }
 
 #ifdef ARGB_CURSOR
+#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
 
 static VisualPtr
 miDCGetWindowVisual (WindowPtr pWin)
@@ -410,8 +415,12 @@ miDCPutBits (
     (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
 }
 
+#define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
+
 static GCPtr
-miDCMakeGC(WindowPtr pWin)
+miDCMakeGC(
+    GCPtr	*ppGC,
+    WindowPtr	pWin)
 {
     GCPtr pGC;
     int   status;
@@ -422,6 +431,7 @@ miDCMakeGC(WindowPtr pWin)
     pGC = CreateGC((DrawablePtr)pWin,
 		   GCSubwindowMode|GCGraphicsExposures, gcvals, &status,
 		   (XID)0, serverClient);
+    *ppGC = pGC;
     return pGC;
 }
 
@@ -446,11 +456,22 @@ miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = MIDCBUFFER(pDev, pScreen);
+    pBuffer = MIDCBUFFER(pDev);
 
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
+        /* see comment in miDCPutUpCursor */
+        if (pBuffer->pRootPicture &&
+                pBuffer->pRootPicture->pDrawable &&
+                pBuffer->pRootPicture->pDrawable->pScreen != pScreen)
+        {
+            tossPict(pBuffer->pRootPicture);
+            pBuffer->pRootPicture = NULL;
+        }
+
+	if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
+	    return FALSE;
 	CompositePicture (PictOpOver,
 			  pPriv->pPicture,
 			  NULL,
@@ -463,6 +484,33 @@ miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     else
 #endif
     {
+        /**
+         * XXX: Before MPX, the sourceGC and maskGC were attached to the
+         * screen, and would switch as the screen switches.  With mpx we have
+         * the GC's attached to the device now, so each time we switch screen
+         * we need to make sure the GC's are allocated on the new screen.
+         * This is ... not optimal. (whot)
+         */
+        if (pBuffer->pSourceGC && pScreen != pBuffer->pSourceGC->pScreen)
+        {
+            tossGC(pBuffer->pSourceGC);
+            pBuffer->pSourceGC = NULL;
+        }
+
+        if (pBuffer->pMaskGC && pScreen != pBuffer->pMaskGC->pScreen)
+        {
+            tossGC(pBuffer->pMaskGC);
+            pBuffer->pMaskGC = NULL;
+        }
+
+	if (!EnsureGC(pBuffer->pSourceGC, pWin))
+	    return FALSE;
+	if (!EnsureGC(pBuffer->pMaskGC, pWin))
+	{
+	    FreeGC (pBuffer->pSourceGC, (GContext) 0);
+	    pBuffer->pSourceGC = 0;
+	    return FALSE;
+	}
 	miDCPutBits ((DrawablePtr)pWin, pPriv,
 		     pBuffer->pSourceGC, pBuffer->pMaskGC,
 		     x, y, pCursor->bits->width, pCursor->bits->height,
@@ -483,7 +531,7 @@ miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev, pScreen);
+    pBuffer = MIDCBUFFER(pDev);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -496,7 +544,14 @@ miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 	if (!pSave)
 	    return FALSE;
     }
-
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pSaveGC);
+        pBuffer->pSaveGC = NULL;
+    }
+    if (!EnsureGC(pBuffer->pSaveGC, pWin))
+	return FALSE;
     pGC = pBuffer->pSaveGC;
     if (pSave->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pSave, pGC);
@@ -517,13 +572,20 @@ miDCRestoreUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev, pScreen);
+    pBuffer = MIDCBUFFER(pDev);
     pSave = pBuffer->pSave;
 
     pWin = WindowTable[pScreen->myNum];
     if (!pSave)
 	return FALSE;
-
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
+    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
+	return FALSE;
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -545,7 +607,7 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev, pScreen);
+    pBuffer = MIDCBUFFER(pDev);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -554,7 +616,14 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
      */
     if (!pSave)
 	return FALSE;
-
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
+    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
+	return FALSE;
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -593,7 +662,14 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
 	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
 			       0, sourcey, -dx, copyh, x + dx, desty);
     }
-
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pSaveGC);
+        pBuffer->pSaveGC = NULL;
+    }
+    if (!EnsureGC(pBuffer->pSaveGC, pWin))
+	return FALSE;
     pGC = pBuffer->pSaveGC;
     if (pSave->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pSave, pGC);
@@ -690,7 +766,7 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = MIDCBUFFER(pDev, pScreen);
+    pBuffer = MIDCBUFFER(pDev);
 
     pTemp = pBuffer->pTemp;
     if (!pTemp ||
@@ -733,9 +809,17 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
-	if (!pBuffer->pTempPicture)
-            miDCMakePicture(&pBuffer->pTempPicture, &pTemp->drawable, pWin);
+        /* see comment in miDCPutUpCursor */
+        if (pBuffer->pTempPicture &&
+                pBuffer->pTempPicture->pDrawable &&
+                pBuffer->pTempPicture->pDrawable->pScreen != pScreen)
+        {
+            tossPict(pBuffer->pTempPicture);
+            pBuffer->pTempPicture = NULL;
+        }
 
+	if (!EnsurePicture(pBuffer->pTempPicture, &pTemp->drawable, pWin))
+	    return FALSE;
 	CompositePicture (PictOpOver,
 			  pPriv->pPicture,
 			  NULL,
@@ -748,12 +832,38 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     else
 #endif
     {
+	if (!pBuffer->pPixSourceGC)
+	{
+	    pBuffer->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
+		GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
+	    if (!pBuffer->pPixSourceGC)
+		return FALSE;
+	}
+	if (!pBuffer->pPixMaskGC)
+	{
+	    pBuffer->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
+		GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
+	    if (!pBuffer->pPixMaskGC)
+		return FALSE;
+	}
 	miDCPutBits ((DrawablePtr)pTemp, pPriv,
 		     pBuffer->pPixSourceGC, pBuffer->pPixMaskGC,
 		     dx, dy, pCursor->bits->width, pCursor->bits->height,
 		     source, mask);
     }
 
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
+    /*
+     * copy the temporary pixmap onto the screen
+     */
+
+    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
+	return FALSE;
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -767,113 +877,51 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
 static Bool
 miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
-    miDCBufferPtr   pBuffer;
-    WindowPtr       pWin;
-    XID             gcval = FALSE;
-    int             status;
-    int             i;
-
-    if (!DevHasCursor(pDev))
-        return TRUE;
-
-    for (i = 0; i < screenInfo.numScreens; i++)
-    {
-        pScreen = screenInfo.screens[i];
-
-        pBuffer = xalloc(sizeof(miDCBufferRec));
-        if (!pBuffer)
-            goto failure;
-
-        dixSetPrivate(&pDev->devPrivates, miDCSpriteKey + pScreen->myNum, pBuffer);
-        pWin = WindowTable[pScreen->myNum];
-
-        pBuffer->pSourceGC = miDCMakeGC(pWin);
-        if (!pBuffer->pSourceGC)
-            goto failure;
-
-        pBuffer->pMaskGC = miDCMakeGC(pWin);
-        if (!pBuffer->pMaskGC)
-            goto failure;
-
-        pBuffer->pSaveGC = miDCMakeGC(pWin);
-        if (!pBuffer->pSaveGC)
-            goto failure;
-
-        pBuffer->pRestoreGC = miDCMakeGC(pWin);
-        if (!pBuffer->pRestoreGC)
-            goto failure;
-
-        pBuffer->pMoveGC = CreateGC ((DrawablePtr)pWin,
-            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
-        if (!pBuffer->pMoveGC)
-            goto failure;
-
-        pBuffer->pPixSourceGC = CreateGC ((DrawablePtr)pWin,
-            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
-        if (!pBuffer->pPixSourceGC)
-            goto failure;
-
-        pBuffer->pPixMaskGC = CreateGC ((DrawablePtr)pWin,
-            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
-        if (!pBuffer->pPixMaskGC)
-            goto failure;
-
+    miDCBufferPtr pBuffer;
+
+    pBuffer = xalloc(sizeof(miDCBufferRec));
+    dixSetPrivate(&pDev->devPrivates, miDCSpriteKey, pBuffer);
+
+    pBuffer->pSourceGC =
+        pBuffer->pMaskGC =
+        pBuffer->pSaveGC =
+        pBuffer->pRestoreGC =
+        pBuffer->pMoveGC =
+        pBuffer->pPixSourceGC =
+        pBuffer->pPixMaskGC = NULL;
 #ifdef ARGB_CURSOR
-        miDCMakePicture(&pBuffer->pRootPicture, &pWin->drawable, pWin);
-        if (!pBuffer->pRootPicture)
-            goto failure;
-
-        pBuffer->pTempPicture = NULL;
+    pBuffer->pRootPicture = NULL;
+    pBuffer->pTempPicture = NULL;
 #endif
-
-        // these get (re)allocated lazily depending on the cursor size
-        pBuffer->pSave = pBuffer->pTemp = NULL;
-    }
+    pBuffer->pSave = pBuffer->pTemp = NULL;
 
     return TRUE;
-
-failure:
-
-    miDCDeviceCleanup(pDev, pScreen);
-
-    return FALSE;
 }
 
 static void
 miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
     miDCBufferPtr   pBuffer;
-    int             i;
 
     if (DevHasCursor(pDev))
     {
-        for (i = 0; i < screenInfo.numScreens; i++)
-        {
-            pScreen = screenInfo.screens[i];
-
-            pBuffer = MIDCBUFFER(pDev, pScreen);
-
-            if (pBuffer)
-            {
-                if (pBuffer->pSourceGC) FreeGC(pBuffer->pSourceGC, (GContext) 0);
-                if (pBuffer->pMaskGC) FreeGC(pBuffer->pMaskGC, (GContext) 0);
-                if (pBuffer->pSaveGC) FreeGC(pBuffer->pSaveGC, (GContext) 0);
-                if (pBuffer->pRestoreGC) FreeGC(pBuffer->pRestoreGC, (GContext) 0);
-                if (pBuffer->pMoveGC) FreeGC(pBuffer->pMoveGC, (GContext) 0);
-                if (pBuffer->pPixSourceGC) FreeGC(pBuffer->pPixSourceGC, (GContext) 0);
-                if (pBuffer->pPixMaskGC) FreeGC(pBuffer->pPixMaskGC, (GContext) 0);
-
+        pBuffer = MIDCBUFFER(pDev);
+        tossGC (pBuffer->pSourceGC);
+        tossGC (pBuffer->pMaskGC);
+        tossGC (pBuffer->pSaveGC);
+        tossGC (pBuffer->pRestoreGC);
+        tossGC (pBuffer->pMoveGC);
+        tossGC (pBuffer->pPixSourceGC);
+        tossGC (pBuffer->pPixMaskGC);
+        tossPix (pBuffer->pSave);
+        tossPix (pBuffer->pTemp);
 #ifdef ARGB_CURSOR
-                if (pBuffer->pRootPicture) FreePicture(pBuffer->pRootPicture, 0);
-                if (pBuffer->pTempPicture) FreePicture(pBuffer->pTempPicture, 0);
+#if 0				/* This has been free()d before */
+        tossPict (pScreenPriv->pRootPicture);
 #endif
-
-                if (pBuffer->pSave) (*pScreen->DestroyPixmap)(pBuffer->pSave);
-                if (pBuffer->pTemp) (*pScreen->DestroyPixmap)(pBuffer->pTemp);
-
-                xfree(pBuffer);
-                dixSetPrivate(&pDev->devPrivates, miDCSpriteKey + pScreen->myNum, NULL);
-            }
-        }
+        tossPict (pBuffer->pTempPicture);
+#endif
+        xfree(pBuffer);
+        dixSetPrivate(&pDev->devPrivates, miDCSpriteKey, NULL);
     }
 }
commit ba2ba32e04f9002dbb60f10e174ac63d16e5f507
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 21 09:17:26 2010 +1000

    xserver 1.7.6.902
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index 058ad01..4b020a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,8 +26,8 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.7.6.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2010-04-12"
+AC_INIT([xorg-server], 1.7.6.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2010-04-21"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([dist-bzip2 foreign])
 AM_MAINTAINER_MODE
commit e8fae02f19d6d75ac3edbea2f5af8d250dcfbde3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 14 17:43:22 2010 +1000

    dix: Fix crash in DeliverGrabbedEvents.
    
    If both devices are synchronously grabbed, first with a GrabPointer, then
    with a GrabKeyboard (GrabModeSync on both), sync.other of each device points
    to the grab of the respective other device.
    
    If the keyboard is then thawed through a AllowSome request, the VCK's
    sync.other is reset to NULL. Subsequently, an event on the VCP would crash
    the server when dereferencing sync.other on the VCP.
    
    The check's purpose is to compare if the other device is grabbed by the same
    client, which should be checked by accessing (dev->deviceGrab->grab->resource).
    A check of the server-1.3 sources confirms that.
    
    XTS test case: Xlib13 XAllowEvents 20.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 9ddbb03fa56aa73c3f417d8ee6433e45b94445b3)

diff --git a/dix/events.c b/dix/events.c
index 311c6b6..44c4624 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3980,7 +3980,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 		FreezeThaw(dev, TRUE);
 		if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) &&
 		    (CLIENT_BITS(grab->resource) ==
-		     CLIENT_BITS(dev->deviceGrab.sync.other->resource)))
+		     CLIENT_BITS(dev->deviceGrab.grab->resource)))
 		    dev->deviceGrab.sync.state = FROZEN_NO_EVENT;
 		else
                     dev->deviceGrab.sync.other = grab;
commit aa6a18fdebf444084c27e4a7f3eef7d93f9929b0
Author: Cyril Brulebois <kibi at debian.org>
Date:   Sat Apr 17 01:31:14 2010 +0200

    exa: handle pixmap create/destroy in lower layers
    
    - Pixmaps that are created during a fallback are automatically prepared access.
    - During the fallback accelerated ops are blocked to prevent new/scratch gc's
      from triggering accelerated ops on mapped pixmaps.
    - A few cases of incorrect wrapping (on the top level pointer instead of
      between damage and (w)fb) have been removed.
    
    Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 342f3689d17256c92cbfee079d24501d27aa1153)
    
    Conflicts:
    
    	exa/exa_mixed.c
    
    Debian bug#576816 <http://bugs.debian.org/576816>
    
    Tested-by: Arthur Marsh <arthur.marsh at internode.on.net>
    Signed-off-by: Cyril Brulebois <kibi at debian.org>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/exa/exa.c b/exa/exa.c
index e264d44..b8f0419 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -480,57 +480,6 @@ const GCFuncs exaGCFuncs = {
     exaCopyClip
 };
 
-/*
- * This wrapper exists to allow fbValidateGC to work.
- * Note that we no longer assume newly created pixmaps to be in normal ram.
- * This assumption is certainly not garuanteed with driver allocated pixmaps.
- */
-static PixmapPtr
-exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
-		unsigned usage_hint)
-{
-    PixmapPtr pPixmap;
-    ExaScreenPriv(pScreen);
-
-    /* This swaps between this function and the real upper layer function.
-     * Normally this would swap to the fb layer pointer, this is a very special case.
-     */
-    swap(pExaScr, pScreen, CreatePixmap);
-    pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
-    swap(pExaScr, pScreen, CreatePixmap);
-
-    if (!pPixmap)
-	return NULL;
-
-    /* Note the usage of ExaDoPrepareAccess, this allowed because:
-     * The pixmap is new, so not offscreen in the classic exa case.
-     * 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, EXA_PREPARE_AUX_DEST);
-
-    return pPixmap;
-}
-
-static Bool
-exaDestroyPixmapWithFinish(PixmapPtr pPixmap)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ExaScreenPriv(pScreen);
-    Bool ret;
-
-    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
-    /* This swaps between this function and the real upper layer function.
-     * Normally this would swap to the fb layer pointer, this is a very special case.
-     */
-    swap(pExaScr, pScreen, DestroyPixmap);
-    ret = pScreen->DestroyPixmap(pPixmap);
-    swap(pExaScr, pScreen, DestroyPixmap);
-
-    return ret;
-}
-
 static void
 exaValidateGC(GCPtr pGC,
 		unsigned long changes,
@@ -542,20 +491,9 @@ exaValidateGC(GCPtr pGC,
 
     ScreenPtr pScreen = pDrawable->pScreen;
     ExaScreenPriv(pScreen);
-    CreatePixmapProcPtr old_ptr = NULL;
-    DestroyPixmapProcPtr old_ptr2 = NULL;
+    ExaGCPriv(pGC);
     PixmapPtr pTile = NULL;
-    EXA_GC_PROLOGUE(pGC);
-
-    /* save the "fb" pointer. */
-    old_ptr = pExaScr->SavedCreatePixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
-
-    /* save the "fb" pointer. */
-    old_ptr2 = pExaScr->SavedDestroyPixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
+    Bool finish_current_tile = FALSE;
 
     /* Either of these conditions is enough to trigger access to a tile pixmap. */
     /* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */
@@ -569,8 +507,10 @@ exaValidateGC(GCPtr pGC,
 	 */
 	if (pTile && pTile->drawable.depth != pDrawable->depth && !(changes & GCTile)) {
 	    PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
-	    if (pRotatedTile->drawable.depth == pDrawable->depth)
+	    if (pRotatedTile && pRotatedTile->drawable.depth == pDrawable->depth)
 		pTile = pRotatedTile;
+	    else
+		finish_current_tile = TRUE; /* CreatePixmap will be called. */
 	}
     }
 
@@ -579,42 +519,39 @@ exaValidateGC(GCPtr pGC,
     if (pTile)
 	exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
 
+    /* Calls to Create/DestroyPixmap have to be identified as special. */
+    pExaScr->fallback_counter++;
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    swap(pExaGC, pGC, funcs);
+    pExaScr->fallback_counter--;
 
     if (pTile)
 	exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+    if (finish_current_tile && pGC->tile.pixmap)
+	exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST);
     if (pGC->stipple)
-        exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, CreatePixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedCreatePixmap = old_ptr;
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, DestroyPixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedDestroyPixmap = old_ptr2;
-
-    EXA_GC_EPILOGUE(pGC);
+	exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
 }
 
 /* Is exaPrepareAccessGC() needed? */
 static void
 exaDestroyGC(GCPtr pGC)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->DestroyGC)(pGC);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
 exaChangeGC (GCPtr pGC,
 		unsigned long mask)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ChangeGC) (pGC, mask);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
@@ -622,9 +559,10 @@ exaCopyGC (GCPtr pGCSrc,
 	      unsigned long mask,
 	      GCPtr	 pGCDst)
 {
-    EXA_GC_PROLOGUE (pGCDst);
+    ExaGCPriv(pGCDst);
+    swap(pExaGC, pGCDst, funcs);
     (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    EXA_GC_EPILOGUE (pGCDst);
+    swap(pExaGC, pGCDst, funcs);
 }
 
 static void
@@ -633,25 +571,28 @@ exaChangeClip (GCPtr pGC,
 		pointer pvalue,
 		int nrects)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 static void
 exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
 {
-    EXA_GC_PROLOGUE (pGCDst);
+    ExaGCPriv(pGCDst);
+    swap(pExaGC, pGCDst, funcs);
     (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
-    EXA_GC_EPILOGUE (pGCDst);
+    swap(pExaGC, pGCDst, funcs);
 }
 
 static void
 exaDestroyClip(GCPtr pGC)
 {
-    EXA_GC_PROLOGUE (pGC);
+    ExaGCPriv(pGC);
+    swap(pExaGC, pGC, funcs);
     (*pGC->funcs->DestroyClip)(pGC);
-    EXA_GC_EPILOGUE (pGC);
+    swap(pExaGC, pGC, funcs);
 }
 
 /**
@@ -682,18 +623,6 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     Bool ret;
     ScreenPtr pScreen = pWin->drawable.pScreen;
     ExaScreenPriv(pScreen);
-    CreatePixmapProcPtr old_ptr = NULL;
-    DestroyPixmapProcPtr old_ptr2 = NULL;
-
-    /* save the "fb" pointer. */
-    old_ptr = pExaScr->SavedCreatePixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
-
-    /* save the "fb" pointer. */
-    old_ptr2 = pExaScr->SavedDestroyPixmap;
-    /* create a new upper layer pointer. */
-    wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
 
     if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
 	exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
@@ -701,25 +630,17 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
     if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
 	exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
 
+    pExaScr->fallback_counter++;
     swap(pExaScr, pScreen, ChangeWindowAttributes);
     ret = pScreen->ChangeWindowAttributes(pWin, mask);
     swap(pExaScr, pScreen, ChangeWindowAttributes);
+    pExaScr->fallback_counter--;
 
     if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) 
 	exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
     if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
 	exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
 
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, CreatePixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedCreatePixmap = old_ptr;
-
-    /* switch back to the normal upper layer. */
-    unwrap(pExaScr, pScreen, DestroyPixmap);
-    /* restore copy of fb layer pointer. */
-    pExaScr->SavedDestroyPixmap = old_ptr2;
-
     return ret;
 }
 
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 7e2dd70..4f94ae8 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -51,7 +51,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
     int		    partX1, partX2;
     int		    off_x, off_y;
 
-    if (pExaScr->swappedOut ||
+    if (pExaScr->fallback_counter ||
+	pExaScr->swappedOut ||
 	pGC->fillStyle != FillSolid ||
 	pExaPixmap->accel_blocked)
     {
@@ -153,7 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
     int bpp = pDrawable->bitsPerPixel;
     Bool ret = TRUE;
 
-    if (pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
 	return FALSE;
 
     /* Don't bother with under 8bpp, XYPixmaps. */
@@ -568,7 +569,8 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
 {
     ExaScreenPriv(pDstDrawable->pScreen);
 
-    if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)
+    if (pExaScr->fallback_counter ||
+	    (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
 	return;
 
     if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
@@ -590,7 +592,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 {
     ExaScreenPriv (pDstDrawable->pScreen);
 
-    if (pExaScr->swappedOut) {
+    if (pExaScr->fallback_counter || pExaScr->swappedOut) {
         return  ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
                                  srcx, srcy, width, height, dstx, dsty);
     }
@@ -604,13 +606,14 @@ static void
 exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	     DDXPointPtr ppt)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     int i;
     xRectangle *prect;
 
     /* If we can't reuse the current GC as is, don't bother accelerating the
      * points.
      */
-    if (pGC->fillStyle != FillSolid) {
+    if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
 	ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
 	return;
     }
@@ -639,10 +642,16 @@ static void
 exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 	     DDXPointPtr ppt)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     xRectangle *prect;
     int x1, x2, y1, y2;
     int i;
 
+    if (pExaScr->fallback_counter) {
+	ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+	return;
+    }
+
     /* Don't try to do wide lines or non-solid fill style. */
     if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
 	pGC->fillStyle != FillSolid) {
@@ -700,12 +709,13 @@ static void
 exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
 		xSegment *pSeg)
 {
+    ExaScreenPriv (pDrawable->pScreen);
     xRectangle *prect;
     int i;
 
     /* Don't try to do wide lines or non-solid fill style. */
-    if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
-	pGC->fillStyle != FillSolid)
+    if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
+	pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid)
     {
 	ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
 	return;
@@ -782,7 +792,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
 
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
 
-    if (pExaScr->swappedOut || pExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaScr->swappedOut ||
+	    pExaPixmap->accel_blocked)
     {
 	goto fallback;
     }
@@ -956,12 +967,18 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 			  -pPixmap->screen_x, -pPixmap->screen_y);
 #endif
 
+    if (pExaScr->fallback_counter) {
+	pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+	goto fallback;
+    }
+
     pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
     miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
 		  NULL,
 		  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
     pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
 
+fallback:
     REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
 
     if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
@@ -984,7 +1001,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
     REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
 
-    if (pExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
 	goto out;
 
     if (pExaScr->do_migration) {
@@ -1080,7 +1097,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
     pPixmap = exaGetDrawablePixmap (pDrawable);
     pExaPixmap = ExaGetPixmapPriv (pPixmap);
 
-    if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
+    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
+	    pTileExaPixmap->accel_blocked)
 	return FALSE;
 
     if (pExaScr->do_migration) {
@@ -1238,7 +1256,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
     int xoff, yoff;
     Bool ok;
 
-    if (pExaScr->swappedOut)
+    if (pExaScr->fallback_counter || pExaScr->swappedOut)
 	goto fallback;
 
     exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
diff --git a/exa/exa_classic.c b/exa/exa_classic.c
index 1eff570..12f3987 100644
--- a/exa/exa_classic.c
+++ b/exa/exa_classic.c
@@ -137,6 +137,10 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
     exaSetAccelBlock(pExaScr, pExaPixmap,
                      w, h, bpp);
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -216,6 +220,10 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaPixmap->area)
 	{
 	    DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
diff --git a/exa/exa_driver.c b/exa/exa_driver.c
index a9165a1..f55c300 100644
--- a/exa/exa_driver.c
+++ b/exa/exa_driver.c
@@ -115,6 +115,10 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
     exaSetAccelBlock(pExaScr, pExaPixmap,
                      w, h, bpp);
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -187,6 +191,10 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaPixmap->driverPriv)
 	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
 	pExaPixmap->driverPriv = NULL;
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index ff02f27..47adad7 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -97,6 +97,10 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     } else
 	pExaPixmap->offscreen = FALSE;
 
+    /* During a fallback we must prepare access. */
+    if (pExaScr->fallback_counter)
+	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+
     return pPixmap;
 }
 
@@ -188,6 +192,10 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
     {
 	ExaPixmapPriv (pPixmap);
 
+	/* During a fallback we must finish access, but we don't know the index. */
+	if (pExaScr->fallback_counter)
+	    exaFinishAccess(&pPixmap->drawable, -1);
+
 	if (pExaPixmap->driverPriv)
 	    pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
 	pExaPixmap->driverPriv = NULL;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 1aec8e9..7d035d4 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -197,6 +197,7 @@ typedef struct {
 
     /* Holds information on fallbacks that cannot be relayed otherwise. */
     unsigned int fallback_flags;
+    unsigned int fallback_counter;
 
     ExaGlyphCacheRec             glyphCaches[EXA_NUM_GLYPH_CACHES];
 } ExaScreenPrivRec, *ExaScreenPrivPtr;
@@ -240,13 +241,21 @@ extern DevPrivateKey exaGCPrivateKey;
     real->mem = tmp; \
 }
 
-#define EXA_GC_PROLOGUE(_gc_) \
+#define EXA_PRE_FALLBACK(_screen_) \
+    ExaScreenPriv(_screen_); \
+    pExaScr->fallback_counter++;
+
+#define EXA_POST_FALLBACK(_screen_) \
+    pExaScr->fallback_counter--;
+
+#define EXA_PRE_FALLBACK_GC(_gc_) \
+    ExaScreenPriv(_gc_->pScreen); \
     ExaGCPriv(_gc_); \
-    swap(pExaGC, _gc_, funcs); \
+    pExaScr->fallback_counter++; \
     swap(pExaGC, _gc_, ops);
 
-#define EXA_GC_EPILOGUE(_gc_) \
-    swap(pExaGC, _gc_, funcs); \
+#define EXA_POST_FALLBACK_GC(_gc_) \
+    pExaScr->fallback_counter--; \
     swap(pExaGC, _gc_, ops);
 
 /** Align an offset to an arbitrary alignment */
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index c8f0172..9bc765a 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -74,26 +74,26 @@ void
 ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
 		   DDXPointPtr ppt, int *pwidth, int fSorted)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     exaPrepareAccessGC (pGC);
     pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -103,9 +103,8 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 {
     PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
     ExaPixmapPriv(pPixmap);
-    ExaScreenPriv(pDrawable->pScreen);
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
 	exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
@@ -116,7 +115,7 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 				    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);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -124,7 +123,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
 	     BoxPtr	pbox, int nbox, int dx, int dy, Bool	reverse, 
 	     Bool upsidedown, Pixel bitplane, void *closure)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -137,7 +136,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
     }
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 RegionPtr
@@ -146,7 +145,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 {
     RegionPtr ret;
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -154,7 +153,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 
     return ret;
 }
@@ -166,7 +165,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 {
     RegionPtr ret;
 
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
     exaPrepareAccess (pDst, EXA_PREPARE_DEST);
@@ -175,7 +174,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		       bitPlane);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 
     return ret;
 }
@@ -184,19 +183,19 @@ void
 ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
 		  int mode, int npt, DDXPointPtr ppt)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
 		  pDrawable, exaDrawableLocation(pDrawable),
 		  pGC->lineWidth, mode, npt));
@@ -206,14 +205,14 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
 		    int nsegInit, xSegment *pSegInit)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
 
@@ -222,14 +221,14 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
 		int narcs, xArc *pArcs)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -237,14 +236,14 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
 ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
 		     int nrect, xRectangle *prect)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
 
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -252,7 +251,7 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -260,7 +259,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		      int x, int y, unsigned int nglyph,
 		      CharInfoPtr *ppci, pointer pglyphBase)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -268,7 +267,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -276,7 +275,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 		     int x, int y, unsigned int nglyph,
 		     CharInfoPtr *ppci, pointer pglyphBase)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
 		  exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
     exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
@@ -284,7 +283,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
     pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
     exaFinishAccessGC (pGC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -292,7 +291,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
 		   DrawablePtr pDrawable,
 		   int w, int h, int x, int y)
 {
-    EXA_GC_PROLOGUE(pGC);
+    EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  exaDrawableLocation(&pBitmap->drawable),
 		  exaDrawableLocation(pDrawable)));
@@ -303,7 +302,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
     exaFinishAccessGC (pGC);
     exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-    EXA_GC_EPILOGUE(pGC);
+    EXA_POST_FALLBACK_GC(pGC);
 }
 
 void
@@ -311,7 +310,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 {
     DrawablePtr pDrawable = &pWin->drawable;
     ScreenPtr pScreen = pDrawable->pScreen;
-    ExaScreenPriv(pScreen);
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p\n", pWin));
 
     /* being both src and dest, src is safest. */
@@ -320,6 +319,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
     swap(pExaScr, pScreen, CopyWindow);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -328,8 +328,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 {
     ScreenPtr pScreen = pDrawable->pScreen;
     PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
-    ExaScreenPriv(pScreen);
-
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
 
@@ -355,6 +354,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
     pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
     swap(pExaScr, pScreen, GetImage);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -366,14 +366,15 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
 		 char *pdstStart)
 {
     ScreenPtr pScreen = pDrawable->pScreen;
-    ExaScreenPriv(pScreen);
 
+    EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
     swap(pExaScr, pScreen, GetSpans);
     pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
     swap(pExaScr, pScreen, GetSpans);
     exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -394,9 +395,9 @@ ExaCheckComposite (CARD8      op,
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    ExaScreenPriv(pScreen);
     RegionRec region;
     int xoff, yoff;
+    EXA_PRE_FALLBACK(pScreen);
 
     REGION_NULL(pScreen, &region);
 
@@ -471,6 +472,7 @@ skip:
 	exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
 
     REGION_UNINIT(pScreen, &region);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 void
@@ -484,7 +486,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    ExaScreenPriv(pScreen);
+    EXA_PRE_FALLBACK(pScreen);
 
     EXA_FALLBACK(("to pict %p (%c)\n",
 		  exaDrawableLocation(pPicture->pDrawable)));
@@ -495,6 +497,7 @@ ExaCheckAddTraps (PicturePtr	pPicture,
     swap(pExaScr, ps, AddTraps);
 #endif /* RENDER */
     exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+    EXA_POST_FALLBACK(pScreen);
 }
 
 /**
commit acbcb77bf6acf513660b4a9df8d20a5c04f1c865
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Apr 6 11:51:53 2010 +0200

    XGE: don't register an extension event
    
    The GenericEvent is a core event, we never send an extension event, so
    don't reserve an id for one.
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit fc5d76740851725e3788c68e14474a012a205892)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/geext.c b/Xext/geext.c
index 2ba0ca8..f0a3d87 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -36,11 +36,8 @@
 
 #define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
 
-int GEEventBase;
-int GEErrorBase;
 static int GEClientPrivateKeyIndex;
 DevPrivateKey GEClientPrivateKey = &GEClientPrivateKeyIndex;
-int GEEventType; /* The opcode for all GenericEvents will have. */
 
 int RT_GECLIENT  = 0;
 
@@ -178,10 +175,6 @@ GEResetProc(ExtensionEntry *extEntry)
 {
     DeleteCallback(&ClientStateCallback, GEClientCallback, 0);
     EventSwapVector[GenericEvent] = NotImplemented;
-
-    GEEventBase = 0;
-    GEErrorBase = 0;
-    GEEventType = 0;
 }
 
 /*  Calls the registered event swap function for the extension.
@@ -225,14 +218,10 @@ GEExtensionInit(void)
     }
 
     if((extEntry = AddExtension(GE_NAME,
-                        GENumberEvents, GENumberErrors,
+                        0, GENumberErrors,
                         ProcGEDispatch, SProcGEDispatch,
                         GEResetProc, StandardMinorOpcode)) != 0)
     {
-        GEEventBase = extEntry->eventBase;
-        GEErrorBase = extEntry->errorBase;
-        GEEventType = GEEventBase;
-
         memset(GEExtensions, 0, sizeof(GEExtensions));
 
         EventSwapVector[GenericEvent] = (EventSwapPtr) SGEGenericEvent;
diff --git a/Xext/geint.h b/Xext/geint.h
index 881d306..10a33ce 100644
--- a/Xext/geint.h
+++ b/Xext/geint.h
@@ -37,9 +37,6 @@
 #include "extnsionst.h"
 #include <X11/extensions/geproto.h>
 
-extern _X_EXPORT int GEEventType;
-extern _X_EXPORT int GEEventBase;
-extern _X_EXPORT int GEErrorBase;
 extern _X_EXPORT DevPrivateKey GEClientPrivateKey;
 
 typedef struct _GEClientInfo {
commit c52b9e143da294e787d93ddbd7b9b620a3a892e2
Author: Julien Cristau <jcristau at debian.org>
Date:   Tue Apr 13 22:28:36 2010 +0200

    vfb: add a name and type to the pointer and keyboard
    
    Fixes a crash in XIQueryDevice which calls strlen on a NULL pointer.
    
     #0  strlen () at ../sysdeps/x86_64/strlen.S:31
     #1  0x00000000004c16ed in SizeDeviceInfo (dev=0x969bd0)
         at ../../Xi/xiquerydevice.c:204
     #2  0x00000000004c1a01 in ProcXIQueryDevice (client=0xa57510)
         at ../../Xi/xiquerydevice.c:98
    
    Debian bug#575905 <http://bugs.debian.org/575905>
    
    Reported-by: "Bernhard R. Link" <brlink at debian.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 0e7703f9b1927328954a2fc87aac6be244819329)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/vfb/InitInput.c b/hw/vfb/InitInput.c
index 7f2d56f..b795047 100644
--- a/hw/vfb/InitInput.c
+++ b/hw/vfb/InitInput.c
@@ -43,6 +43,7 @@ from The Open Group.
 #include <X11/keysym.h>
 #include "xserver-properties.h"
 #include "exevents.h"
+#include "extinit.h"
 
 Bool
 LegalModifier(unsigned int key, DeviceIntPtr pDev)
@@ -136,9 +137,14 @@ void
 InitInput(int argc, char *argv[])
 {
     DeviceIntPtr p, k;
+    Atom xiclass;
     p = AddInputDevice(serverClient, vfbMouseProc, TRUE);
     k = AddInputDevice(serverClient, vfbKeybdProc, TRUE);
     RegisterPointerDevice(p);
+    xiclass = MakeAtom(XI_MOUSE, sizeof(XI_MOUSE) - 1, TRUE);
+    AssignTypeAndName(p, xiclass, "Xvfb mouse");
     RegisterKeyboardDevice(k);
+    xiclass = MakeAtom(XI_KEYBOARD, sizeof(XI_KEYBOARD) - 1, TRUE);
+    AssignTypeAndName(k, xiclass, "Xvfb keyboard");
     (void)mieqInit();
 }
commit 9a9a19ac4ecdab0e2602d70354145545de37f3c5
Author: Pierre-Loup A. Griffais <pgriffais at nvidia.com>
Date:   Wed Apr 7 13:52:47 2010 -0700

    mi: don't thrash resources when displaying the software cursor across screens
    
    This changes the DC layer to maintain a persistent set of GCs/pixmaps/pictures
    for each pScreen instead of failing to thrash between them when changing
    screens.
    
    Signed-off-by: Pierre-Loup A. Griffais <pgriffais at nvidia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 00b8b7ad61b6f818271fb4d1e383113170309d72)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/midispcur.c b/mi/midispcur.c
index 3fb7e02..3a31b74 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -59,9 +59,9 @@ static DevPrivateKey miDCScreenKey = &miDCScreenKeyIndex;
 
 static Bool	miDCCloseScreen(int index, ScreenPtr pScreen);
 
-/* per device private data */
-static int miDCSpriteKeyIndex;
-static DevPrivateKey miDCSpriteKey = &miDCSpriteKeyIndex;
+/* per device per-screen private data */
+static int miDCSpriteKeyIndex[MAXSCREENS];
+static DevPrivateKey miDCSpriteKey = miDCSpriteKeyIndex;
 
 typedef struct {
     GCPtr	    pSourceGC, pMaskGC;
@@ -75,10 +75,10 @@ typedef struct {
 #endif
 } miDCBufferRec, *miDCBufferPtr;
 
-#define MIDCBUFFER(dev) \
+#define MIDCBUFFER(dev, screen) \
  ((DevHasCursor(dev)) ? \
-  (miDCBufferPtr)dixLookupPrivate(&dev->devPrivates, miDCSpriteKey) : \
-  (miDCBufferPtr)dixLookupPrivate(&dev->u.master->devPrivates, miDCSpriteKey))
+  (miDCBufferPtr)dixLookupPrivate(&dev->devPrivates, miDCSpriteKey + (screen)->myNum) : \
+  (miDCBufferPtr)dixLookupPrivate(&dev->u.master->devPrivates, miDCSpriteKey + (screen)->myNum))
 
 /* 
  * The core pointer buffer will point to the index of the virtual core pointer
@@ -158,10 +158,6 @@ miDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
     return TRUE;
 }
 
-#define tossGC(gc)  (gc ? FreeGC (gc, (GContext) 0) : 0)
-#define tossPix(pix)	(pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
-#define tossPict(pict)	(pict ? FreePicture (pict, 0) : 0)
-
 static Bool
 miDCCloseScreen (int index, ScreenPtr pScreen)
 {
@@ -183,7 +179,6 @@ miDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 }
 
 #ifdef ARGB_CURSOR
-#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
 
 static VisualPtr
 miDCGetWindowVisual (WindowPtr pWin)
@@ -415,12 +410,8 @@ miDCPutBits (
     (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
 }
 
-#define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
-
 static GCPtr
-miDCMakeGC(
-    GCPtr	*ppGC,
-    WindowPtr	pWin)
+miDCMakeGC(WindowPtr pWin)
 {
     GCPtr pGC;
     int   status;
@@ -431,7 +422,6 @@ miDCMakeGC(
     pGC = CreateGC((DrawablePtr)pWin,
 		   GCSubwindowMode|GCGraphicsExposures, gcvals, &status,
 		   (XID)0, serverClient);
-    *ppGC = pGC;
     return pGC;
 }
 
@@ -456,22 +446,11 @@ miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = MIDCBUFFER(pDev);
+    pBuffer = MIDCBUFFER(pDev, pScreen);
 
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
-        /* see comment in miDCPutUpCursor */
-        if (pBuffer->pRootPicture && 
-                pBuffer->pRootPicture->pDrawable &&
-                pBuffer->pRootPicture->pDrawable->pScreen != pScreen)
-        {
-            tossPict(pBuffer->pRootPicture);
-            pBuffer->pRootPicture = NULL;
-        }
-
-	if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
-	    return FALSE;
 	CompositePicture (PictOpOver,
 			  pPriv->pPicture,
 			  NULL,
@@ -484,33 +463,6 @@ miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     else
 #endif
     {
-        /**
-         * XXX: Before MPX, the sourceGC and maskGC were attached to the
-         * screen, and would switch as the screen switches.  With mpx we have
-         * the GC's attached to the device now, so each time we switch screen
-         * we need to make sure the GC's are allocated on the new screen.
-         * This is ... not optimal. (whot)
-         */
-        if (pBuffer->pSourceGC && pScreen != pBuffer->pSourceGC->pScreen)
-        {
-            tossGC(pBuffer->pSourceGC);
-            pBuffer->pSourceGC = NULL;
-        }
-
-        if (pBuffer->pMaskGC && pScreen != pBuffer->pMaskGC->pScreen)
-        {
-            tossGC(pBuffer->pMaskGC);
-            pBuffer->pMaskGC = NULL;
-        }
-
-	if (!EnsureGC(pBuffer->pSourceGC, pWin))
-	    return FALSE;
-	if (!EnsureGC(pBuffer->pMaskGC, pWin))
-	{
-	    FreeGC (pBuffer->pSourceGC, (GContext) 0);
-	    pBuffer->pSourceGC = 0;
-	    return FALSE;
-	}
 	miDCPutBits ((DrawablePtr)pWin, pPriv,
 		     pBuffer->pSourceGC, pBuffer->pMaskGC,
 		     x, y, pCursor->bits->width, pCursor->bits->height,
@@ -531,7 +483,7 @@ miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev);
+    pBuffer = MIDCBUFFER(pDev, pScreen);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -544,14 +496,7 @@ miDCSaveUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 	if (!pSave)
 	    return FALSE;
     }
-    /* see comment in miDCPutUpCursor */
-    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
-    {
-        tossGC(pBuffer->pSaveGC);
-        pBuffer->pSaveGC = NULL;
-    }
-    if (!EnsureGC(pBuffer->pSaveGC, pWin))
-	return FALSE;
+
     pGC = pBuffer->pSaveGC;
     if (pSave->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pSave, pGC);
@@ -572,20 +517,13 @@ miDCRestoreUnderCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev);
+    pBuffer = MIDCBUFFER(pDev, pScreen);
     pSave = pBuffer->pSave;
 
     pWin = WindowTable[pScreen->myNum];
     if (!pSave)
 	return FALSE;
-    /* see comment in miDCPutUpCursor */
-    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
-    {
-        tossGC(pBuffer->pRestoreGC);
-        pBuffer->pRestoreGC = NULL;
-    }
-    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
-	return FALSE;
+
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -607,7 +545,7 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
-    pBuffer = MIDCBUFFER(pDev);
+    pBuffer = MIDCBUFFER(pDev, pScreen);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -616,14 +554,7 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
      */
     if (!pSave)
 	return FALSE;
-    /* see comment in miDCPutUpCursor */
-    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
-    {
-        tossGC(pBuffer->pRestoreGC);
-        pBuffer->pRestoreGC = NULL;
-    }
-    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
-	return FALSE;
+
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -662,14 +593,7 @@ miDCChangeSave (DeviceIntPtr pDev, ScreenPtr pScreen,
 	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
 			       0, sourcey, -dx, copyh, x + dx, desty);
     }
-    /* see comment in miDCPutUpCursor */
-    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
-    {
-        tossGC(pBuffer->pSaveGC);
-        pBuffer->pSaveGC = NULL;
-    }
-    if (!EnsureGC(pBuffer->pSaveGC, pWin))
-	return FALSE;
+
     pGC = pBuffer->pSaveGC;
     if (pSave->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pSave, pGC);
@@ -766,7 +690,7 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     pScreenPriv = (miDCScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						  miDCScreenKey);
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = MIDCBUFFER(pDev);
+    pBuffer = MIDCBUFFER(pDev, pScreen);
 
     pTemp = pBuffer->pTemp;
     if (!pTemp ||
@@ -809,17 +733,9 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
-        /* see comment in miDCPutUpCursor */
-        if (pBuffer->pTempPicture && 
-                pBuffer->pTempPicture->pDrawable &&
-                pBuffer->pTempPicture->pDrawable->pScreen != pScreen)
-        {
-            tossPict(pBuffer->pTempPicture);
-            pBuffer->pTempPicture = NULL;
-        }
+	if (!pBuffer->pTempPicture)
+            miDCMakePicture(&pBuffer->pTempPicture, &pTemp->drawable, pWin);
 
-	if (!EnsurePicture(pBuffer->pTempPicture, &pTemp->drawable, pWin))
-	    return FALSE;
 	CompositePicture (PictOpOver,
 			  pPriv->pPicture,
 			  NULL,
@@ -832,38 +748,12 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     else
 #endif
     {
-	if (!pBuffer->pPixSourceGC)
-	{
-	    pBuffer->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
-		GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
-	    if (!pBuffer->pPixSourceGC)
-		return FALSE;
-	}
-	if (!pBuffer->pPixMaskGC)
-	{
-	    pBuffer->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
-		GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
-	    if (!pBuffer->pPixMaskGC)
-		return FALSE;
-	}
 	miDCPutBits ((DrawablePtr)pTemp, pPriv,
 		     pBuffer->pPixSourceGC, pBuffer->pPixMaskGC,
 		     dx, dy, pCursor->bits->width, pCursor->bits->height,
 		     source, mask);
     }
 
-    /* see comment in miDCPutUpCursor */
-    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
-    {
-        tossGC(pBuffer->pRestoreGC);
-        pBuffer->pRestoreGC = NULL;
-    }
-    /*
-     * copy the temporary pixmap onto the screen
-     */
-
-    if (!EnsureGC(pBuffer->pRestoreGC, pWin))
-	return FALSE;
     pGC = pBuffer->pRestoreGC;
     if (pWin->drawable.serialNumber != pGC->serialNumber)
 	ValidateGC ((DrawablePtr) pWin, pGC);
@@ -877,51 +767,113 @@ miDCMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
 static Bool
 miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
-    miDCBufferPtr pBuffer;
-
-    pBuffer = xalloc(sizeof(miDCBufferRec));
-    dixSetPrivate(&pDev->devPrivates, miDCSpriteKey, pBuffer);
-
-    pBuffer->pSourceGC =
-        pBuffer->pMaskGC =
-        pBuffer->pSaveGC =
-        pBuffer->pRestoreGC =
-        pBuffer->pMoveGC =
-        pBuffer->pPixSourceGC =
-        pBuffer->pPixMaskGC = NULL;
+    miDCBufferPtr   pBuffer;
+    WindowPtr       pWin;
+    XID             gcval = FALSE;
+    int             status;
+    int             i;
+
+    if (!DevHasCursor(pDev))
+        return TRUE;
+
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+        pScreen = screenInfo.screens[i];
+
+        pBuffer = xalloc(sizeof(miDCBufferRec));
+        if (!pBuffer)
+            goto failure;
+
+        dixSetPrivate(&pDev->devPrivates, miDCSpriteKey + pScreen->myNum, pBuffer);
+        pWin = WindowTable[pScreen->myNum];
+
+        pBuffer->pSourceGC = miDCMakeGC(pWin);
+        if (!pBuffer->pSourceGC)
+            goto failure;
+
+        pBuffer->pMaskGC = miDCMakeGC(pWin);
+        if (!pBuffer->pMaskGC)
+            goto failure;
+
+        pBuffer->pSaveGC = miDCMakeGC(pWin);
+        if (!pBuffer->pSaveGC)
+            goto failure;
+
+        pBuffer->pRestoreGC = miDCMakeGC(pWin);
+        if (!pBuffer->pRestoreGC)
+            goto failure;
+
+        pBuffer->pMoveGC = CreateGC ((DrawablePtr)pWin,
+            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
+        if (!pBuffer->pMoveGC)
+            goto failure;
+
+        pBuffer->pPixSourceGC = CreateGC ((DrawablePtr)pWin,
+            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
+        if (!pBuffer->pPixSourceGC)
+            goto failure;
+
+        pBuffer->pPixMaskGC = CreateGC ((DrawablePtr)pWin,
+            GCGraphicsExposures, &gcval, &status, (XID)0, serverClient);
+        if (!pBuffer->pPixMaskGC)
+            goto failure;
+
 #ifdef ARGB_CURSOR
-    pBuffer->pRootPicture = NULL;
-    pBuffer->pTempPicture = NULL;
+        miDCMakePicture(&pBuffer->pRootPicture, &pWin->drawable, pWin);
+        if (!pBuffer->pRootPicture)
+            goto failure;
+
+        pBuffer->pTempPicture = NULL;
 #endif
-    pBuffer->pSave = pBuffer->pTemp = NULL;
+
+        // these get (re)allocated lazily depending on the cursor size
+        pBuffer->pSave = pBuffer->pTemp = NULL;
+    }
 
     return TRUE;
+
+failure:
+
+    miDCDeviceCleanup(pDev, pScreen);
+
+    return FALSE;
 }
 
 static void
 miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
     miDCBufferPtr   pBuffer;
+    int             i;
 
     if (DevHasCursor(pDev))
     {
-        pBuffer = MIDCBUFFER(pDev);
-        tossGC (pBuffer->pSourceGC);
-        tossGC (pBuffer->pMaskGC);
-        tossGC (pBuffer->pSaveGC);
-        tossGC (pBuffer->pRestoreGC);
-        tossGC (pBuffer->pMoveGC);
-        tossGC (pBuffer->pPixSourceGC);
-        tossGC (pBuffer->pPixMaskGC);
-        tossPix (pBuffer->pSave);
-        tossPix (pBuffer->pTemp);
+        for (i = 0; i < screenInfo.numScreens; i++)
+        {
+            pScreen = screenInfo.screens[i];
+
+            pBuffer = MIDCBUFFER(pDev, pScreen);
+
+            if (pBuffer)
+            {
+                if (pBuffer->pSourceGC) FreeGC(pBuffer->pSourceGC, (GContext) 0);
+                if (pBuffer->pMaskGC) FreeGC(pBuffer->pMaskGC, (GContext) 0);
+                if (pBuffer->pSaveGC) FreeGC(pBuffer->pSaveGC, (GContext) 0);
+                if (pBuffer->pRestoreGC) FreeGC(pBuffer->pRestoreGC, (GContext) 0);
+                if (pBuffer->pMoveGC) FreeGC(pBuffer->pMoveGC, (GContext) 0);
+                if (pBuffer->pPixSourceGC) FreeGC(pBuffer->pPixSourceGC, (GContext) 0);
+                if (pBuffer->pPixMaskGC) FreeGC(pBuffer->pPixMaskGC, (GContext) 0);
+
 #ifdef ARGB_CURSOR
-#if 0				/* This has been free()d before */
-        tossPict (pScreenPriv->pRootPicture);
-#endif 
-        tossPict (pBuffer->pTempPicture);
+                if (pBuffer->pRootPicture) FreePicture(pBuffer->pRootPicture, 0);
+                if (pBuffer->pTempPicture) FreePicture(pBuffer->pTempPicture, 0);
 #endif
-        xfree(pBuffer);
-        dixSetPrivate(&pDev->devPrivates, miDCSpriteKey, NULL);
+
+                if (pBuffer->pSave) (*pScreen->DestroyPixmap)(pBuffer->pSave);
+                if (pBuffer->pTemp) (*pScreen->DestroyPixmap)(pBuffer->pTemp);
+
+                xfree(pBuffer);
+                dixSetPrivate(&pDev->devPrivates, miDCSpriteKey + pScreen->myNum, NULL);
+            }
+        }
     }
 }
commit ff02e0e4a2f33131520bc3bf7d6621a301c5296d
Author: Tim Yamin <plasm at roo.me.uk>
Date:   Mon Mar 8 12:45:15 2010 +1000

    dix: fix cursor screen check for xinerama setups.
    
    The de-duplication of CheckPhysLimits 942eae6868b8b0f343b6a added a
    condition that is invalid for a Xinerama setup. pScreen is invalid for the
    Xinerama case, so comparing it to anything is a bad idea.
    
    Signed-off-by: Tim Yamin <plasm at roo.me.uk>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5f31e2196179f8db3170d65a17d8ad40da1acb0d)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 732740e..311c6b6 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -738,7 +738,11 @@ CheckPhysLimits(
 	    new.y = pSprite->physLimits.y2 - 1;
     if (pSprite->hotShape)
 	ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y);
-    if ((pScreen != pSprite->hotPhys.pScreen) ||
+    if ((
+#ifdef PANORAMIX
+            noPanoramiXExtension &&
+#endif
+            (pScreen != pSprite->hotPhys.pScreen)) ||
 	(new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y))
     {
 #ifdef PANORAMIX


More information about the Xquartz-changes mailing list