[Xquartz-changes] xserver: Branch 'server-1.8-branch' - 20 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Tue Apr 27 02:19:44 PDT 2010


 configure.ac                   |    4 -
 dix/events.c                   |    8 ++-
 exa/exa_accel.c                |    2 
 glx/glxcmds.c                  |   39 ++++++++++-----
 glx/glxext.c                   |   11 ++++
 glx/glxscreens.c               |   28 -----------
 glx/glxscreens.h               |    1 
 hw/vfb/InitInput.c             |    6 ++
 hw/vfb/InitOutput.c            |    2 
 hw/xfree86/common/xf86Xinput.c |    8 +--
 include/input.h                |    8 +--
 include/xkbsrv.h               |    1 
 mi/midispcur.c                 |    6 +-
 mi/misprite.c                  |   27 ++---------
 xkb/ddxDevBtn.c                |   16 +-----
 xkb/ddxFakeMtn.c               |  100 +++++++++--------------------------------
 xkb/xkbActions.c               |    4 -
 17 files changed, 100 insertions(+), 171 deletions(-)

New commits:
commit c394b17266301d363a9e234f58f8015f74e01307
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 27 17:53:22 2010 +1000

    Revert "DRI2: Track DRI2 drawables as resources, not privates"
    
    This change breaks GLX compositing managers.
    See Bug 27767 <https://bugs.freedesktop.org/show_bug.cgi?id=27767>
    
    This reverts commit 0c499f2ee4ae2b7dc424009abb336fc81a8a2853.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index bde519a..edd29b0 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -105,6 +105,11 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
     
     (*core->destroyDrawable)(private->driDrawable);
 
+    /* If the X window was destroyed, the dri DestroyWindow hook will
+     * aready have taken care of this, so only call if pDraw isn't NULL. */
+    if (drawable->pDraw != NULL)
+	DRI2DestroyDrawable(drawable->pDraw);
+
     __glXDrawableRelease(drawable);
 
     xfree(private);
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 63bef28..48618e1 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,14 +45,15 @@
 
 #include "xf86.h"
 
-static int           dri2ScreenPrivateKeyIndex;
+static int dri2ScreenPrivateKeyIndex;
 static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
-static RESTYPE       dri2DrawableRes;
-
-typedef struct _DRI2Screen *DRI2ScreenPtr;
+static int dri2WindowPrivateKeyIndex;
+static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
+static int dri2PixmapPrivateKeyIndex;
+static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
 
 typedef struct _DRI2Drawable {
-    DRI2ScreenPtr        dri2_screen;
+    unsigned int	 refCount;
     int			 width;
     int			 height;
     DRI2BufferPtr	*buffers;
@@ -66,8 +67,9 @@ typedef struct _DRI2Drawable {
     int			 swap_limit; /* for N-buffering */
 } DRI2DrawableRec, *DRI2DrawablePtr;
 
+typedef struct _DRI2Screen *DRI2ScreenPtr;
+
 typedef struct _DRI2Screen {
-    ScreenPtr			 screen;
     unsigned int		 numDrivers;
     const char			**driverNames;
     const char			*deviceName;
@@ -93,33 +95,43 @@ DRI2GetScreen(ScreenPtr pScreen)
 static DRI2DrawablePtr
 DRI2GetDrawable(DrawablePtr pDraw)
 {
-    DRI2DrawablePtr pPriv;
-    int rc;
- 
-    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
-				 dri2DrawableRes, NULL, DixReadAccess);
-    if (rc != Success)
+    WindowPtr		  pWin;
+    PixmapPtr		  pPixmap;
+
+    if (!pDraw)
 	return NULL;
 
-    return pPriv;
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+	pWin = (WindowPtr) pDraw;
+	return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+    }
+    else
+    {
+	pPixmap = (PixmapPtr) pDraw;
+	return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+    }
 }
 
 int
 DRI2CreateDrawable(DrawablePtr pDraw)
 {
+    WindowPtr	    pWin;
+    PixmapPtr	    pPixmap;
     DRI2DrawablePtr pPriv;
-    int rc;
 
-    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
-				 dri2DrawableRes, NULL, DixReadAccess);
-    if (rc == Success || rc != BadValue)
-	return rc;
+    pPriv = DRI2GetDrawable(pDraw);
+    if (pPriv != NULL)
+    {
+	pPriv->refCount++;
+	return Success;
+    }
 
     pPriv = xalloc(sizeof *pPriv);
     if (pPriv == NULL)
 	return BadAlloc;
 
-    pPriv->dri2_screen = DRI2GetScreen(pDraw->pScreen);
+    pPriv->refCount = 1;
     pPriv->width = pDraw->width;
     pPriv->height = pDraw->height;
     pPriv->buffers = NULL;
@@ -132,30 +144,43 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     pPriv->last_swap_target = -1;
     pPriv->swap_limit = 1; /* default to double buffering */
 
-    if (!AddResource(pDraw->id, dri2DrawableRes, pPriv))
-	return BadAlloc;
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+	pWin = (WindowPtr) pDraw;
+	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
+    }
+    else
+    {
+	pPixmap = (PixmapPtr) pDraw;
+	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
+    }
 
     return Success;
 }
 
-static int DRI2DrawableGone(pointer p, XID id)
+static void
+DRI2FreeDrawable(DrawablePtr pDraw)
 {
-    DRI2DrawablePtr pPriv = p;
-    DRI2ScreenPtr   ds = pPriv->dri2_screen;
-    DrawablePtr     root;
-    int i;
-
-    root = &WindowTable[ds->screen->myNum]->drawable;
-    if (pPriv->buffers != NULL) {
-	for (i = 0; i < pPriv->bufferCount; i++)
-	    (*ds->DestroyBuffer)(root, pPriv->buffers[i]);
+    DRI2DrawablePtr pPriv;
+    WindowPtr  	    pWin;
+    PixmapPtr	    pPixmap;
 
-	xfree(pPriv->buffers);
-    }
+    pPriv = DRI2GetDrawable(pDraw);
+    if (pPriv == NULL)
+	return;
 
     xfree(pPriv);
 
-    return Success;
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+	pWin = (WindowPtr) pDraw;
+	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+    }
+    else
+    {
+	pPixmap = (PixmapPtr) pDraw;
+	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+    }
 }
 
 static int
@@ -509,6 +534,13 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	return;
     }
 
+    if (pPriv->refCount == 0) {
+        xf86DrvMsg(pScreen->myNum, X_ERROR,
+		   "[DRI2] %s: bad drawable refcount\n", __func__);
+	DRI2FreeDrawable(pDraw);
+	return;
+    }
+
     ust = ((CARD64)tv_sec * 1000000) + tv_usec;
     if (swap_complete)
 	swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -721,6 +753,36 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
     return Success;
 }
 
+void
+DRI2DestroyDrawable(DrawablePtr pDraw)
+{
+    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
+    DRI2DrawablePtr pPriv;
+
+    pPriv = DRI2GetDrawable(pDraw);
+    if (pPriv == NULL)
+	return;
+
+    pPriv->refCount--;
+    if (pPriv->refCount > 0)
+	return;
+
+    if (pPriv->buffers != NULL) {
+	int i;
+
+	for (i = 0; i < pPriv->bufferCount; i++)
+	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+
+	xfree(pPriv->buffers);
+    }
+
+    /* If the window is destroyed while we have a swap pending, don't
+     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
+     * callback and we'll free it there once we're done. */
+    if (!pPriv->swapsPending)
+	DRI2FreeDrawable(pDraw);
+}
+
 Bool
 DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
 	    const char **driverName, const char **deviceName)
@@ -772,7 +834,6 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!ds)
 	return FALSE;
 
-    ds->screen         = pScreen;
     ds->fd	       = info->fd;
     ds->deviceName     = info->deviceName;
 
@@ -836,8 +897,6 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
     static Bool setupDone = FALSE;
 
-    dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
-
     if (!setupDone)
     {
 	setupDone = TRUE;
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 1ac4a5f..bd92fd3 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -51,6 +51,7 @@
 #include "xf86Module.h"
 
 static ExtensionEntry	*dri2Extension;
+static RESTYPE		 dri2DrawableRes;
 
 static Bool
 validDrawable(ClientPtr client, XID drawable, Mask access_mode,
@@ -171,6 +172,11 @@ ProcDRI2CreateDrawable(ClientPtr client)
     if (status != Success)
 	return status;
 
+    if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
+	DRI2DestroyDrawable(pDrawable);
+	return BadAlloc;
+    }
+
     return client->noClientException;
 }
 
@@ -186,6 +192,8 @@ ProcDRI2DestroyDrawable(ClientPtr client)
 		       &pDrawable, &status))
 	return status;
 
+    FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
+
     return client->noClientException;
 }
 
@@ -612,11 +620,25 @@ SProcDRI2Dispatch (ClientPtr client)
     }
 }
 
+static int DRI2DrawableGone(pointer p, XID id)
+{
+    DrawablePtr pDrawable = p;
+
+    DRI2DestroyDrawable(pDrawable);
+
+    return Success;
+}
+
 int DRI2EventBase;
 
 static void
 DRI2ExtensionInit(void)
 {
+    dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
+
+    if (!dri2DrawableRes)
+	return;
+
     dri2Extension = AddExtension(DRI2_NAME,
 				 DRI2NumberEvents,
 				 DRI2NumberErrors,
commit 65e84507b48546443fd0f67bc3263903d116bf62
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 27 14:08:58 2010 +1000

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

diff --git a/configure.ac b/configure.ac
index 4c1034f..b8cc209 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.8.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2010-04-02"
+AC_INIT([xorg-server], 1.8.0.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2010-04-27"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
commit 5d757096fc72233a9ff520149ec7cfd1ced457d8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 23 13:42:34 2010 +1000

    Xvfb: Usage message typo fix.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 0782894b5702adcf6f4a90861793b717f3856fa5)
    
    Conflicts:
    
    	hw/vfb/InitOutput.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index e7dd1d9..841d762 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -249,7 +249,7 @@ ddxUseMsg(void)
     ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
     ErrorF("-pixdepths list-of-int support given pixmap depths\n");
 #ifdef RENDER
-    ErrorF("+/-render		   turn on/of RENDER extension support"
+    ErrorF("+/-render		   turn on/off RENDER extension support"
 	   "(default on)\n");
 #endif
     ErrorF("-linebias n            adjust thin line pixelization\n");
commit feb39870e0d2c5917c8da1951c721f6f72cb4d39
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 5455df65207aa367531f5a3c35d39cb6c390e5de
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 14 09:48:53 2010 +1000

    xkb: purge unneeded includes from ddxDevBtn.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Dan Nicholson <dbn.lists at gmail.com>
    (cherry picked from commit da4e2e382828d7ba460766709368ec6214b286dd)

diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
index b8a222d..b8a1255 100644
--- a/xkb/ddxDevBtn.c
+++ b/xkb/ddxDevBtn.c
@@ -28,18 +28,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
 #include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "eventstr.h"
 #include <xkbsrv.h>
 #include "mi.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
 
 void
 XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
commit 72664a84e0f700fc51737b76bfd89b1d3b9cbdce
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 13 14:44:59 2010 +1000

    xkb: use GPE for XKB fake motion events.
    
    Section 4.6.1 of the XKB spec says that "the initial event always moves the
    cursor the distance specified in the action [...]", so skip the
    POINTER_ACCELERATE flag for GPE, it would cause double-acceleration.
    
    Potential regression - GPE expects the coordinates to be either relative or
    both. XKB in theory allows for x to be relative and y to be absolute (or
    vice versa). Let's pretend that scenario has no users.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Simon Thum <simon.thum at gmx.de>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    (cherry picked from commit f4106c02318fcc4b534224df5b95a58aff555fb4)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 278ff76..239b7a1 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -769,6 +769,7 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators(
 );
 
 extern _X_EXPORT void XkbDDXFakePointerMotion(
+	DeviceIntPtr	/* dev */,
  	unsigned int	/* flags */,
 	int		/* x */,
 	int		/* y */
diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c
index f90d209..b383716 100644
--- a/xkb/ddxFakeMtn.c
+++ b/xkb/ddxFakeMtn.c
@@ -28,91 +28,37 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
 #include "inputstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
 #include <xkbsrv.h>
-#include <X11/extensions/XI.h>
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-#include "mipointer.h"
-#include "mipointrst.h"
+#include "mi.h"
 
 void
-XkbDDXFakePointerMotion(unsigned flags,int x,int y)
+XkbDDXFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
 {
-int 		   oldX,oldY;
-ScreenPtr	   pScreen, oldScreen;
-
-    GetSpritePosition(inputInfo.pointer, &oldX, &oldY);
-    pScreen = oldScreen = GetSpriteWindow(inputInfo.pointer)->drawable.pScreen;
-
-#ifdef PANORAMIX
-    if (!noPanoramiXExtension) {
-	BoxRec box;
-	int i;
+    EventListPtr        events;
+    int                 nevents, i;
+    DeviceIntPtr        ptr;
+    int                 gpe_flags = 0;
 
-	if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
-							    oldX, oldY, &box)) {
-	    FOR_NSCREENS(i) {
-		if(i == pScreen->myNum)
-		    continue;
-		if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i],
-				   oldX, oldY, &box)) {
-		    pScreen = screenInfo.screens[i];
-		    break;
-		}
-	    }
-	}
-	oldScreen = pScreen;
-
-	if (flags&XkbSA_MoveAbsoluteX)
-	     oldX=  x;
-	else oldX+= x;
-	if (flags&XkbSA_MoveAbsoluteY)
-	     oldY=  y;
-	else oldY+= y;
+    if (!dev->u.master)
+        ptr = dev;
+    else
+        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
 
-	if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
-							    oldX, oldY, &box)) {
-	    FOR_NSCREENS(i) {
-		if(i == pScreen->myNum)
-		    continue;
-		if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i],
-				   oldX, oldY, &box)) {
-		    pScreen = screenInfo.screens[i];
-		    break;
-		}
-	    }
-	}
-	oldX -= panoramiXdataPtr[pScreen->myNum].x;
-	oldY -= panoramiXdataPtr[pScreen->myNum].y;
-    }
+    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
+        gpe_flags = POINTER_ABSOLUTE;
     else
-#endif
-    {
-	if (flags&XkbSA_MoveAbsoluteX)
-	     oldX=  x;
-	else oldX+= x;
-	if (flags&XkbSA_MoveAbsoluteY)
-	     oldY=  y;
-	else oldY+= y;
+        gpe_flags = POINTER_RELATIVE;
+
+    events = InitEventList(GetMaximumEventsNum());
+    OsBlockSignals();
+    nevents = GetPointerEvents(events, ptr,
+                               MotionNotify, 0,
+                               gpe_flags, 0, 2, (int[]){x, y});
+    OsReleaseSignals();
 
-#define GetScreenPrivate(s) ((miPointerScreenPtr)dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey))
-	(*(GetScreenPrivate(oldScreen))->screenFuncs->CursorOffScreen)
-	    (&pScreen, &oldX, &oldY);
-    }
+    for (i = 0; i < nevents; i++)
+        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
 
-    if (pScreen != oldScreen)
-	NewCurrentScreen(inputInfo.pointer, pScreen, oldX, oldY);
-    if (pScreen->SetCursorPosition)
-	(*pScreen->SetCursorPosition)(inputInfo.pointer, pScreen, oldX, oldY, TRUE);
+    FreeEventList(events, GetMaximumEventsNum());
 }
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 2cdb6fc..4c7bce2 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -479,7 +479,7 @@ int		dx,dy;
 	dx= xkbi->mouseKeysDX;
 	dy= xkbi->mouseKeysDY;
     }
-    XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
+    XkbDDXFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
     return xkbi->desc->ctrls->mk_interval;
 }
 
@@ -507,7 +507,7 @@ Bool	accel;
 	accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
 	x= XkbPtrActionX(&pAction->ptr);
 	y= XkbPtrActionY(&pAction->ptr);
-	XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
+	XkbDDXFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
 	AccessXCancelRepeatKey(xkbi,keycode);
 	xkbi->mouseKeysAccel= accel&&
 		(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
commit 3e76abe1c16ff45f25de8f20c3aaf3268dff10c8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 14 10:51:41 2010 +1000

    xkb: Guard against SIGIO updates during PointerKeys.
    
    In theory, an event coming in during GPE could reset our lastSlave, leading
    to rather interesting events lateron.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Simon Thum <simon.thum at gmx.de>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    (cherry picked from commit 6c42c8c356be305dc7f3f92ad8d58675da8c2f07)

diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
index 3bee84b..b8a222d 100644
--- a/xkb/ddxDevBtn.c
+++ b/xkb/ddxDevBtn.c
@@ -64,11 +64,12 @@ XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
         return;
 
     events = InitEventList(GetMaximumEventsNum());
+    OsBlockSignals();
     nevents = GetPointerEvents(events, ptr,
                                press ? ButtonPress : ButtonRelease, button,
                                0 /* flags */, 0 /* first */,
                                0 /* num_val */, NULL);
-
+    OsReleaseSignals();
 
     for (i = 0; i < nevents; i++)
         mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
commit 37c3d2aef089a8bb45adecb4f0372c47b62e0bb7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 13 14:41:07 2010 +1000

    xkb: Post PointerKeys through the XTEST device.
    
    Posting an event through a master device may cause pointer jumps once
    lastSlave == master, caused by double scaling. To avoid this, post the fake
    event generated by XKB through the XTEST device instead.
    
    Fedora bug #560356 <https://bugzilla.redhat.com/560356>
    Tested-by: Andrew McNabb
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    (cherry picked from commit 108457dff816569453a2d88cd72595fa7eb02479)

diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
index 94630d1..3bee84b 100644
--- a/xkb/ddxDevBtn.c
+++ b/xkb/ddxDevBtn.c
@@ -51,13 +51,13 @@ XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
      * post through the attached master pointer we'd get duplicate events.
      *
-     * if dev is a master keyboard, post through the master pointer.
+     * if dev is a master keyboard, post through the XTEST device
      *
      * if dev is a floating slave, post through the device itself.
      */
 
     if (IsMaster(dev))
-        ptr = GetMaster(dev, MASTER_POINTER);
+        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
     else if (!dev->u.master)
         ptr = dev;
     else
commit a9c978bb9723ec7c291074ff75423623c8bf7209
Author: Benjamin Tissoires <tissoire at cena.fr>
Date:   Wed Apr 14 17:27:51 2010 +0200

    xf86ScaleAxis: support for high resolution devices
    
    High resolution devices was generating integer overflow.
    For instance the wacom Cintiq 21UX has an axis value up to
    87000. Thus the term (dSx * (Cx - Rxlow)) is greater than
    MAX_INT32.
    
    Using 64bits integer avoids such problem.
    
    Signed-off-by: Philippe Ribet <ribet at cena.fr>
    Signed-off-by: Benjamin Tissoires <tissoire at cena.fr>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit a780e5b3638a0ff81301fc68aca15b47ba0befb7)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 7723ba6..dba3370 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -86,6 +86,7 @@
 #include "windowstr.h"	/* screenIsSaved */
 
 #include <stdarg.h>
+#include <stdint.h>          /* for int64_t */
 
 #include <X11/Xpoll.h>
 
@@ -1177,12 +1178,11 @@ xf86ScaleAxis(int	Cx,
               int	Rxlow )
 {
     int X;
-    int dSx = Sxhigh - Sxlow;
-    int dRx = Rxhigh - Rxlow;
+    int64_t dSx = Sxhigh - Sxlow;
+    int64_t dRx = Rxhigh - Rxlow;
 
-    dSx = Sxhigh - Sxlow;
     if (dRx) {
-	X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow;
+	X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow);
     }
     else {
 	X = 0;
commit 6ab87eb04cf24619c17c1fa05daaeebb481a6a50
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Apr 16 05:55:35 2010 -0400

    glx: Drop DestroyWindow hook
    
    Now that glx doesn't call DRI2DestroyDrawable anymore, we don't need to
    force a specific resource destruction order in the DestroyWindow hook.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Michel Dänzer <michel at daenzer.net>
    
    https://bugs.freedesktop.org/show_bug.cgi?id=26394
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index 58d8ee0..b75aea6 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -215,7 +215,6 @@ glxCloseScreen (int index, ScreenPtr pScreen)
     __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
 
     pScreen->CloseScreen = pGlxScreen->CloseScreen;
-    pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
 
     pGlxScreen->destroy(pGlxScreen);
 
@@ -347,31 +346,6 @@ pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual)
     return best;
 }
 
-static Bool
-glxDestroyWindow(WindowPtr pWin)
-{
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
-    Bool retval = TRUE;
-
-    FreeResource(pWin->drawable.id, FALSE);
-
-    /* call lower wrapped functions */
-    if (pGlxScreen->DestroyWindow) {
-	/* unwrap */
-	pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
-
-	/* call lower layers */
-	retval = (*pScreen->DestroyWindow)(pWin);
-
-	/* rewrap */
-	pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
-	pScreen->DestroyWindow = glxDestroyWindow;
-    }
-
-    return retval;
-}
-
 void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 {
     __GLXconfig *m;
@@ -394,8 +368,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 
     pGlxScreen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = glxCloseScreen;
-    pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
-    pScreen->DestroyWindow = glxDestroyWindow;
 
     i = 0;
     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index bff4363..d52099f 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -173,7 +173,6 @@ struct __GLXscreen {
     /*@}*/
 
     Bool (*CloseScreen)(int index, ScreenPtr pScreen);
-    Bool (*DestroyWindow)(WindowPtr pWindow);
 };
 
 
commit 0c499f2ee4ae2b7dc424009abb336fc81a8a2853
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Apr 16 05:55:34 2010 -0400

    DRI2: Track DRI2 drawables as resources, not privates
    
    The main motivation here is to have the resource system clean up the
    DRI2 drawable automatically so glx doesn't have to.  Right now, the
    glx drawable resource must be destroyed before the X drawable, so that
    calling DRI2DestroyDrawable doesn't crash.  By making the DRI2
    drawable a resource, GLX doesn't have to worry about that and the
    resource destruction order becomes irrelevant.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=26394
    
    [Ported to 1.8 branch by ajax at redhat.com]
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index edd29b0..bde519a 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -105,11 +105,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
     
     (*core->destroyDrawable)(private->driDrawable);
 
-    /* If the X window was destroyed, the dri DestroyWindow hook will
-     * aready have taken care of this, so only call if pDraw isn't NULL. */
-    if (drawable->pDraw != NULL)
-	DRI2DestroyDrawable(drawable->pDraw);
-
     __glXDrawableRelease(drawable);
 
     xfree(private);
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 48618e1..63bef28 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,15 +45,14 @@
 
 #include "xf86.h"
 
-static int dri2ScreenPrivateKeyIndex;
+static int           dri2ScreenPrivateKeyIndex;
 static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
-static int dri2WindowPrivateKeyIndex;
-static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
-static int dri2PixmapPrivateKeyIndex;
-static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
+static RESTYPE       dri2DrawableRes;
+
+typedef struct _DRI2Screen *DRI2ScreenPtr;
 
 typedef struct _DRI2Drawable {
-    unsigned int	 refCount;
+    DRI2ScreenPtr        dri2_screen;
     int			 width;
     int			 height;
     DRI2BufferPtr	*buffers;
@@ -67,9 +66,8 @@ typedef struct _DRI2Drawable {
     int			 swap_limit; /* for N-buffering */
 } DRI2DrawableRec, *DRI2DrawablePtr;
 
-typedef struct _DRI2Screen *DRI2ScreenPtr;
-
 typedef struct _DRI2Screen {
+    ScreenPtr			 screen;
     unsigned int		 numDrivers;
     const char			**driverNames;
     const char			*deviceName;
@@ -95,43 +93,33 @@ DRI2GetScreen(ScreenPtr pScreen)
 static DRI2DrawablePtr
 DRI2GetDrawable(DrawablePtr pDraw)
 {
-    WindowPtr		  pWin;
-    PixmapPtr		  pPixmap;
-
-    if (!pDraw)
+    DRI2DrawablePtr pPriv;
+    int rc;
+ 
+    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
+				 dri2DrawableRes, NULL, DixReadAccess);
+    if (rc != Success)
 	return NULL;
 
-    if (pDraw->type == DRAWABLE_WINDOW)
-    {
-	pWin = (WindowPtr) pDraw;
-	return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
-    }
-    else
-    {
-	pPixmap = (PixmapPtr) pDraw;
-	return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
-    }
+    return pPriv;
 }
 
 int
 DRI2CreateDrawable(DrawablePtr pDraw)
 {
-    WindowPtr	    pWin;
-    PixmapPtr	    pPixmap;
     DRI2DrawablePtr pPriv;
+    int rc;
 
-    pPriv = DRI2GetDrawable(pDraw);
-    if (pPriv != NULL)
-    {
-	pPriv->refCount++;
-	return Success;
-    }
+    rc = dixLookupResourceByType((pointer *) &pPriv, pDraw->id,
+				 dri2DrawableRes, NULL, DixReadAccess);
+    if (rc == Success || rc != BadValue)
+	return rc;
 
     pPriv = xalloc(sizeof *pPriv);
     if (pPriv == NULL)
 	return BadAlloc;
 
-    pPriv->refCount = 1;
+    pPriv->dri2_screen = DRI2GetScreen(pDraw->pScreen);
     pPriv->width = pDraw->width;
     pPriv->height = pDraw->height;
     pPriv->buffers = NULL;
@@ -144,43 +132,30 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     pPriv->last_swap_target = -1;
     pPriv->swap_limit = 1; /* default to double buffering */
 
-    if (pDraw->type == DRAWABLE_WINDOW)
-    {
-	pWin = (WindowPtr) pDraw;
-	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
-    }
-    else
-    {
-	pPixmap = (PixmapPtr) pDraw;
-	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
-    }
+    if (!AddResource(pDraw->id, dri2DrawableRes, pPriv))
+	return BadAlloc;
 
     return Success;
 }
 
-static void
-DRI2FreeDrawable(DrawablePtr pDraw)
+static int DRI2DrawableGone(pointer p, XID id)
 {
-    DRI2DrawablePtr pPriv;
-    WindowPtr  	    pWin;
-    PixmapPtr	    pPixmap;
+    DRI2DrawablePtr pPriv = p;
+    DRI2ScreenPtr   ds = pPriv->dri2_screen;
+    DrawablePtr     root;
+    int i;
 
-    pPriv = DRI2GetDrawable(pDraw);
-    if (pPriv == NULL)
-	return;
+    root = &WindowTable[ds->screen->myNum]->drawable;
+    if (pPriv->buffers != NULL) {
+	for (i = 0; i < pPriv->bufferCount; i++)
+	    (*ds->DestroyBuffer)(root, pPriv->buffers[i]);
+
+	xfree(pPriv->buffers);
+    }
 
     xfree(pPriv);
 
-    if (pDraw->type == DRAWABLE_WINDOW)
-    {
-	pWin = (WindowPtr) pDraw;
-	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
-    }
-    else
-    {
-	pPixmap = (PixmapPtr) pDraw;
-	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
-    }
+    return Success;
 }
 
 static int
@@ -534,13 +509,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	return;
     }
 
-    if (pPriv->refCount == 0) {
-        xf86DrvMsg(pScreen->myNum, X_ERROR,
-		   "[DRI2] %s: bad drawable refcount\n", __func__);
-	DRI2FreeDrawable(pDraw);
-	return;
-    }
-
     ust = ((CARD64)tv_sec * 1000000) + tv_usec;
     if (swap_complete)
 	swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -753,36 +721,6 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
     return Success;
 }
 
-void
-DRI2DestroyDrawable(DrawablePtr pDraw)
-{
-    DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
-    DRI2DrawablePtr pPriv;
-
-    pPriv = DRI2GetDrawable(pDraw);
-    if (pPriv == NULL)
-	return;
-
-    pPriv->refCount--;
-    if (pPriv->refCount > 0)
-	return;
-
-    if (pPriv->buffers != NULL) {
-	int i;
-
-	for (i = 0; i < pPriv->bufferCount; i++)
-	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
-
-	xfree(pPriv->buffers);
-    }
-
-    /* If the window is destroyed while we have a swap pending, don't
-     * actually free the priv yet.  We'll need it in the DRI2SwapComplete()
-     * callback and we'll free it there once we're done. */
-    if (!pPriv->swapsPending)
-	DRI2FreeDrawable(pDraw);
-}
-
 Bool
 DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
 	    const char **driverName, const char **deviceName)
@@ -834,6 +772,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!ds)
 	return FALSE;
 
+    ds->screen         = pScreen;
     ds->fd	       = info->fd;
     ds->deviceName     = info->deviceName;
 
@@ -897,6 +836,8 @@ DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
     static Bool setupDone = FALSE;
 
+    dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
+
     if (!setupDone)
     {
 	setupDone = TRUE;
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index bd92fd3..1ac4a5f 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -51,7 +51,6 @@
 #include "xf86Module.h"
 
 static ExtensionEntry	*dri2Extension;
-static RESTYPE		 dri2DrawableRes;
 
 static Bool
 validDrawable(ClientPtr client, XID drawable, Mask access_mode,
@@ -172,11 +171,6 @@ ProcDRI2CreateDrawable(ClientPtr client)
     if (status != Success)
 	return status;
 
-    if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
-	DRI2DestroyDrawable(pDrawable);
-	return BadAlloc;
-    }
-
     return client->noClientException;
 }
 
@@ -192,8 +186,6 @@ ProcDRI2DestroyDrawable(ClientPtr client)
 		       &pDrawable, &status))
 	return status;
 
-    FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
-
     return client->noClientException;
 }
 
@@ -620,25 +612,11 @@ SProcDRI2Dispatch (ClientPtr client)
     }
 }
 
-static int DRI2DrawableGone(pointer p, XID id)
-{
-    DrawablePtr pDrawable = p;
-
-    DRI2DestroyDrawable(pDrawable);
-
-    return Success;
-}
-
 int DRI2EventBase;
 
 static void
 DRI2ExtensionInit(void)
 {
-    dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
-
-    if (!dri2DrawableRes)
-	return;
-
     dri2Extension = AddExtension(DRI2_NAME,
 				 DRI2NumberEvents,
 				 DRI2NumberErrors,
commit 0460a76b9ae25fe26f683f0cbff1e4157287cf56
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Apr 16 05:55:33 2010 -0400

    glx: Let the resource system destroy pixmaps
    
    GLX pbuffers are implemented using a pixmap allocated by the server.
    With the change to DRI2 to track DRI2 drawables as resources, we need to make
    sure that every drawable we create a DRI2 drawable for has an XID.  By
    using the XID of the pbuffer, the resource system will automatically
    reclaim the hidden pixmap and the DRI2 drawable when the pbuffer is
    destroyed or the client exits.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 22da7aa9d743deee198aaf6df5d370a446db9763)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 04c6d40..087d52e 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1101,14 +1101,6 @@ __glXDrawableInit(__GLXdrawable *drawable,
 void
 __glXDrawableRelease(__GLXdrawable *drawable)
 {
-    ScreenPtr pScreen = drawable->pDraw->pScreen;
-
-    switch (drawable->type) {
-    case GLX_DRAWABLE_PIXMAP:
-    case GLX_DRAWABLE_PBUFFER:
-	(*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw);
-	break;
-    }
 }
 
 static int 
@@ -1117,8 +1109,6 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
 {
     __GLXdrawable *pGlxDraw;
 
-    LEGAL_NEW_RESOURCE(glxDrawableId, client);
-
     if (pGlxScreen->pScreen != pDraw->pScreen)
 	return BadMatch;
 
@@ -1135,7 +1125,8 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
     /* Add the glx drawable under the XID of the underlying X drawable
      * too.  That way we'll get a callback in DrawableGone and can
      * clean up properly when the drawable is destroyed. */
-    if (!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
+    if (pDraw->id != glxDrawableId &&
+	!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
 	pGlxDraw->destroy (pGlxDraw);
 	return BadAlloc;
     }
@@ -1150,6 +1141,8 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
     DrawablePtr pDraw;
     int err;
 
+    LEGAL_NEW_RESOURCE(glxDrawableId, client);
+
     err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
     if (err != Success) {
 	client->errorValue = drawableId;
@@ -1163,9 +1156,6 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
     err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
 			      glxDrawableId, GLX_DRAWABLE_PIXMAP);
 
-    if (err == Success)
-	((PixmapPtr) pDraw)->refcnt++;
-
     return err;
 }
 
@@ -1306,6 +1296,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
     PixmapPtr		 pPixmap;
     int			 err;
 
+    LEGAL_NEW_RESOURCE(glxDrawableId, client);
+
     if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
 	return err;
     if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
@@ -1316,6 +1308,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
 						    width, height, config->rgbBits, 0);
     __glXleaveServer(GL_FALSE);
 
+    /* Assign the pixmap the same id as the pbuffer and add it as a
+     * resource so it and the DRI2 drawable will be reclaimed when the
+     * pbuffer is destroyed. */
+    pPixmap->drawable.id = glxDrawableId;
+    if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap))
+	return BadAlloc;
+
     return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
 			       glxDrawableId, GLX_DRAWABLE_PBUFFER);
 }
@@ -1423,6 +1422,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
     DrawablePtr		 pDraw;
     int			 err;
 
+    LEGAL_NEW_RESOURCE(req->glxwindow, client);
+
     if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
 	return err;
     if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
commit 86ca6baee221fc691c7828b078008314ac989864
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Apr 16 05:55:32 2010 -0400

    glx: Track GLX 1.3 style GLX drawables under their X drawable ID as well
    
    This ensures that the DrawableGone callback gets called as necessary
    when the X drawable goes away.  Otherwise, using a GLX drawable
    (say, glXSwapBuffers) in indirect mode after the X drawable has been
    destroyed will crash the server.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Michel Dänzer <michel at daenzer.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit f0006aa58f6cf7552a239e169ff6e7e4fda532f4)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 77afbf4..04c6d40 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -161,7 +161,11 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
 	return FALSE;
     }
 
+    /* If the ID of the glx drawable we looked up doesn't match the id
+     * we looked for, it's because we looked it up under the X
+     * drawable ID (see DoCreateGLXDrawable). */
     if (rc == BadValue ||
+	(*drawable)->drawId != id ||
 	(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
 	client->errorValue = id;
 	switch (type) {
@@ -1128,6 +1132,14 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
 	return BadAlloc;
     }
 
+    /* Add the glx drawable under the XID of the underlying X drawable
+     * too.  That way we'll get a callback in DrawableGone and can
+     * clean up properly when the drawable is destroyed. */
+    if (!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
+	pGlxDraw->destroy (pGlxDraw);
+	return BadAlloc;
+    }
+
     return Success;
 }
 
diff --git a/glx/glxext.c b/glx/glxext.c
index 59bcfbe..89e58b0 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -126,6 +126,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 {
     __GLXcontext *c;
 
+    /* If this drawable was created using glx 1.3 drawable
+     * constructors, we added it as a glx drawable resource under both
+     * its glx drawable ID and it X drawable ID.  Remove the other
+     * resource now so we don't a callback for freed memory. */
+    if (glxPriv->drawId != glxPriv->pDraw->id) {
+	if (xid == glxPriv->drawId)
+	    FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
+	else
+	    FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
+    }
+
     for (c = glxAllContexts; c; c = c->next) {
 	if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
 	    int i;
commit 7d5e6012df237c0d9d4741ca275751bc49f731ed
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)

diff --git a/hw/vfb/InitInput.c b/hw/vfb/InitInput.c
index 35d1dc4..10bb6a5 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,10 +137,15 @@ 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 0e6c08655cdb240b5de42a7559cfd3ef60a85118
Author: Adam Tkac <atkac at redhat.com>
Date:   Mon Mar 22 14:52:29 2010 +0100

    dix: Export AllocDevicePair GetPointerEvents, GetKeyboardEvents and generate_modkeymap functions from Xorg.
    
    Those functions are used by TigerVNC libvnc.so module which doesn't
    use standard XInput infrastructure but uses same functions like,
    for example, XTest devices.
    
    Signed-off-by: Adam Tkac <atkac at redhat.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 2f29b163bbdebe384c24f781bb97b446959e8f4c)

diff --git a/include/input.h b/include/input.h
index 8561308..63f981e 100644
--- a/include/input.h
+++ b/include/input.h
@@ -432,7 +432,7 @@ extern void CreateClassesChangedEvent(EventListPtr event,
                                       DeviceIntPtr master,
                                       DeviceIntPtr slave,
                                       int type);
-extern int GetPointerEvents(
+extern _X_EXPORT int GetPointerEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
@@ -442,7 +442,7 @@ extern int GetPointerEvents(
     int num_valuators,
     int *valuators);
 
-extern int GetKeyboardEvents(
+extern _X_EXPORT int GetKeyboardEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
@@ -493,7 +493,7 @@ extern int AttachDevice(ClientPtr client,
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
 extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
 
-extern int AllocDevicePair(ClientPtr client,
+extern _X_EXPORT int AllocDevicePair(ClientPtr client,
                              char* name,
                              DeviceIntPtr* ptr,
                              DeviceIntPtr* keybd,
@@ -505,7 +505,7 @@ extern void DeepCopyDeviceClasses(DeviceIntPtr from,
                                   DeviceChangedEvent *dce);
 
 /* Helper functions. */
-extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
+extern _X_EXPORT int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
                               KeyCode **modkeymap, int *max_keys_per_mod);
 extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
                          int max_keys_per_mod);
commit 8ab76efb14ba7010c2762120fc7784e3f8bd7d11
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 23 14:35:56 2010 +1000

    mi: remove log-spamming bogus error message (#26843)
    
    miSpriteRealizeCursor is called whenever a device is set floating and it's
    fine to do so, no need for an error message.
    Same goes for the other miSprite messages.
    
    X.Org Bug 26843 <http://bugs.freedesktop.org/show_bug.cgi?id=26843>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 241b53b77750b5eea6759e79b23be4ff270a3d1f)

diff --git a/mi/misprite.c b/mi/misprite.c
index 2ec6782..ac025e1 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -765,10 +765,8 @@ miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
 
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteRealizeCursor called for floating device.\n");
         return FALSE;
-    }
+
     pCursorInfo = MISPRITE(pDev);
 
     if (pCursor == pCursorInfo->pCursor)
@@ -796,10 +794,8 @@ miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
 
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteSetCursor called for floating device.\n");
         return;
-    }
+
     pPointer = MISPRITE(pDev);
 
     if (!pCursor)
@@ -913,10 +909,8 @@ miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteMoveCursor called for floating device.\n");
         return;
-    }
+
     pCursor = MISPRITE(pDev)->pCursor;
 
     miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
@@ -981,10 +975,8 @@ miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
 
 
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteRemoveCursor called for floating device.\n");
         return;
-    }
+
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
     pCursorInfo = MISPRITE(pDev);
@@ -1021,10 +1013,8 @@ miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
     miCursorInfoPtr     pCursorInfo;
 
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteSaveUnderCursor called for floating device.\n");
         return;
-    }
+
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
     pCursorInfo = MISPRITE(pDev);
@@ -1064,10 +1054,7 @@ miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
     miCursorInfoPtr     pCursorInfo;
 
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteRestoreCursor called for floating device.\n");
         return;
-    }
 
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
@@ -1108,10 +1095,8 @@ miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
     miCursorInfoPtr pCursorInfo;
 
     if (!IsMaster(pDev) && !pDev->u.master)
-    {
-        ErrorF("[mi] miSpriteComputeSaved called for floating device.\n");
         return;
-    }
+
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
     pCursorInfo = MISPRITE(pDev);
 
commit 049a36cd402da9219e60221f5671f94a8f8f687f
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)

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 59ee696aa1232698ab0fc22ffffe4e6f438bf764
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)

diff --git a/dix/events.c b/dix/events.c
index 24c9e84..6d0137d 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
commit 19b1fa1b5ff615f8711ad95f28663895707a3970
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 6541652..24c9e84 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3976,7 +3976,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 1ae61e0c406bbb454ca24aebd0f61148fe04e60c
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Wed Apr 14 19:28:37 2010 +0200

    EXA: Check sys_ptr isn't NULL before passing it to the UploadToScreen hook.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=27510 .
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 7b6517526631a65891b806bca30be8f49955d0a8)

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 4680c37..57029fd 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -512,7 +512,7 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
 	 *
 	 * Only taking this path for directly accessible pixmaps.
 	 */
-	} else if (!pDstExaPixmap->pDamage) {
+	} else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) {
 	    int bpp = pSrcDrawable->bitsPerPixel;
 	    int src_stride = exaGetPixmapPitch(pSrcPixmap);
 	    CARD8 *src = NULL;


More information about the Xquartz-changes mailing list