[Xquartz-changes] xserver: Branch 'master' - 10 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Fri Apr 16 15:43:05 PDT 2010


 dix/events.c              |    6 -
 glx/glxcmds.c             |   39 ++++--
 glx/glxdri2.c             |    5 
 glx/glxext.c              |   11 +
 glx/glxscreens.c          |   28 ----
 glx/glxscreens.h          |    1 
 hw/vfb/InitInput.c        |    6 +
 hw/xfree86/dri2/dri2.c    |  139 ++++++-----------------
 hw/xfree86/dri2/dri2ext.c |   22 ---
 include/input.h           |    8 -
 mi/midispcur.c            |  270 ++++++++++++++++++----------------------------
 mi/misprite.c             |   27 +---
 12 files changed, 207 insertions(+), 355 deletions(-)

New commits:
commit a92b2c2c8dd1e86ee852168146f01bdf72bfe2d0
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 1da1f33f2dd5b437dd56cd9f5d6782de4ad5a1bc
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
    
    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 4c9f381..74d6ebc 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 2bdb733..6c4dabc 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -48,15 +48,14 @@
 CARD8 dri2_major; /* version of DRI2 supported by DDX */
 CARD8 dri2_minor;
 
-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;
@@ -73,9 +72,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;
@@ -101,45 +99,35 @@ DRI2GetScreen(ScreenPtr pScreen)
 static DRI2DrawablePtr
 DRI2GetDrawable(DrawablePtr pDraw)
 {
-    WindowPtr		  pWin;
-    PixmapPtr		  pPixmap;
+    DRI2DrawablePtr pPriv;
+    int rc;
 
-    if (!pDraw)
+    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)
 {
     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
-    WindowPtr	    pWin;
-    PixmapPtr	    pPixmap;
     DRI2DrawablePtr pPriv;
     CARD64          ust;
+    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 = ds;
     pPriv->width = pDraw->width;
     pPriv->height = pDraw->height;
     pPriv->buffers = NULL;
@@ -158,43 +146,30 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     pPriv->last_swap_msc = 0;
     pPriv->last_swap_ust = 0;
 
-    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
@@ -505,10 +480,6 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 
     pPriv->blockedClient = NULL;
     pPriv->blockedOnMsc = FALSE;
-
-    /* If there's still a swap pending, let DRI2SwapComplete free it */
-    if (pPriv->refCount == 0 && pPriv->swapsPending == 0)
-	DRI2FreeDrawable(pDraw);
 }
 
 static void
@@ -576,13 +547,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
     pPriv->last_swap_ust = ust;
 
     DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
-
-    /*
-     * It's normal for the app to have exited with a swap outstanding, but
-     * don't free the drawable until they're all complete.
-     */
-    if (pPriv->swapsPending == 0 && pPriv->refCount == 0)
-	DRI2FreeDrawable(pDraw);
 }
 
 Bool
@@ -750,7 +714,7 @@ DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
     Bool ret;
 
     pPriv = DRI2GetDrawable(pDraw);
-    if (pPriv == NULL || pPriv->refCount == 0)
+    if (pPriv == NULL)
 	return BadDrawable;
 
     /* Old DDX just completes immediately */
@@ -774,7 +738,7 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
     DRI2DrawablePtr pPriv;
 
     pPriv = DRI2GetDrawable(pDraw);
-    if (pPriv == NULL || pPriv->refCount == 0)
+    if (pPriv == NULL)
 	return BadDrawable;
 
     /* target_sbc == 0 means to block until all pending swaps are
@@ -800,36 +764,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 or wait 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 && !pPriv->blockedClient)
-	DRI2FreeDrawable(pDraw);
-}
-
 Bool
 DRI2HasSwapControl(ScreenPtr pScreen)
 {
@@ -890,6 +824,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!ds)
 	return FALSE;
 
+    ds->screen         = pScreen;
     ds->fd	       = info->fd;
     ds->deviceName     = info->deviceName;
     dri2_major         = 1;
@@ -961,6 +896,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 094d54d..17df130 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;
 }
 
@@ -627,25 +619,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 22da7aa9d743deee198aaf6df5d370a446db9763
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>

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 f0006aa58f6cf7552a239e169ff6e7e4fda532f4
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>

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 e424d5812300e82de375d83dc0b490a76d865016
Merge: 5b0faf3... 0e7703f...
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Apr 15 15:01:34 2010 -0700

    Merge remote branch 'whot/for-keith'

commit 0e7703f9b1927328954a2fc87aac6be244819329
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>

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 2f29b163bbdebe384c24f781bb97b446959e8f4c
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>

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 241b53b77750b5eea6759e79b23be4ff270a3d1f
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>

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 00b8b7ad61b6f818271fb4d1e383113170309d72
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>

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 5f31e2196179f8db3170d65a17d8ad40da1acb0d
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>

diff --git a/dix/events.c b/dix/events.c
index 6541652..eaa2c57 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