xserver: Branch 'dmx-2' - 23 commits

David Reveman davidr at kemper.freedesktop.org
Thu Jan 15 05:51:18 PST 2009


 config/dbus-core.c    |    4 
 configure.ac          |    2 
 hw/dmx/dmx.h          |   12 -
 hw/dmx/dmxcb.c        |   85 ++++++++
 hw/dmx/dmxcursor.c    |  130 +++----------
 hw/dmx/dmxdnd.c       |  289 ++++++++++++++++++++++++----
 hw/dmx/dmxextension.c |   21 ++
 hw/dmx/dmxgcops.c     |  212 ++++++++++++---------
 hw/dmx/dmxgrab.c      |   22 +-
 hw/dmx/dmxgrab.h      |    6 
 hw/dmx/dmxinit.c      |   11 +
 hw/dmx/dmxinput.c     |  499 ++++++++++++++++++++++++++++++++++++++++++++------
 hw/dmx/dmxinput.h     |    8 
 hw/dmx/dmxlaunch.c    |   17 +
 hw/dmx/dmxrandr.c     |   18 +
 hw/dmx/dmxscrinit.c   |   14 -
 hw/dmx/dmxselection.c |  309 +++++++++++++++---------------
 hw/dmx/dmxselection.h |    3 
 hw/dmx/dmxshm.c       |   16 +
 hw/dmx/dmxwindow.c    |   32 ++-
 20 files changed, 1244 insertions(+), 466 deletions(-)

New commits:
commit 73a8a1aa6cd6d747d533ca63213f511244820a45
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 17:40:58 2008 -0500

    Fix a number of obvious XLIB_PROLOGUE/EPILOGUE issues.

diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index 3764bf3..c7eecaf 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -1495,7 +1495,7 @@ dmxAttachScreen (int                    idx,
 	return 1;
     }
 
-    XLIB_PROLOGUE (dmxScreens);
+    XLIB_PROLOGUE (dmxScreen);
     beShape = XShapeQueryExtension (dmxScreen->beDisplay,
 				    &dmxScreen->beShapeEventBase,
 				    &errorBase);
@@ -1515,9 +1515,11 @@ dmxAttachScreen (int                    idx,
     if (!dmxScreen->scrnWin)
 	dmxScreen->scrnWin = DefaultRootWindow (dmxScreen->beDisplay);
 
+    XLIB_PROLOGUE (dmxScreen);
     XSelectInput (dmxScreen->beDisplay,
 		  dmxScreen->scrnWin,
 		  StructureNotifyMask);
+    XLIB_EPILOGUE (dmxScreen);
 
     dmxSetErrorHandler(dmxScreen);
     dmxGetScreenAttribs(dmxScreen);
diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c
index bf27b31..23e1c28 100644
--- a/hw/dmx/dmxinit.c
+++ b/hw/dmx/dmxinit.c
@@ -323,8 +323,17 @@ Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen,
 	XSetAuthorization ((char *) authType, authTypeLen,
 			   (char *) authData, authDataLen);
 
-    if (!(dmxScreen->beDisplay = XOpenDisplay(display)))
+    dmxScreen->alive = 1;
+
+    XLIB_PROLOGUE (dmxScreen);
+    dmxScreen->beDisplay = XOpenDisplay (display);
+    XLIB_EPILOGUE (dmxScreen);
+
+    if (!dmxScreen->beDisplay)
+    {
+        dmxScreen->alive = 0;	
 	return FALSE;
+    }
 
     dmxScreen->alive      = 1;
     dmxScreen->broken     = 0;
diff --git a/hw/dmx/dmxrandr.c b/hw/dmx/dmxrandr.c
index f0b69fb..18ba733 100644
--- a/hw/dmx/dmxrandr.c
+++ b/hw/dmx/dmxrandr.c
@@ -1233,9 +1233,9 @@ dmxRRScreenInit (ScreenPtr pScreen)
 
 	if (display && beRandr)
 	{
-	    XLIB_PROLOGUE (dmxScreens);
+	    XLIB_PROLOGUE (dmxScreen);
 	    r = XRRGetScreenResources (display, DefaultRootWindow (display));
-	    XLIB_EPILOGUE (dmxScreens);
+	    XLIB_EPILOGUE (dmxScreen);
 	}
 
 	if (r)
diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index da3c579..55225a5 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -150,7 +150,7 @@ void dmxBEScreenInit(ScreenPtr pScreen)
     while (--i)
 	dmxBEPrefetchAtom (dmxScreen, (Atom) i);
     
-    XLIB_PROLOGUE (dmxScreens);
+    XLIB_PROLOGUE (dmxScreen);
     dmxScreen->beSelectionAtom = XInternAtom (dmxScreen->beDisplay, buf, 0);
     XLIB_EPILOGUE (dmxScreen);
 
@@ -175,7 +175,7 @@ void dmxBEScreenInit(ScreenPtr pScreen)
 	    if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
 		(dmxScreen->bePixmapFormats[i].depth ==
 		 dmxScreen->beDepths[j])) {
-		XLIB_PROLOGUE (dmxScreens);
+		XLIB_PROLOGUE (dmxScreen);
 		dmxScreen->scrnDefDrawables[i] = (Drawable)
 		    XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
 				  1, 1, dmxScreen->bePixmapFormats[i].depth);
commit 2fddbd302426f7d6cd11e2b5fe5ef0d670bd0f68
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 17:33:38 2008 -0500

    Have DMX DnD support handle shaped windows properly.

diff --git a/configure.ac b/configure.ac
index e067506..56b1d99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1568,7 +1568,7 @@ AM_CONDITIONAL(INTEGRATED_XPBPROXY, [test "x$INTEGRATED_XPBPROXY" = xyes])
 
 dnl DMX DDX
 
-PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi >= 1.1.99.1 dmxproto xau xcomposite xrandr xv x11-xcb xcb-randr xcb-xinput xcb-aux >= 0.2.1 xcb-image $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
+PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi >= 1.1.99.1 dmxproto xau xcomposite xrandr xv x11-xcb xcb-randr xcb-xinput xcb-aux >= 0.2.1 xcb-image xcb-shape $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
 if test "x$DMX" = xauto; then
 	DMX="$have_dmx"
 	case $host_os in
diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h
index 3213554..0833adb 100644
--- a/hw/dmx/dmx.h
+++ b/hw/dmx/dmx.h
@@ -189,6 +189,8 @@ typedef struct _DMXScreenInfo {
     Pixel         beBlackPixel;   /**< Default black pixel for BE */
     Pixel         beWhitePixel;   /**< Default white pixel for BE */
 
+    int           beShapeEventBase;
+
 #ifdef RANDR
     Bool          beRandr;        /**< Use RANDR support on BE server */
     Bool          beRandrPending;
diff --git a/hw/dmx/dmxdnd.c b/hw/dmx/dmxdnd.c
index 6218b66..0841db6 100644
--- a/hw/dmx/dmxdnd.c
+++ b/hw/dmx/dmxdnd.c
@@ -45,13 +45,16 @@
 #endif
 
 #include <xcb/xinput.h>
+#include <xcb/shape.h>
 
 struct _DMXDnDChild {
-    Window target;
-    Window wid;
-    BoxRec box;
-    int    map_state;
-    int    version;
+    Window    target;
+    Window    wid;
+    BoxRec    box;
+    RegionPtr boundingShape;
+    RegionPtr inputShape;
+    int       map_state;
+    int       version;
 };
 
 void
@@ -138,7 +141,27 @@ dmxBEDnDUpdateTarget (ScreenPtr pScreen)
 		dmxScreen->dndChildren[n].box.y1 <= dmxScreen->dndY &&
 		dmxScreen->dndChildren[n].box.x2 >  dmxScreen->dndX &&
 		dmxScreen->dndChildren[n].box.y2 >  dmxScreen->dndY)
-		break;
+	    {
+		BoxRec box;
+
+		if ((!dmxScreen->dndChildren[n].boundingShape ||
+		     POINT_IN_REGION (pScreen,
+				      dmxScreen->dndChildren[n].boundingShape,
+				      dmxScreen->dndX -
+				      dmxScreen->dndChildren[n].box.x1,
+				      dmxScreen->dndY -
+				      dmxScreen->dndChildren[n].box.y1,
+				      &box)) &&
+		    (!dmxScreen->dndChildren[n].inputShape ||
+		     POINT_IN_REGION (pScreen,
+				      dmxScreen->dndChildren[n].inputShape,
+				      dmxScreen->dndX -
+				      dmxScreen->dndChildren[n].box.x1,
+				      dmxScreen->dndY -
+				      dmxScreen->dndChildren[n].box.y1,
+				      &box)))
+		    break;
+	    }
 	}
 
 	if (n >= 0 && dmxScreen->dndChildren[n].version >= 3)
@@ -353,6 +376,103 @@ dmxDnDGeometryReply (ScreenPtr           pScreen,
     }
 }
 
+typedef struct dmx_xcb_shape_get_rectangles_reply_t {
+    uint8_t  response_type;
+    uint8_t  ordering;
+    uint16_t sequence;
+    uint32_t length;
+    uint32_t rectangles_len;
+    uint32_t pad1;
+    uint32_t pad2;
+    uint32_t pad3;
+    uint32_t pad4;
+    uint32_t pad5;
+} dmx_xcb_shape_get_rectangles_reply_t;
+
+static void
+dmxDnDBoundingShapeReply (ScreenPtr           pScreen,
+			  unsigned int        sequence,
+			  xcb_generic_reply_t *reply,
+			  xcb_generic_error_t *error,
+			  void                *data)
+{
+    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+    int           n = (int) data;
+    RegionPtr     pRegion;
+
+    if (!dmxScreen->dndChildren || n >= dmxScreen->dndNChildren)
+	return;
+
+    if (reply)
+    {
+	dmx_xcb_shape_get_rectangles_reply_t *xshape =
+	    (dmx_xcb_shape_get_rectangles_reply_t *) reply;
+
+	pRegion = RECTS_TO_REGION (pScreen,
+				   xshape->rectangles_len,
+				   (xRectangle *) (xshape + 1),
+				   xshape->ordering);
+
+	if (dmxScreen->dndChildren[n].boundingShape)
+	    REGION_DESTROY (pScreen, dmxScreen->dndChildren[n].boundingShape);
+
+	dmxScreen->dndChildren[n].boundingShape = pRegion;
+    }
+}
+
+static void
+dmxDnDInputShapeReply (ScreenPtr           pScreen,
+		       unsigned int        sequence,
+		       xcb_generic_reply_t *reply,
+		       xcb_generic_error_t *error,
+		       void                *data)
+{
+    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+    int           n = (int) data;
+    RegionPtr     pRegion;
+
+    if (!dmxScreen->dndChildren || n >= dmxScreen->dndNChildren)
+	return;
+
+    if (reply)
+    {
+	dmx_xcb_shape_get_rectangles_reply_t *xshape =
+	    (dmx_xcb_shape_get_rectangles_reply_t *) reply;
+
+	pRegion = RECTS_TO_REGION (pScreen,
+				   xshape->rectangles_len,
+				   (xRectangle *) (xshape + 1),
+				   xshape->ordering);
+
+	if (dmxScreen->dndChildren[n].inputShape)
+	    REGION_DESTROY (pScreen, dmxScreen->dndChildren[n].inputShape);
+
+	dmxScreen->dndChildren[n].inputShape = pRegion;
+    }
+}
+
+static void
+dmxDnDBoundingShapeUpdateReply (ScreenPtr           pScreen,
+				unsigned int        sequence,
+				xcb_generic_reply_t *reply,
+				xcb_generic_error_t *error,
+				void                *data)
+{
+    dmxDnDBoundingShapeReply (pScreen, sequence, reply, error, data);
+    dmxBEDnDUpdateTarget (pScreen);
+}
+
+static void
+dmxDnDInputShapeUpdateReply (ScreenPtr           pScreen,
+			     unsigned int        sequence,
+			     xcb_generic_reply_t *reply,
+			     xcb_generic_error_t *error,
+			     void                *data)
+{
+    dmxDnDInputShapeReply (pScreen, sequence, reply, error, data);
+    dmxBEDnDUpdateTarget (pScreen);
+}
+
 static void
 dmxDnDWindowAttributesReply (ScreenPtr           pScreen,
 			     unsigned int        sequence,
@@ -415,15 +535,18 @@ dmxDnDQueryTreeReply (ScreenPtr           pScreen,
 	{
 	    xcb_get_property_cookie_t          prop;
 	    xcb_get_geometry_cookie_t          geometry;
+	    xcb_shape_get_rectangles_cookie_t  shape;
 	    xcb_get_window_attributes_cookie_t attr;
 
-	    children[n].box.x1  = 0;
-	    children[n].box.y1  = 0;
-	    children[n].box.x2  = 0;
-	    children[n].box.y2  = 0;
-	    children[n].version = 0;
-	    children[n].target  = c[n];
-	    children[n].wid     = c[n];
+	    children[n].box.x1        = 0;
+	    children[n].box.y1        = 0;
+	    children[n].box.x2        = 0;
+	    children[n].box.y2        = 0;
+	    children[n].boundingShape = NULL;
+	    children[n].inputShape    = NULL;
+	    children[n].version       = 0;
+	    children[n].target        = c[n];
+	    children[n].wid           = c[n];
 
 	    prop = xcb_get_property (dmxScreen->connection,
 				     xFalse,
@@ -457,6 +580,22 @@ dmxDnDQueryTreeReply (ScreenPtr           pScreen,
 			   geometry.sequence,
 			   (void *) n);
 
+	    xcb_shape_select_input (dmxScreen->connection, c[n], 1);
+
+	    shape = xcb_shape_get_rectangles (dmxScreen->connection, c[n],
+					      ShapeBounding);
+	    dmxAddRequest (&dmxScreen->request,
+			   dmxDnDBoundingShapeReply,
+			   shape.sequence,
+			   (void *) n);
+
+	    shape = xcb_shape_get_rectangles (dmxScreen->connection, c[n],
+					      ShapeInput);
+	    dmxAddRequest (&dmxScreen->request,
+			   dmxDnDInputShapeReply,
+			   shape.sequence,
+			   (void *) n);
+
 	    attr = xcb_get_window_attributes (dmxScreen->connection, c[n]);
 	    dmxAddRequest (&dmxScreen->request,
 			   dmxDnDWindowAttributesReply,
@@ -505,6 +644,37 @@ dmxBEDnDUpdatePosition (ScreenPtr pScreen,
 }
 
 static void
+dmxDnDFreeChildren (ScreenPtr pScreen)
+{
+    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+
+    if (dmxScreen->dndChildren)
+    {
+	int i;
+
+	for (i = 0; i < dmxScreen->dndNChildren; i++)
+	{
+	    if (dmxScreen->dndChildren[i].boundingShape)
+		REGION_DESTROY (pScreen,
+				dmxScreen->dndChildren[i].boundingShape);
+
+	    if (dmxScreen->dndChildren[i].inputShape)
+		REGION_DESTROY (pScreen,
+				dmxScreen->dndChildren[i].inputShape);
+
+	    xcb_shape_select_input (dmxScreen->connection,
+				    dmxScreen->dndChildren[i].target,
+				    0);
+	}
+
+	xfree (dmxScreen->dndChildren);
+
+	dmxScreen->dndChildren  = NULL;
+	dmxScreen->dndNChildren = 0;
+    }
+}
+
+static void
 dmxBEDnDHideProxyWindow (ScreenPtr pScreen)
 {
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
@@ -523,13 +693,7 @@ dmxBEDnDHideProxyWindow (ScreenPtr pScreen)
 		      DefaultRootWindow (dmxScreen->beDisplay),
 		      dmxScreen->scrnEventMask);
 
-    if (dmxScreen->dndChildren)
-    {
-	xfree (dmxScreen->dndChildren);
-
-	dmxScreen->dndChildren  = NULL;
-	dmxScreen->dndNChildren = 0;
-    }
+    dmxDnDFreeChildren (pScreen);
 
     dmxScreen->dndSource = None;
     dmxScreen->queryTree.sequence = 0;
@@ -1284,8 +1448,9 @@ dmxScreenEventCheckDnD (ScreenPtr           pScreen,
 {
     DMXScreenInfo          *dmxScreen = &dmxScreens[pScreen->myNum];
     xcb_map_notify_event_t *xmap = (xcb_map_notify_event_t *) event;
+    int                    reltype, type = event->response_type & 0x7f;
 
-    switch (event->response_type & ~0x80) {
+    switch (type) {
     case XCB_MAP_NOTIFY:
 	if (xmap->window == dmxScreen->rootWin)
 	    return FALSE;
@@ -1295,14 +1460,8 @@ dmxScreenEventCheckDnD (ScreenPtr           pScreen,
     case XCB_CONFIGURE_NOTIFY:
 	if (xmap->event != DefaultRootWindow (dmxScreen->beDisplay))
 	    return FALSE;
-	
-	if (dmxScreen->dndChildren)
-	{
-	    xfree (dmxScreen->dndChildren);
 
-	    dmxScreen->dndChildren  = NULL;
-	    dmxScreen->dndNChildren = 0;
-	}
+	dmxDnDFreeChildren (pScreen);
 
 	dmxScreen->queryTree.sequence = 0;
 
@@ -1364,7 +1523,52 @@ dmxScreenEventCheckDnD (ScreenPtr           pScreen,
 	}
     } break;
     default:
-	return FALSE;
+	reltype = type - dmxScreen->beShapeEventBase;
+
+	switch (reltype) {
+	case XCB_SHAPE_NOTIFY: {
+	    xcb_shape_notify_event_t *xshape =
+		(xcb_shape_notify_event_t *) event;
+	    int                      i;
+
+	    for (i = 0; i < dmxScreen->dndNChildren; i++)
+		if (dmxScreen->dndChildren[i].target == xshape->affected_window)
+		    break;
+
+	    if (i < dmxScreen->dndNChildren)
+	    {
+		xcb_shape_get_rectangles_cookie_t shape;
+
+		switch (xshape->shape_kind) {
+		case ShapeBounding:
+		    shape = xcb_shape_get_rectangles (dmxScreen->connection,
+						      xshape->affected_window,
+						      ShapeBounding);
+		    dmxAddRequest (&dmxScreen->request,
+				   dmxDnDBoundingShapeUpdateReply,
+				   shape.sequence,
+				   (void *) i);
+
+		case ShapeInput:
+		    shape = xcb_shape_get_rectangles (dmxScreen->connection,
+						      xshape->affected_window,
+						      ShapeInput);
+		    dmxAddRequest (&dmxScreen->request,
+				   dmxDnDInputShapeUpdateReply,
+				   shape.sequence,
+				   (void *) i);
+		default:
+		    break;
+		}
+	    }
+	    else
+	    {
+		return FALSE;
+	    }
+	} break;
+	default:
+	    return FALSE;
+	}
     }
 
     return TRUE;
diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index 6aa3321..3764bf3 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -1433,6 +1433,8 @@ dmxAttachScreen (int                    idx,
     ScreenPtr     pScreen;
     DMXScreenInfo *dmxScreen;
     DMXScreenInfo oldDMXScreen;
+    Bool          beShape = FALSE;
+    int           errorBase;
 
     /* Return failure if dynamic addition/removal of screens is disabled */
     if (!dmxAddRemoveScreens) {
@@ -1493,6 +1495,23 @@ dmxAttachScreen (int                    idx,
 	return 1;
     }
 
+    XLIB_PROLOGUE (dmxScreens);
+    beShape = XShapeQueryExtension (dmxScreen->beDisplay,
+				    &dmxScreen->beShapeEventBase,
+				    &errorBase);
+    XLIB_EPILOGUE (dmxScreen);
+
+    if (!beShape)
+    {
+	dmxLogErrorSet (dmxWarning, errorSet, error, errorName,
+			"SHAPE extension missing");
+	dmxCloseDisplay (dmxScreen);
+
+	/* Restore the old screen */
+	*dmxScreen = oldDMXScreen;
+	return 1;
+    }
+
     if (!dmxScreen->scrnWin)
 	dmxScreen->scrnWin = DefaultRootWindow (dmxScreen->beDisplay);
 
commit d02da7afa1e051eac82f4e1c4f433cafb49ec345
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 13:59:52 2008 -0500

    Use IsPointerDevice and IsKeyboardDevice.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 8d75a43..91a52b6 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -72,8 +72,11 @@ dmxUpdateKeycodeMap (DeviceIntPtr pDevice)
     int               width = src->mapWidth;
     int               i;
 
-    if (!pDevice->isMaster && pDevice->u.master && pDevice->u.master->key)
-	dst = &pDevice->u.master->key->curKeySyms;
+    if (!pDevice->isMaster && pDevice->u.master)
+    {
+	if (IsKeyboardDevice (pDevice->u.master))
+	    dst = &pDevice->u.master->key->curKeySyms;
+    }
 
     if (dst->mapWidth < width)
 	width = dst->mapWidth;
@@ -193,7 +196,7 @@ dmxGetButtonDevice (DMXInputInfo *dmxInput,
     {
 	dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (dmxInput->devs[i]);
 
-	if (!dmxInput->devs[i]->button)
+	if (!IsPointerDevice (dmxInput->devs[i]))
 	    continue;
 	
 	if (deviceId >= 0)
@@ -479,7 +482,7 @@ dmxFakePointerGrab (DMXInputInfo *dmxInput)
 	if (!pDevice->isMaster && pDevice->u.master)
 	    pDevice = pDevice->u.master;
 
-	if (!pDevice->button)
+	if (!IsPointerDevice (pDevice))
 	    continue;
 
 	newGrab.device = pDevice;
@@ -503,7 +506,7 @@ dmxReleaseFakePointerGrab (DMXInputInfo *dmxInput)
 	if (!pDevice->isMaster && pDevice->u.master)
 	    pDevice = pDevice->u.master;
 
-	if (!pDevice->button)
+	if (!IsPointerDevice (pDevice))
 	    continue;
 
 	dmxDeactivateFakeGrab (pDevice);
@@ -543,7 +546,7 @@ dmxFakeKeyboardGrab (DMXInputInfo *dmxInput)
 	if (!pDevice->isMaster && pDevice->u.master)
 	    pDevice = pDevice->u.master;
 
-	if (!pDevice->key)
+	if (!IsKeyboardDevice (pDevice))
 	    continue;
 
 	newGrab.device = pDevice;
@@ -567,7 +570,7 @@ dmxReleaseFakeKeyboardGrab (DMXInputInfo *dmxInput)
 	if (!pDevice->isMaster && pDevice->u.master)
 	    pDevice = pDevice->u.master;
 
-	if (!pDevice->key)
+	if (!IsKeyboardDevice (pDevice))
 	    continue;
 
 	dmxDeactivateFakeGrab (pDevice);
@@ -588,7 +591,7 @@ dmxFakeMotion (DMXInputInfo *dmxInput,
     {
 	DeviceIntPtr pDevice = dmxInput->devs[i];
 
-	if (!pDevice->button)
+	if (!IsPointerDevice (pDevice))
 	    continue;
 
 	dmxUpdateSpritePosition (pDevice, x, y);
@@ -1550,7 +1553,7 @@ dmxInputGrabKeyboard (DMXInputInfo *dmxInput,
 	if (pExtDevice->u.master != pDevice)
 	    continue;
 
-	if (!pExtDevice->key)
+	if (!IsKeyboardDevice (pExtDevice))
 	    continue;
 
 	dmxDeviceGrabKeyboard (pExtDevice, pWindow);
@@ -1571,7 +1574,7 @@ dmxInputUngrabKeyboard (DMXInputInfo *dmxInput,
 	if (pExtDevice->u.master != pDevice)
 	    continue;
 
-	if (!pExtDevice->key)
+	if (!IsKeyboardDevice (pExtDevice))
 	    continue;
 
 	dmxDeviceUngrabKeyboard (pExtDevice);
@@ -1594,7 +1597,7 @@ dmxInputGrabPointer (DMXInputInfo *dmxInput,
 	if (pExtDevice->u.master != pDevice)
 	    continue;
 
-	if (!pExtDevice->button)
+	if (!IsPointerDevice (pExtDevice))
 	    continue;
 
 	dmxDeviceGrabPointer (pExtDevice,
@@ -1618,7 +1621,7 @@ dmxInputUngrabPointer (DMXInputInfo *dmxInput,
 	if (pExtDevice->u.master != pDevice)
 	    continue;
 
-	if (!pExtDevice->button)
+	if (!IsPointerDevice (pExtDevice))
 	    continue;
 
 	dmxDeviceUngrabPointer (pExtDevice);
@@ -1642,7 +1645,7 @@ dmxInputWarpPointer (DMXInputInfo *dmxInput,
 	if (pExtDevice->u.master != pDevice)
 	    continue;
 
-	if (!pExtDevice->button)
+	if (!IsPointerDevice (pExtDevice))
 	    continue;
 
 	if (!pDevPriv->active)
@@ -2229,9 +2232,9 @@ dmxInputDisable (DMXInputInfo *dmxInput)
         dmxLogInput (dmxInput, "Disable device id %d: %s\n",
 		     dmxInput->devs[i]->id, dmxInput->devs[i]->name);
 
-	if (dmxInput->devs[i]->key)
+	if (IsKeyboardDevice (dmxInput->devs[i]))
 	    dmxUpdateKeyState (dmxInput->devs[i], state);
-	else if (dmxInput->devs[i]->button)
+	else if (IsPointerDevice (dmxInput->devs[i]))
 	    dmxUpdateButtonState (dmxInput->devs[i], state);
 
         DisableDevice (dmxInput->devs[i]);
commit f773f0d55b39cdaa79cdef52872b665aa2f94f76
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 13:52:57 2008 -0500

    Maintain fake grab while keyboard is inactive.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index acdfffb..8d75a43 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -510,6 +510,70 @@ dmxReleaseFakePointerGrab (DMXInputInfo *dmxInput)
     }
 }
 
+static Bool
+dmxFakeKeyboardGrab (DMXInputInfo *dmxInput)
+{
+    DMXScreenInfo *dmxScreen = (DMXScreenInfo *) dmxInput;
+    WindowPtr     pWin = WindowTable[dmxScreen->index];
+    GrabRec       newGrab;
+    int           i;
+
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension)
+	pWin = WindowTable[0];
+#endif
+
+    memset (&newGrab, 0, sizeof (GrabRec));	    
+
+    newGrab.window       = pWin;
+    newGrab.resource     = 0;
+    newGrab.ownerEvents  = xFalse;
+    newGrab.cursor       = NULL;
+    newGrab.confineTo    = NullWindow;
+    newGrab.eventMask    = NoEventMask;
+    newGrab.genericMasks = NULL;
+    newGrab.next         = NULL;
+    newGrab.keyboardMode = GrabModeAsync;
+    newGrab.pointerMode  = GrabModeAsync;
+
+    for (i = 0; i < dmxInput->numDevs; i++)
+    {
+	DeviceIntPtr pDevice = dmxInput->devs[i];
+
+	if (!pDevice->isMaster && pDevice->u.master)
+	    pDevice = pDevice->u.master;
+
+	if (!pDevice->key)
+	    continue;
+
+	newGrab.device = pDevice;
+
+	if (!dmxActivateFakeGrab (pDevice, &newGrab))
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void
+dmxReleaseFakeKeyboardGrab (DMXInputInfo *dmxInput)
+{
+    int i;
+
+    for (i = 0; i < dmxInput->numDevs; i++)
+    {
+	DeviceIntPtr pDevice = dmxInput->devs[i];
+
+	if (!pDevice->isMaster && pDevice->u.master)
+	    pDevice = pDevice->u.master;
+
+	if (!pDevice->key)
+	    continue;
+
+	dmxDeactivateFakeGrab (pDevice);
+    }
+}
+
 Bool
 dmxFakeMotion (DMXInputInfo *dmxInput,
 	       int          x,
@@ -1163,6 +1227,8 @@ dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
     if (pDevPriv->active)
 	return;
 
+    dmxReleaseFakeKeyboardGrab (pDevPriv->dmxInput);
+
     pDevPriv->active = TRUE;
 
     if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
@@ -1210,7 +1276,14 @@ dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
 static void
 dmxDeviceKeyboardDeactivate (DeviceIntPtr pDevice)
 {
-    DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
+    dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+
+    if (!pDevPriv->active)
+	return;
+
+    pDevPriv->active = FALSE;
+
+    dmxFakeKeyboardGrab (pDevPriv->dmxInput);
 }
 
 static void
@@ -1273,11 +1346,10 @@ dmxUpdateKeyStateFromEvent (DeviceIntPtr pDevice,
 	y += pWin->drawable.y;
     }
 
-    dmxEndFakeMotion (&dmxScreen->input);
-
     pButtonDev = dmxGetPairedButtonDevice (pDevice);
-    if (pButtonDev)
+    if (pButtonDev && DMX_GET_DEVICE_PRIV (pButtonDev)->active)
     {
+	dmxEndFakeMotion (&dmxScreen->input);
 	dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
 	dmxUpdateSpritePosition (pButtonDev, x, y);
     }
commit a4794aa1681ae4de71d92d5804923c55cf953dcd
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 13:51:34 2008 -0500

    Fix device grabbing when xinerama is disabled.

diff --git a/hw/dmx/dmxgrab.c b/hw/dmx/dmxgrab.c
index ef29d7e..297ea31 100644
--- a/hw/dmx/dmxgrab.c
+++ b/hw/dmx/dmxgrab.c
@@ -79,8 +79,12 @@ dmxGrabKeyboard (DeviceIntPtr pDev,
 	}
 	else
 #endif
+
+	{
+	    pWin = pGrab->window;
 	    if (i != pWin->drawable.pScreen->myNum)
 		continue;
+	}
 
 	dmxInputGrabKeyboard (&dmxScreen->input, pDev, pWin);
     }
@@ -125,8 +129,12 @@ dmxUngrabKeyboard (DeviceIntPtr pDev,
 	}
 	else
 #endif
+
+	{
+	    pWin = pGrab->window;
 	    if (i != pWin->drawable.pScreen->myNum)
 		continue;
+	}
 
 	dmxInputUngrabKeyboard (&dmxScreen->input, pDev, pWin);
     }
@@ -212,8 +220,12 @@ dmxGrabPointer (DeviceIntPtr pDev,
 	}
 	else
 #endif
+
+	{
+	    pWin = pGrab->window;
 	    if (i != pWin->drawable.pScreen->myNum)
 		continue;
+	}
 
 	dmxInputGrabPointer (&dmxScreen->input,
 			     pDev,
@@ -262,8 +274,12 @@ dmxUngrabPointer (DeviceIntPtr pDev,
 	}
 	else
 #endif
+
+	{
+	    pWin = pGrab->window;
 	    if (i != pWin->drawable.pScreen->myNum)
 		continue;
+	}
 
 	dmxInputUngrabPointer (&dmxScreen->input, pDev, pWin);
     }
commit 03d44a4b8b265dbbffe91cd4cbeee91dcc45f768
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 11:25:14 2008 -0500

    dmxActivateFakePointerGrab -> dmxActivateFakeGrab and
    dmxDeactivateFakePointerGrab -> dmxDeactivateFakeGrab.

diff --git a/hw/dmx/dmxgrab.c b/hw/dmx/dmxgrab.c
index 7b2b419..ef29d7e 100644
--- a/hw/dmx/dmxgrab.c
+++ b/hw/dmx/dmxgrab.c
@@ -301,8 +301,8 @@ dmxDeactivatePointerGrab (DeviceIntPtr pDev)
 }
 
 Bool
-dmxActivateFakePointerGrab (DeviceIntPtr pDev,
-			    GrabPtr      pGrab)
+dmxActivateFakeGrab (DeviceIntPtr pDev,
+		     GrabPtr      pGrab)
 {
     dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
 
@@ -323,7 +323,7 @@ dmxActivateFakePointerGrab (DeviceIntPtr pDev,
 }
 
 void
-dmxDeactivateFakePointerGrab (DeviceIntPtr pDev)
+dmxDeactivateFakeGrab (DeviceIntPtr pDev)
 {
     dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
 
diff --git a/hw/dmx/dmxgrab.h b/hw/dmx/dmxgrab.h
index 29913f5..fe0dc0b 100644
--- a/hw/dmx/dmxgrab.h
+++ b/hw/dmx/dmxgrab.h
@@ -40,9 +40,9 @@ extern void dmxActivatePointerGrab (DeviceIntPtr pDev,
 				    Bool         autoGrab);
 extern void dmxDeactivatePointerGrab (DeviceIntPtr pDev);
 
-extern Bool dmxActivateFakePointerGrab (DeviceIntPtr pDev,
-					GrabPtr      pGrab);
-extern void dmxDeactivateFakePointerGrab (DeviceIntPtr pDev);
+extern Bool dmxActivateFakeGrab (DeviceIntPtr pDev,
+				 GrabPtr      pGrab);
+extern void dmxDeactivateFakeGrab (DeviceIntPtr pDev);
 
 extern void dmxInitGrabs (void);
 extern void dmxResetGrabs (void);
diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 8bfebc4..acdfffb 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -484,7 +484,7 @@ dmxFakePointerGrab (DMXInputInfo *dmxInput)
 
 	newGrab.device = pDevice;
 
-	if (!dmxActivateFakePointerGrab (pDevice, &newGrab))
+	if (!dmxActivateFakeGrab (pDevice, &newGrab))
 	    return FALSE;
     }
 
@@ -506,7 +506,7 @@ dmxReleaseFakePointerGrab (DMXInputInfo *dmxInput)
 	if (!pDevice->button)
 	    continue;
 
-	dmxDeactivateFakePointerGrab (pDevice);
+	dmxDeactivateFakeGrab (pDevice);
     }
 }
 
commit 0f2f7f081ad58980a9f7585888ca98d8d009438b
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 11:20:19 2008 -0500

    Maintain fake grab while pointer is inactive.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 1f5ae38..8bfebc4 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -873,6 +873,8 @@ dmxDevicePointerActivate (DeviceIntPtr pDevice)
 
     pDevPriv->active = TRUE;
 
+    dmxReleaseFakePointerGrab (pDevPriv->dmxInput);
+
     if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
 	pDevPriv->grab.sequence == 0)
     {
@@ -935,7 +937,14 @@ dmxDevicePointerActivate (DeviceIntPtr pDevice)
 static void
 dmxDevicePointerDeactivate (DeviceIntPtr pDevice)
 {
-    DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
+    dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+
+    if (!pDevPriv->active)
+	return;
+
+    pDevPriv->active = FALSE;
+
+    dmxFakePointerGrab (pDevPriv->dmxInput);
 }
 
 static void
commit 101dd8276340a65cd6c442d5c87355039d505f55
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 19 11:01:40 2008 -0500

    Add dmxFakePointerGrab and dmxReleaseFakePointerGrab.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index ddd7627..1f5ae38 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -446,10 +446,8 @@ dmxUpdateSpritePosition (DeviceIntPtr pDevice,
     return dmxButtonEvent (pDevice, 0, x, y, XCB_MOTION_NOTIFY);
 }
 
-Bool
-dmxFakeMotion (DMXInputInfo *dmxInput,
-	       int          x,
-	       int          y)
+static Bool
+dmxFakePointerGrab (DMXInputInfo *dmxInput)
 {
     DMXScreenInfo *dmxScreen = (DMXScreenInfo *) dmxInput;
     WindowPtr     pWin = WindowTable[dmxScreen->index];
@@ -490,36 +488,55 @@ dmxFakeMotion (DMXInputInfo *dmxInput,
 	    return FALSE;
     }
 
+    return TRUE;
+}
+
+static void
+dmxReleaseFakePointerGrab (DMXInputInfo *dmxInput)
+{
+    int i;
+
     for (i = 0; i < dmxInput->numDevs; i++)
     {
 	DeviceIntPtr pDevice = dmxInput->devs[i];
 
+	if (!pDevice->isMaster && pDevice->u.master)
+	    pDevice = pDevice->u.master;
+
 	if (!pDevice->button)
 	    continue;
 
-	dmxUpdateSpritePosition (pDevice, x, y);
+	dmxDeactivateFakePointerGrab (pDevice);
     }
-
-    return TRUE;
 }
 
-void
-dmxEndFakeMotion (DMXInputInfo *dmxInput)
+Bool
+dmxFakeMotion (DMXInputInfo *dmxInput,
+	       int          x,
+	       int          y)
 {
     int i;
 
+    if (!dmxFakePointerGrab (dmxInput))
+	return FALSE;
+
     for (i = 0; i < dmxInput->numDevs; i++)
     {
 	DeviceIntPtr pDevice = dmxInput->devs[i];
 
-	if (!pDevice->isMaster && pDevice->u.master)
-	    pDevice = pDevice->u.master;
-
 	if (!pDevice->button)
 	    continue;
 
-	dmxDeactivateFakePointerGrab (pDevice);
+	dmxUpdateSpritePosition (pDevice, x, y);
     }
+
+    return TRUE;
+}
+
+void
+dmxEndFakeMotion (DMXInputInfo *dmxInput)
+{
+    dmxReleaseFakePointerGrab (dmxInput);
 }
 
 static void
commit f05de44e824838b0debbfec6e8342639e97a3cbb
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 18 18:22:34 2008 -0500

    Never update proxy window geometry on backend server.

diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c
index 4e06fea..3a0ab16 100644
--- a/hw/dmx/dmxwindow.c
+++ b/hw/dmx/dmxwindow.c
@@ -263,6 +263,7 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
     XSetWindowAttributes  attribs;
     dmxWinPrivPtr         pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
     Window                win = None;
+    int                   x, y, w, h, bw;
 
     /* Avoid to create windows on back-end servers with virtual framebuffer */
     if (dmxScreen->virtualFb)
@@ -309,14 +310,29 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
        be created on top of the stack, so we must restack the windows */
     pWinPriv->restacked = (pWindow->prevSib != NullWindow);
 
+    if (pWindow != dmxScreen->pInputOverlayWin)
+    {
+	x = pWindow->origin.x - wBorderWidth(pWindow);
+	y = pWindow->origin.y - wBorderWidth(pWindow);
+	w = pWindow->drawable.width;
+	h = pWindow->drawable.height;
+	bw = pWindow->borderWidth;
+    }
+    else
+    {
+	x = y = -1;
+	w = h = 1;
+	bw = 0;
+    }
+
     XLIB_PROLOGUE (dmxScreen);
     win = XCreateWindow(dmxScreen->beDisplay,
 			parent,
-			pWindow->origin.x - wBorderWidth(pWindow),
-			pWindow->origin.y - wBorderWidth(pWindow),
-			pWindow->drawable.width,
-			pWindow->drawable.height,
-			pWindow->borderWidth,
+			x,
+			y,
+			w,
+			h,
+			bw,
 			pWindow->drawable.depth,
 			pWindow->drawable.class,
 			pWinPriv->visual,
@@ -514,7 +530,7 @@ Bool dmxPositionWindow(WindowPtr pWindow, int x, int y)
        been created yet, create it and map it */
     if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
 	dmxCreateAndRealizeWindow(pWindow, TRUE);
-    } else if (pWinPriv->window) {
+    } else if (pWinPriv->window && pWindow != dmxScreen->pInputOverlayWin) {
 	/* Position window on back-end server */
 	m = CWX | CWY | CWWidth | CWHeight;
 	c.x = pWindow->origin.x - wBorderWidth(pWindow);
@@ -897,7 +913,7 @@ void dmxResizeWindow(WindowPtr pWindow, int x, int y,
        been created yet, create it and map it */
     if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
 	dmxCreateAndRealizeWindow(pWindow, TRUE);
-    } else if (pWinPriv->window) {
+    } else if (pWinPriv->window && pWindow != dmxScreen->pInputOverlayWin) {
 	/* Handle resizing on back-end server */
 	m = CWX | CWY | CWWidth | CWHeight;
 	c.x = pWindow->origin.x - wBorderWidth(pWindow);
@@ -960,7 +976,7 @@ void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width)
 
     /* NOTE: Do we need to check for on/off screen here? */
 
-    if (pWinPriv->window) {
+    if (pWinPriv->window && pWindow != dmxScreen->pInputOverlayWin) {
 	/* Handle border width change on back-end server */
 	m = CWBorderWidth;
 	c.border_width = width;
commit 0a4fa666b5f264769858cf12ecec4f1f4978020d
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 18 18:20:55 2008 -0500

    Check if reply != NULL.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 3714745..ddd7627 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -820,7 +820,7 @@ dmxDevicePointerReplyCheck (DeviceIntPtr        pDevice,
 
     if (request == pDevPriv->grab.sequence)
     {
-	if (reply->response_type == 1)
+	if (reply)
 	{
 	    if (pDevPriv->deviceId >= 0)
 	    {
commit 8761e963d0859b94f05c060ddc0acc1b7c207b8b
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 18 17:19:29 2008 -0500

    Position input overlay window at -1, -1.

diff --git a/hw/dmx/dmxcb.c b/hw/dmx/dmxcb.c
index 1dd5e2f..3a45f87 100644
--- a/hw/dmx/dmxcb.c
+++ b/hw/dmx/dmxcb.c
@@ -117,7 +117,7 @@ dmxCreateInputOverlayWindow (void)
 
 	FOR_NSCREENS_BACKWARD(j) {
 	    pWin = CreateWindow (newWin->info[j].id, WindowTable[j],
-				 0, 0, 1, 1, 0, InputOnly, 
+				 -1, -1, 1, 1, 0, InputOnly, 
 				 CWOverrideRedirect, &overrideRedirect,
 				 0, serverClient, CopyFromParent, 
 				 &result);
@@ -137,7 +137,7 @@ dmxCreateInputOverlayWindow (void)
 	
     {
 	pWin = CreateWindow (inputOverlayWid, WindowTable[0],
-			     0, 0, 1, 1, 0, InputOnly, 
+			     -1, -1, 1, 1, 0, InputOnly, 
 			     CWOverrideRedirect, &overrideRedirect,
 			     0, serverClient, CopyFromParent, 
 			     &result);
commit b6dd1a68b612afb5c994b08b4556930081282cb7
Author: David Reveman <davidr at novell.com>
Date:   Wed Nov 12 09:32:26 2008 -0500

    Cleanup dmxcursor.c and implement proper pointer warping.

diff --git a/hw/dmx/dmxcursor.c b/hw/dmx/dmxcursor.c
index 6808a20..59bfa73 100644
--- a/hw/dmx/dmxcursor.c
+++ b/hw/dmx/dmxcursor.c
@@ -33,51 +33,10 @@
  *
  */
 
-/** \file
- * This file contains code than supports cursor movement, including the
- * code that initializes and reinitializes the screen positions and
- * computes screen overlap.
- *
- * "This code is based very closely on the XFree86 equivalent
- * (xfree86/common/xf86Cursor.c)."  --David Dawes.
- *
- * "This code was then extensively re-written, as explained here."
- * --Rik Faith
- *
- * The code in xf86Cursor.c used edge lists to implement the
- * CursorOffScreen function.  The edge list computation was complex
- * (especially in the face of arbitrarily overlapping screens) compared
- * with the speed savings in the CursorOffScreen function.  The new
- * implementation has erred on the side of correctness, readability, and
- * maintainability over efficiency.  For the common (non-edge) case, the
- * dmxCursorOffScreen function does avoid a loop over all the screens.
- * When the cursor has left the screen, all the screens are searched,
- * and the first screen (in dmxScreens order) containing the cursor will
- * be returned.  If run-time profiling shows that this routing is a
- * performance bottle-neck, then an edge list may have to be
- * reimplemented.  An edge list algorithm is O(edges) whereas the new
- * algorithm is O(dmxNumScreens).  Since edges is usually 1-3 and
- * dmxNumScreens may be 30-60 for large backend walls, this trade off
- * may be compelling.
- *
- * The xf86InitOrigins routine uses bit masks during the computation and
- * is therefore limited to the length of a word (e.g., 32 or 64 bits)
- * screens.  Because Xdmx is expected to be used with a large number of
- * backend displays, this limitation was removed.  The new
- * implementation has erred on the side of readability over efficiency,
- * using the dmxSL* routines to manage a screen list instead of a
- * bitmap, and a function call to decrease the length of the main
- * routine.  Both algorithms are of the same order, and both are called
- * only at server generation time, so trading clarity and long-term
- * maintainability for efficiency does not seem justified in this case.
- */
-
 #ifdef HAVE_DMX_CONFIG_H
 #include <dmx-config.h>
 #endif
 
-#define DMX_CURSOR_DEBUG 0
-
 #include "dmx.h"
 #include "dmxsync.h"
 #include "dmxcursor.h"
@@ -90,50 +49,38 @@
 #include "windowstr.h"
 #include "globals.h"
 #include "cursorstr.h"
-#include "dixevents.h"          /* For GetSpriteCursor() */
-
-#if DMX_CURSOR_DEBUG
-#define DMXDBG0(f)               dmxLog(dmxDebug,f)
-#define DMXDBG1(f,a)             dmxLog(dmxDebug,f,a)
-#define DMXDBG2(f,a,b)           dmxLog(dmxDebug,f,a,b)
-#define DMXDBG3(f,a,b,c)         dmxLog(dmxDebug,f,a,b,c)
-#define DMXDBG4(f,a,b,c,d)       dmxLog(dmxDebug,f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e)     dmxLog(dmxDebug,f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g)   dmxLog(dmxDebug,f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
-#else
-#define DMXDBG0(f)
-#define DMXDBG1(f,a)
-#define DMXDBG2(f,a,b)
-#define DMXDBG3(f,a,b,c)
-#define DMXDBG4(f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h)
-#endif
 
-/** Initialize the private area for the cursor functions. */
-Bool dmxInitCursor(ScreenPtr pScreen)
+Bool
+dmxInitCursor (ScreenPtr pScreen)
 {
-    if (!dixRequestPrivate(CursorScreenKey(pScreen), sizeof(dmxCursorPrivRec)))
+    if (!dixRequestPrivate (CursorScreenKey (pScreen), sizeof (dmxCursorPrivRec)))
 	return FALSE;
 
-    if (!dixRequestPrivate (dmxDevicePrivateKey, sizeof(dmxDevicePrivRec)))
+    if (!dixRequestPrivate (dmxDevicePrivateKey, sizeof (dmxDevicePrivRec)))
 	return FALSE;
 
     return TRUE;
 }
 
-static Bool dmxCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+static Bool
+dmxCursorOffScreen (ScreenPtr *ppScreen,
+		    int       *x,
+		    int       *y)
 {
     return FALSE;
 }
 
-static void dmxCrossScreen(ScreenPtr pScreen, Bool entering)
+static void
+dmxCrossScreen (ScreenPtr pScreen,
+		Bool      entering)
 {
 }
 
-static void dmxWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+static void
+dmxWarpCursor (DeviceIntPtr pDev,
+	       ScreenPtr    pScreen,
+	       int          x,
+	       int          y)
 {
     int i;
 
@@ -144,10 +91,7 @@ static void dmxWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 	if (!dmxScreen->beDisplay)
 	    continue;
 
-	XLIB_PROLOGUE (dmxScreen);
-	XWarpPointer (dmxScreen->beDisplay, None, dmxScreen->scrnWin,
-		      0, 0, 0, 0, x, y);
-	XLIB_EPILOGUE (dmxScreen);
+	dmxInputWarpPointer (&dmxScreen->input, pDev, x, y);
     }
 }
 
@@ -166,7 +110,9 @@ dmxCreateARGBCursor (ScreenPtr pScreen,
 #endif
 
 /** Create \a pCursor on the back-end associated with \a pScreen. */
-void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
+void
+dmxBECreateCursor (ScreenPtr pScreen,
+		   CursorPtr pCursor)
 {
     DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
     dmxCursorPrivPtr  pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
@@ -291,33 +237,36 @@ void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
     XLIB_EPILOGUE (dmxScreen);
 }
 
-static Bool _dmxRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+static Bool
+_dmxRealizeCursor (ScreenPtr pScreen,
+		   CursorPtr pCursor)
 {
     DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
-    dmxCursorPrivPtr  pCursorPriv;
-
-    DMXDBG2("_dmxRealizeCursor(%d,%p)\n", pScreen->myNum, pCursor);
+    dmxCursorPrivPtr pCursorPriv;
 
-    pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
-    pCursorPriv->cursor = (Cursor)0;
+    pCursorPriv = DMX_GET_CURSOR_PRIV (pCursor, pScreen);
+    pCursorPriv->cursor = (Cursor) 0;
 
     if (dmxScreen->beDisplay)
-	dmxBECreateCursor(pScreen, pCursor);
+	dmxBECreateCursor (pScreen, pCursor);
 
     return TRUE;
 }
 
 /** Free \a pCursor on the back-end associated with \a pScreen. */
-Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+Bool
+dmxBEFreeCursor (ScreenPtr pScreen,
+		 CursorPtr pCursor)
 {
     DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
-    dmxCursorPrivPtr  pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
+    dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV (pCursor, pScreen);
 
     if (pCursorPriv->cursor)
     {
 	XLIB_PROLOGUE (dmxScreen);
-	XFreeCursor(dmxScreen->beDisplay, pCursorPriv->cursor);
+	XFreeCursor (dmxScreen->beDisplay, pCursorPriv->cursor);
 	XLIB_EPILOGUE (dmxScreen);
+
 	pCursorPriv->cursor = (Cursor) 0;
 
 	if (IsAnimCur (pCursor))
@@ -336,18 +285,17 @@ Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
 }
 
 static Bool
-_dmxUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+_dmxUnrealizeCursor (ScreenPtr pScreen,
+		     CursorPtr pCursor)
 {
-    DMXDBG2("_dmxUnrealizeCursor(%d,%p)\n",
-            pScreen->myNum, pCursor);
-
-    dmxBEFreeCursor(pScreen, pCursor);
-
+    dmxBEFreeCursor (pScreen, pCursor);
     return TRUE;
 }
 
 static Bool
-dmxRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+dmxRealizeCursor (DeviceIntPtr pDev,
+		  ScreenPtr    pScreen,
+		  CursorPtr    pCursor)
 {
     if (pDev == inputInfo.pointer)
 	return _dmxRealizeCursor (pScreen, pCursor);
diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 3964b15..3714745 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -543,6 +543,26 @@ dmxInputGrabDeviceReply (ScreenPtr           pScreen,
 }
 
 /* not in xcb-xinput yet */
+
+#define DMX_XCB_WARP_DEVICE_POINTER 41
+
+typedef struct dmx_xcb_warp_device_pointer_request_t {
+    uint8_t      major_opcode;
+    uint8_t      minor_opcode;
+    uint16_t     length;
+    xcb_window_t src_win;
+    xcb_window_t dst_win;
+    int16_t      src_x;
+    int16_t      src_y;
+    uint16_t     src_width;
+    uint16_t     src_height;
+    int16_t      dst_x;
+    int16_t      dst_y;
+    uint8_t      deviceid;
+    uint8_t      pad0;
+    uint16_t     pad1;
+} dmx_xcb_warp_device_pointer_request_t;
+
 #define DMX_XCB_INPUT_EXTENDED_GRAB_DEVICE 45
 
 typedef struct dmx_xcb_input_extended_grab_device_request_t {
@@ -1507,6 +1527,64 @@ dmxInputUngrabPointer (DMXInputInfo *dmxInput,
     }
 }
 
+void
+dmxInputWarpPointer (DMXInputInfo *dmxInput,
+		     DeviceIntPtr pDevice,
+		     int          x,
+		     int          y)
+{
+    DMXScreenInfo *dmxScreen = (DMXScreenInfo *) dmxInput;
+    int           i;
+
+    for (i = 0; i < dmxInput->numDevs; i++)
+    {
+	DeviceIntPtr     pExtDevice = dmxInput->devs[i];
+	dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pExtDevice);
+
+	if (pExtDevice->u.master != pDevice)
+	    continue;
+
+	if (!pExtDevice->button)
+	    continue;
+
+	if (!pDevPriv->active)
+	    continue;
+
+	if (pDevPriv->deviceId >= 0)
+	{
+	    dmx_xcb_warp_device_pointer_request_t warp = {
+		.src_win  = dmxScreen->rootWin,
+		.dst_win  = dmxScreen->rootWin,
+		.dst_x    = x,
+		.dst_y    = y,
+		.deviceid = pDevPriv->deviceId
+	    };
+	    xcb_protocol_request_t request = {
+		1,
+		&xcb_input_id,
+		DMX_XCB_WARP_DEVICE_POINTER,
+		FALSE
+	    };
+	    struct iovec vector[] =  {
+		{ &warp, sizeof (warp) }
+	    };
+
+	    xcb_send_request (dmxScreen->connection,
+			      0,
+			      vector,
+			      &request);
+	}
+	else
+	{
+	    xcb_warp_pointer (dmxScreen->connection,
+			      dmxScreen->rootWin, dmxScreen->rootWin,
+			      0, 0,
+			      0, 0,
+			      x, y);
+	}
+    }
+}
+
 static void
 dmxKeyboardBell (int          volume,
 		 DeviceIntPtr pDevice,
diff --git a/hw/dmx/dmxinput.h b/hw/dmx/dmxinput.h
index b0f217a..caacab0 100644
--- a/hw/dmx/dmxinput.h
+++ b/hw/dmx/dmxinput.h
@@ -94,6 +94,12 @@ dmxInputUngrabPointer (DMXInputInfo *dmxInput,
 		       DeviceIntPtr pDevice,
 		       WindowPtr    pWindow);
 
+void
+dmxInputWarpPointer (DMXInputInfo *dmxInput,
+		     DeviceIntPtr pDevice,
+		     int          x,
+		     int          y);
+
 int
 dmxInputEnable (DMXInputInfo *dmxInput);
 
commit 2681b50b44e5b8f14165835f4b5e1303663c4434
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 17:05:28 2008 -0500

    Use a private system bus connection to properly handle
    teardown and reconnect during server reset.

diff --git a/config/dbus-core.c b/config/dbus-core.c
index b349c6e..8b97e24 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -85,7 +85,7 @@ teardown(void)
      * completeness.  But then it gets awkward, given that you can't
      * guarantee that they'll be called ... */
     if (bus_info.connection)
-        dbus_connection_unref(bus_info.connection);
+        dbus_connection_close(bus_info.connection);
 
     RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
     if (bus_info.fd != -1)
@@ -140,7 +140,7 @@ connect_to_bus(void)
     struct config_dbus_core_hook *hook;
 
     dbus_error_init(&error);
-    bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+    bus_info.connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
     if (!bus_info.connection || dbus_error_is_set(&error)) {
         DebugF("[config/dbus-core] error connecting to system bus: %s (%s)\n",
                error.name, error.message);
commit 9fd9c35af06182d802b31936cc89e334fd85b56d
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 17:03:28 2008 -0500

    Release randr mode references properly.

diff --git a/hw/dmx/dmxrandr.c b/hw/dmx/dmxrandr.c
index 41e7624..f0b69fb 100644
--- a/hw/dmx/dmxrandr.c
+++ b/hw/dmx/dmxrandr.c
@@ -225,7 +225,12 @@ dmxRRUpdateCrtc (ScreenPtr	    pScreen,
     XLIB_EPILOGUE (dmxScreen);
 
     if (!gamma)
+    {
+	if (mode)
+	    RRModeDestroy (mode);
+	
 	return FALSE;
+    }
 
     RRCrtcGammaSet (crtc, gamma->red, gamma->green, gamma->blue);
 
@@ -236,6 +241,9 @@ dmxRRUpdateCrtc (ScreenPtr	    pScreen,
     if (outputs)
 	xfree (outputs);
 
+    if (mode)
+	RRModeDestroy (mode);
+
     XRRFreeCrtcInfo (c);
 
     return TRUE;
@@ -634,6 +642,9 @@ dmxRRGetInfo (ScreenPtr pScreen,
 			      dmxScreen->rootX, dmxScreen->rootY,
 			      RR_Rotate_0, 1,
 			      &pScrPriv->outputs[baseOutput]);
+
+		if (mode)
+		    RRModeDestroy (mode);
 	    }
 	    else
 	    {
commit 893d5ddda929e323f82f211147390fb153eff52b
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 17:02:09 2008 -0500

    Terminate launched display when closing first screen.

diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index 745d3ce..da3c579 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -60,6 +60,7 @@
 #include "dmxatom.h"
 #include "dmxshm.h"
 #include "dmxdnd.h"
+#include "dmxlaunch.h"
 
 #ifdef PANORAMIX
 #include "panoramiX.h"
@@ -1405,6 +1406,9 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
 	dmxScreen->bePixmapFormats = NULL;
     }
 
+    if (idx == 0)
+	dmxAbortDisplay ();
+
     DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
     return pScreen->CloseScreen(idx, pScreen);
 }
commit 0e937cb11bfd1eabd573e2fb4f1ab452213ba9a8
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 17:00:26 2008 -0500

    Replace HAVE_SIGPROCMASK with SIG_BLOCK and make sure
    display can be re-launched at server reset.

diff --git a/hw/dmx/dmxlaunch.c b/hw/dmx/dmxlaunch.c
index b10db89..4cab118 100644
--- a/hw/dmx/dmxlaunch.c
+++ b/hw/dmx/dmxlaunch.c
@@ -135,6 +135,8 @@ dmxAbortDisplay (void)
 
     if (xbeAuth)
 	unlink (xbeAuth);
+
+    xbePid = 0;
 }
 
 static void
@@ -148,13 +150,13 @@ static void
 sigUsr1Jump (int sig)
 {
 
-#ifdef HAVE_SIGPROCMASK
+#ifdef SIG_BLOCK
     sigset_t set;
 #endif
 
     signal (sig, sigUsr1Waiting);
 
-#ifdef HAVE_SIGPROCMASK
+#ifdef SIG_BLOCK
     sigemptyset (&set);
     sigaddset (&set, SIGUSR1);
     sigprocmask (SIG_UNBLOCK, &set, NULL);
@@ -285,7 +287,16 @@ dmxLaunchDisplay (int argc, char *argv[], int index, char *vt)
     int		 mask;
 
     if (xbePid)
-	return TRUE;
+	return FALSE;
+
+    if (xbeArgv)
+    {
+	free (xbeArgv);
+	xbeArgv = NULL;
+	nXbeArgv = 0;
+    }
+
+    receivedUsr1 = 0;
 
     strcpy (xbeAuthBuf, xbeAuthTempl);
     mask = umask (0077);
commit 5946cdf71abc7e2f1390e4badea93b0a8e086045
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 11:34:57 2008 -0500

    Fix input device grab handling.
    
    - only try to grab back-end server devices when they are active
    - try to establish existing grab when device becomes active

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 7762820..3964b15 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -44,6 +44,11 @@
 #include "XIstubs.h"
 #include "xace.h"
 
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
 #include <X11/keysym.h>
 #include <xcb/xinput.h>
 
@@ -585,6 +590,9 @@ dmxDeviceGrabKeyboard (DeviceIntPtr pDevice,
     DMXScreenInfo    *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
     Window           window = (DMX_GET_WINDOW_PRIV (pWindow))->window;
 
+    if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS && !pDevPriv->active)
+	return;
+
     if (pDevPriv->deviceId >= 0)
     {
 	dmx_xcb_input_extended_grab_device_request_t grab = {
@@ -649,6 +657,8 @@ dmxDeviceUngrabKeyboard (DeviceIntPtr pDevice)
     {
 	xcb_ungrab_keyboard (dmxScreen->connection, 0);
     }
+
+    pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
 }
 
 static Bool
@@ -660,8 +670,6 @@ dmxDeviceKeyboardReplyCheck (DeviceIntPtr        pDevice,
 
     if (request == pDevPriv->grab.sequence)
     {
-	xcb_grab_status_t status = XCB_GRAB_STATUS_FROZEN;
-
 	if (reply)
 	{
 	    if (pDevPriv->deviceId >= 0)
@@ -669,22 +677,17 @@ dmxDeviceKeyboardReplyCheck (DeviceIntPtr        pDevice,
 		xcb_input_grab_device_reply_t *xgrab =
 		    (xcb_input_grab_device_reply_t *) reply;
 
-		status = xgrab->status;
+		pDevPriv->grabStatus = xgrab->status;
 	    }
 	    else
 	    {
 		xcb_grab_keyboard_reply_t *xgrab =
 		    (xcb_grab_keyboard_reply_t *) reply;
 
-		status = xgrab->status;
+		pDevPriv->grabStatus = xgrab->status;
 	    }
 	}
 
-	if (status == XCB_GRAB_STATUS_SUCCESS)
-	{
-	    /* TODO: track state of grabs */
-	}
-
 	pDevPriv->grab.sequence = 0;
 	return TRUE;
     }
@@ -705,6 +708,9 @@ dmxDeviceGrabPointer (DeviceIntPtr pDevice,
     Window           confineTo = None;
     Cursor           cursor = None;
 
+    if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS && !pDevPriv->active)
+	return;
+
     if (pConfineTo)
 	confineTo = (DMX_GET_WINDOW_PRIV (pConfineTo))->window;
 
@@ -781,6 +787,8 @@ dmxDeviceUngrabPointer (DeviceIntPtr pDevice)
     {
 	xcb_ungrab_pointer (dmxScreen->connection, 0);
     }
+
+    pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
 }
 
 static Bool
@@ -792,8 +800,6 @@ dmxDevicePointerReplyCheck (DeviceIntPtr        pDevice,
 
     if (request == pDevPriv->grab.sequence)
     {
-	xcb_grab_status_t status = XCB_GRAB_STATUS_FROZEN;
-
 	if (reply->response_type == 1)
 	{
 	    if (pDevPriv->deviceId >= 0)
@@ -801,22 +807,17 @@ dmxDevicePointerReplyCheck (DeviceIntPtr        pDevice,
 		xcb_input_grab_device_reply_t *xgrab =
 		    (xcb_input_grab_device_reply_t *) reply;
 
-		status = xgrab->status;
+		pDevPriv->grabStatus = xgrab->status;
 	    }
 	    else
 	    {
 		xcb_grab_pointer_reply_t *xgrab =
 		    (xcb_grab_pointer_reply_t *) reply;
 
-		status = xgrab->status;
+		pDevPriv->grabStatus = xgrab->status;
 	    }
 	}
 
-	if (status == XCB_GRAB_STATUS_SUCCESS)
-	{
-	    /* TODO: track state of grabs */
-	}
-
 	pDevPriv->grab.sequence = 0;
 	return TRUE;
     }
@@ -828,11 +829,70 @@ static void
 dmxDevicePointerActivate (DeviceIntPtr pDevice)
 {
     dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+    DMXScreenInfo    *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
 
     if (pDevPriv->active)
 	return;
 
     pDevPriv->active = TRUE;
+
+    if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
+	pDevPriv->grab.sequence == 0)
+    {
+	DeviceIntPtr pMaster = pDevice;
+
+	if (!pDevice->isMaster && pDevice->u.master)
+	    pMaster = pDevice->u.master;
+
+	if (pMaster->deviceGrab.grab)
+	{
+	    GrabPtr   pGrab = pMaster->deviceGrab.grab;
+	    WindowPtr pWin, pConfineTo = NULL;
+
+#ifdef PANORAMIX
+	    if (!noPanoramiXExtension)
+	    {
+		PanoramiXRes *win, *confineToWin = NULL;
+		int          i = dmxScreen->index;
+
+		if (!(win = (PanoramiXRes *)
+		      SecurityLookupIDByType(
+			  serverClient, pGrab->window->drawable.id, XRT_WINDOW,
+			  DixGetAttrAccess)))
+		    return;
+		if (pGrab->confineTo)
+		    if (!(confineToWin = (PanoramiXRes *)
+			  SecurityLookupIDByType(
+			      serverClient, pGrab->confineTo->drawable.id,
+			      XRT_WINDOW, DixGetAttrAccess)))
+			return;
+
+		if (dixLookupWindow (&pWin,
+				     win->info[i].id,
+				     serverClient,
+				     DixGetAttrAccess) != Success)
+		    return;
+
+		if (confineToWin)
+		    if (dixLookupWindow (&pConfineTo,
+					 confineToWin->info[i].id,
+					 serverClient,
+					 DixGetAttrAccess) != Success)
+			return;
+	    }
+	    else
+#endif
+	    {
+		pWin       = pGrab->window;
+		pConfineTo = pGrab->confineTo;
+	    }
+
+	    dmxDeviceGrabPointer (pDevice,
+				  pWin,
+				  pConfineTo,
+				  pGrab->cursor);
+	}
+    }
 }
 
 static void
@@ -898,10 +958,10 @@ dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
 	y += pWin->drawable.y;
     }
 
-    dmxDevicePointerActivate (pDevice);
     dmxEndFakeMotion (&dmxScreen->input);
     dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
     dmxUpdateSpritePosition (pDevice, x, y);
+    dmxDevicePointerActivate (pDevice);
 }
 
 static Bool
@@ -1052,11 +1112,53 @@ static void
 dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
 {
     dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+    DMXScreenInfo    *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
 
     if (pDevPriv->active)
 	return;
 
     pDevPriv->active = TRUE;
+
+    if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
+	pDevPriv->grab.sequence == 0)
+    {
+	DeviceIntPtr pMaster = pDevice;
+
+	if (!pDevice->isMaster && pDevice->u.master)
+	    pMaster = pDevice->u.master;
+
+	if (pMaster->deviceGrab.grab)
+	{
+	    GrabPtr   pGrab = pMaster->deviceGrab.grab;
+	    WindowPtr pWin;
+
+#ifdef PANORAMIX
+	    if (!noPanoramiXExtension)
+	    {
+		PanoramiXRes *win;
+		int          i = dmxScreen->index;
+
+		if (!(win = (PanoramiXRes *)
+		      SecurityLookupIDByType(
+			  serverClient, pGrab->window->drawable.id, XRT_WINDOW,
+			  DixGetAttrAccess)))
+		    return;
+
+		if (dixLookupWindow (&pWin,
+				     win->info[i].id,
+				     serverClient,
+				     DixGetAttrAccess) != Success)
+		    return;
+	    }
+	    else
+#endif
+	    {
+		pWin = pGrab->window;
+	    }
+
+	    dmxDeviceGrabKeyboard (pDevice, pWin);
+	}
+    }
 }
 
 static void
@@ -1777,6 +1879,7 @@ dmxAddInputDevice (DMXInputInfo *dmxInput,
 	pDevPriv->masterId   = masterId;
 	pDevPriv->device     = NULL;
 	pDevPriv->fakeGrab   = xFalse;
+	pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
 	pDevPriv->active     = xFalse;
 	pDevPriv->EventCheck = EventCheck;
 	pDevPriv->ReplyCheck = ReplyCheck;
diff --git a/hw/dmx/dmxinput.h b/hw/dmx/dmxinput.h
index 42ae3be..b0f217a 100644
--- a/hw/dmx/dmxinput.h
+++ b/hw/dmx/dmxinput.h
@@ -39,6 +39,7 @@ typedef struct _dmxDevicePriv {
     KeySymsRec               keySyms;
     KeyCode                  *keycode;
     xcb_void_cookie_t        grab;
+    int                      grabStatus;
     Bool                     fakeGrab;
     Bool                     active;
 
commit b27fbaf53e4ba0ac7bc3da78bd6b1d26349d9f7c
Author: David Reveman <davidr at novell.com>
Date:   Tue Nov 11 10:47:29 2008 -0500

    Keep track of input focus and pointer location.

diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 96e3b03..7762820 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -47,11 +47,12 @@
 #include <X11/keysym.h>
 #include <xcb/xinput.h>
 
-#define DMX_KEYBOARD_EVENT_MASK				\
-    (KeyPressMask | KeyReleaseMask | KeymapStateMask)
+#define DMX_KEYBOARD_EVENT_MASK					        \
+    (KeyPressMask | KeyReleaseMask | KeymapStateMask | FocusChangeMask)
 
-#define DMX_POINTER_EVENT_MASK					\
-    (ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
+#define DMX_POINTER_EVENT_MASK				       \
+    (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
+     LeaveWindowMask)
 
 static EventListPtr dmxEvents = NULL;
 
@@ -555,6 +556,27 @@ typedef struct dmx_xcb_input_extended_grab_device_request_t {
     uint16_t        generic_event_count;
 } dmx_xcb_input_extended_grab_device_request_t;
 
+#define DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY 17
+
+typedef struct dmx_xcb_input_device_state_notify_event_t {
+    uint8_t         response_type;
+    uint8_t         detail;
+    uint16_t        sequence;
+    xcb_timestamp_t time;
+    xcb_window_t    root;
+    xcb_window_t    event;
+    xcb_window_t    child;
+    int16_t         root_x;
+    int16_t         root_y;
+    int16_t         event_x;
+    int16_t         event_y;
+    uint16_t        state;
+    uint8_t         mode;
+    uint8_t         device_id;
+} dmx_xcb_input_device_state_notify_event_t;
+
+typedef xcb_input_focus_in_event_t dmx_xcb_input_focus_out_event_t;
+
 static void
 dmxDeviceGrabKeyboard (DeviceIntPtr pDevice,
 		       WindowPtr    pWindow)
@@ -803,6 +825,23 @@ dmxDevicePointerReplyCheck (DeviceIntPtr        pDevice,
 }
 
 static void
+dmxDevicePointerActivate (DeviceIntPtr pDevice)
+{
+    dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+
+    if (pDevPriv->active)
+	return;
+
+    pDevPriv->active = TRUE;
+}
+
+static void
+dmxDevicePointerDeactivate (DeviceIntPtr pDevice)
+{
+    DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
+}
+
+static void
 dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
 			  xcb_window_t event,
 			  int          x,
@@ -859,6 +898,7 @@ dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
 	y += pWin->drawable.y;
     }
 
+    dmxDevicePointerActivate (pDevice);
     dmxEndFakeMotion (&dmxScreen->input);
     dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
     dmxUpdateSpritePosition (pDevice, x, y);
@@ -901,6 +941,13 @@ dmxDevicePointerEventCheck (DeviceIntPtr        pDevice,
 			      xbutton->detail,
 			      type);
     } break;
+    case XCB_LEAVE_NOTIFY: {
+	xcb_leave_notify_event_t *xcrossing =
+	    (xcb_leave_notify_event_t *) event;
+
+	if (xcrossing->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+	    dmxDevicePointerDeactivate (pButtonDev);
+    } break;
     default:
 	if (id < 0)
 	    return FALSE;
@@ -983,6 +1030,16 @@ dmxDevicePointerEventCheck (DeviceIntPtr        pDevice,
 	    memcpy (&pDevPriv->keysbuttons[4], xstate->buttons, 28);
 	    dmxUpdateButtonState (pButtonDev, pDevPriv->keysbuttons);
 	} break;
+	case DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY: {
+	    dmx_xcb_input_device_state_notify_event_t *xcrossing =
+		(dmx_xcb_input_device_state_notify_event_t *) event;
+
+	    if (id != (xcrossing->device_id & DEVICE_BITS))
+		return FALSE;
+
+	    if (xcrossing->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+		dmxDevicePointerDeactivate (pButtonDev);
+	} break;
 	default:
 	    return FALSE;
 	}
@@ -992,6 +1049,23 @@ dmxDevicePointerEventCheck (DeviceIntPtr        pDevice,
 }
 
 static void
+dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
+{
+    dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+
+    if (pDevPriv->active)
+	return;
+
+    pDevPriv->active = TRUE;
+}
+
+static void
+dmxDeviceKeyboardDeactivate (DeviceIntPtr pDevice)
+{
+    DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
+}
+
+static void
 dmxUpdateKeyStateFromEvent (DeviceIntPtr pDevice,
 			    xcb_window_t event,
 			    int          detail,
@@ -1106,6 +1180,18 @@ dmxDeviceKeyboardEventCheck (DeviceIntPtr        pDevice,
 				      xmapping->first_keycode,
 				      xmapping->count);
     } break;
+    case XCB_FOCUS_IN: {
+	xcb_focus_in_event_t *xfocus = (xcb_focus_in_event_t *) event;
+
+	if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+	    dmxDeviceKeyboardActivate (pKeyDev);
+    } break;
+    case XCB_FOCUS_OUT: {
+	xcb_focus_out_event_t *xfocus = (xcb_focus_out_event_t *) event;
+
+	if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+	    dmxDeviceKeyboardDeactivate (pKeyDev);
+    } break;
     default:
 	if (id < 0)
 	    return FALSE;
@@ -1184,6 +1270,26 @@ dmxDeviceKeyboardEventCheck (DeviceIntPtr        pDevice,
 					  xmapping->first_keycode,
 					  xmapping->count);
 	} break;
+	case XCB_INPUT_FOCUS_IN: {
+	    xcb_input_focus_in_event_t *xfocus =
+		(xcb_input_focus_in_event_t *) event;
+
+	    if (id != (xfocus->device_id & DEVICE_BITS))
+		return FALSE;
+
+	    if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+		dmxDeviceKeyboardActivate (pKeyDev);
+	} break;
+	case XCB_INPUT_FOCUS_OUT: {
+	    dmx_xcb_input_focus_out_event_t *xfocus =
+		(dmx_xcb_input_focus_out_event_t *) event;
+
+	    if (id != (xfocus->device_id & DEVICE_BITS))
+		return FALSE;
+
+	    if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
+		dmxDeviceKeyboardDeactivate (pKeyDev);
+	} break;
 	default:
 	    return FALSE;
 	}
@@ -1333,7 +1439,7 @@ dmxKeyboardOn (DeviceIntPtr pDevice)
 
     if (pDevPriv->deviceId >= 0)
     {
-	XEventClass cls[3];
+	XEventClass cls[5];
 	int         type;
 
 	pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
@@ -1349,10 +1455,12 @@ dmxKeyboardOn (DeviceIntPtr pDevice)
 	DeviceKeyPress (pDevPriv->device, type, cls[0]);
 	DeviceKeyRelease (pDevPriv->device, type, cls[1]);
 	DeviceStateNotify (pDevPriv->device, type, cls[2]);
+	DeviceFocusIn (pDevPriv->device, type, cls[3]);
+	DeviceFocusOut (pDevPriv->device, type, cls[4]);
 
 	XLIB_PROLOGUE (dmxScreen);
 	XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
-			       cls, 3);
+			       cls, 5);
 	XLIB_EPILOGUE (dmxScreen);
     }
     else
@@ -1483,11 +1591,12 @@ static int
 dmxPointerOn (DeviceIntPtr pDevice)
 {
     dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
-    DMXScreenInfo    *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
+    DMXInputInfo     *dmxInput = pDevPriv->dmxInput;
+    DMXScreenInfo    *dmxScreen = (DMXScreenInfo *) dmxInput;
 
     if (pDevPriv->deviceId >= 0)
     {
-	XEventClass cls[5];
+	XEventClass cls[6];
 	int         type;
 
 	pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
@@ -1505,9 +1614,12 @@ dmxPointerOn (DeviceIntPtr pDevice)
 	DeviceButtonPressGrab (pDevPriv->device, type, cls[3]);
 	DeviceStateNotify (pDevPriv->device, type, cls[4]);
 
+	cls[5] = (pDevPriv->device->device_id << 8) |
+	    (dmxInput->eventBase + DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY);
+
 	XLIB_PROLOGUE (dmxScreen);
 	XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
-			       cls, 5);
+			       cls, 6);
 	XLIB_EPILOGUE (dmxScreen);
     }
     else
@@ -1665,6 +1777,7 @@ dmxAddInputDevice (DMXInputInfo *dmxInput,
 	pDevPriv->masterId   = masterId;
 	pDevPriv->device     = NULL;
 	pDevPriv->fakeGrab   = xFalse;
+	pDevPriv->active     = xFalse;
 	pDevPriv->EventCheck = EventCheck;
 	pDevPriv->ReplyCheck = ReplyCheck;
 
diff --git a/hw/dmx/dmxinput.h b/hw/dmx/dmxinput.h
index e6bb249..42ae3be 100644
--- a/hw/dmx/dmxinput.h
+++ b/hw/dmx/dmxinput.h
@@ -40,6 +40,7 @@ typedef struct _dmxDevicePriv {
     KeyCode                  *keycode;
     xcb_void_cookie_t        grab;
     Bool                     fakeGrab;
+    Bool                     active;
 
     Bool (*EventCheck) (DeviceIntPtr, xcb_generic_event_t *);
     Bool (*ReplyCheck) (DeviceIntPtr, unsigned int, xcb_generic_reply_t *);
commit f2d45e1153b0439281901c5f775266c3b279cc2f
Author: David Reveman <davidr at novell.com>
Date:   Sat Nov 8 09:51:07 2008 -0500

    Handle errors properly in dmxProcShmGetImage.

diff --git a/hw/dmx/dmxshm.c b/hw/dmx/dmxshm.c
index 17c6cee..c7b2c25 100644
--- a/hw/dmx/dmxshm.c
+++ b/hw/dmx/dmxshm.c
@@ -414,6 +414,9 @@ dmxProcShmGetImage (ClientPtr client)
 	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
     }
 
+    if (!draw)
+	return (*dmxSaveProcVector[X_ShmGetImage]) (client);
+
     VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
     xgi.size = length;
 
@@ -424,6 +427,7 @@ dmxProcShmGetImage (ClientPtr client)
 	DMXScreenInfo		   *dmxScreen =
 	    &dmxScreens[pDraw->pScreen->myNum];
 
+	rc = BadValue;
 	cookie = xcb_shm_get_image (dmxScreen->connection, draw,
 				    stuff->x, stuff->y,
 				    stuff->width, stuff->height,
@@ -437,10 +441,20 @@ dmxProcShmGetImage (ClientPtr client)
 				    cookie.sequence,
 				    (void **) &reply,
 				    NULL))
+	    {
+		if (reply)
+		{
+		    rc = Success;
+		    free (reply);
+		}
 		break;
+	    }
 	} while (dmxWaitForResponse () && dmxScreen->alive);
+
+	if (rc != Success)
+	    return (*dmxSaveProcVector[X_ShmGetImage]) (client);
     }
-    
+
     if (client->swapped) {
     	swaps(&xgi.sequenceNumber, n);
     	swapl(&xgi.length, n);
commit 2f19aa9ab0fe22dd750e1f651b21bc3f9647ac98
Author: David Reveman <davidr at novell.com>
Date:   Fri Nov 7 11:24:45 2008 -0500

    Improve selection handling.
    
    Dynamically create proxy windows as needed. Handle multiple
    simultaneous selection conversions of the same selection
    properly.

diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h
index 39e9661..3213554 100644
--- a/hw/dmx/dmx.h
+++ b/hw/dmx/dmx.h
@@ -129,10 +129,6 @@ typedef struct _DMXSelectionMap {
 
 #define DMX_DETACHED 0xff
 
-/** Number of backend selection conversion requests that can be
-    processed simultaneously . */
-#define DMX_N_SELECTION_PROXY 10
-
 /** Provide the typedef globally, but keep the contents opaque outside
  * of the XSync statistic routines.  \see dmxstat.c */
 typedef struct _DMXStatInfo DMXStatInfo;
@@ -233,13 +229,15 @@ typedef struct _DMXScreenInfo {
     int           rootY;          /**< Y offset of "root" window WRT "screen"*/
     int           rootEventMask;
 
+    /*---------- Input overlay ----------*/
+    XID                              inputOverlayWid;
+    WindowPtr                        pInputOverlayWin;
+
     /*---------- Selection information ----------*/
     Atom                             beSelectionAtom;
     Window                           selectionOwner;
     xcb_get_selection_owner_cookie_t getSelectionOwner;
     Window                           getSelectionOwnerResult;
-    XID                              selectionProxyWid[DMX_N_SELECTION_PROXY];
-    WindowPtr                        pSelectionProxyWin[DMX_N_SELECTION_PROXY];
     Atom                             multipleAtom;
     Atom                             atomPairAtom;
     Atom                             incrAtom;
diff --git a/hw/dmx/dmxcb.c b/hw/dmx/dmxcb.c
index 996eee7..1dd5e2f 100644
--- a/hw/dmx/dmxcb.c
+++ b/hw/dmx/dmxcb.c
@@ -42,7 +42,7 @@
 #include "dmxcb.h"
 #include "dmxinput.h"
 #include "dmxlog.h"
-#include "dmxselection.h"
+#include "dmxwindow.h"
 
 extern int     connBlockScreenStart;
 
@@ -50,6 +50,8 @@ extern int     connBlockScreenStart;
 extern int     PanoramiXPixWidth;
 extern int     PanoramiXPixHeight;
 extern int     PanoramiXNumScreens;
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
 #endif
 
        int     dmxGlobalWidth, dmxGlobalHeight;
@@ -82,6 +84,84 @@ void dmxComputeWidthHeight(void)
     dmxSetWidthHeight (w, h);
 }
 
+static Bool
+dmxCreateInputOverlayWindow (void)
+{
+    WindowPtr pWin;
+    XID       inputOverlayWid;
+    XID       overrideRedirect = TRUE;
+    int	      result;
+    Atom      xdndVersion = 5;
+
+    if (dmxScreens[0].inputOverlayWid)
+	return TRUE;
+
+    inputOverlayWid = FakeClientID (0);
+
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension)
+    {
+	PanoramiXRes *newWin;
+	int          j;
+
+	if (!(newWin = (PanoramiXRes *) xalloc (sizeof (PanoramiXRes))))
+	    return BadAlloc;
+
+	newWin->type = XRT_WINDOW;
+	newWin->u.win.visibility = VisibilityNotViewable;
+	newWin->u.win.class = InputOnly;
+	newWin->u.win.root = FALSE;
+	newWin->info[0].id = inputOverlayWid;
+	for(j = 1; j < PanoramiXNumScreens; j++)
+	    newWin->info[j].id = FakeClientID (0);
+
+	FOR_NSCREENS_BACKWARD(j) {
+	    pWin = CreateWindow (newWin->info[j].id, WindowTable[j],
+				 0, 0, 1, 1, 0, InputOnly, 
+				 CWOverrideRedirect, &overrideRedirect,
+				 0, serverClient, CopyFromParent, 
+				 &result);
+	    if (result != Success)
+		return FALSE;
+	    if (!AddResource (pWin->drawable.id, RT_WINDOW, pWin))
+		return FALSE;
+
+	    dmxScreens[j].inputOverlayWid = inputOverlayWid;
+	    dmxScreens[j].pInputOverlayWin = pWin;
+	}
+
+	AddResource (newWin->info[0].id, XRT_WINDOW, newWin);
+    }
+    else
+#endif
+	
+    {
+	pWin = CreateWindow (inputOverlayWid, WindowTable[0],
+			     0, 0, 1, 1, 0, InputOnly, 
+			     CWOverrideRedirect, &overrideRedirect,
+			     0, serverClient, CopyFromParent, 
+			     &result);
+	if (result != Success)
+	    return FALSE;
+	if (!AddResource (pWin->drawable.id, RT_WINDOW, pWin))
+	    return FALSE;
+
+	dmxScreens[0].inputOverlayWid = inputOverlayWid;
+	dmxScreens[0].pInputOverlayWin = pWin;
+    }
+
+    ChangeWindowProperty (dmxScreens[0].pInputOverlayWin,
+			  dmxScreens[0].xdndAwareAtom,
+			  XA_ATOM,
+			  32,
+			  PropModeReplace,
+			  1,
+			  &xdndVersion,
+			  TRUE);
+
+    return TRUE;
+}
+
 /** A callback routine that hooks into Xinerama and provides a
  * convenient place to print summary log information during server
  * startup.  This routine does not modify any values. */
@@ -196,5 +276,6 @@ void dmxConnectionBlockCallback(void)
 #endif
     MAXSCREENSFREE(found);
 
-    dmxCreateSelectionProxies ();
+    if (!dmxCreateInputOverlayWindow ())
+	dmxLog (dmxFatal, "dmxCreateInputOverlayWindow: failed");
 }
diff --git a/hw/dmx/dmxdnd.c b/hw/dmx/dmxdnd.c
index ee96c51..6218b66 100644
--- a/hw/dmx/dmxdnd.c
+++ b/hw/dmx/dmxdnd.c
@@ -98,7 +98,7 @@ dmxDnDSendDeclineStatus (void)
 	x.u.u.detail                 = 32;
 	x.u.clientMessage.window     = dmxScreens[0].dndWindow;
 	x.u.clientMessage.u.l.type   = dmxScreens[0].xdndStatusAtom;
-	x.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
+	x.u.clientMessage.u.l.longs0 = dmxScreens[0].inputOverlayWid;
 	x.u.clientMessage.u.l.longs1 = 0;
 	x.u.clientMessage.u.l.longs2 = 0;
 	x.u.clientMessage.u.l.longs3 = 0;
@@ -508,7 +508,7 @@ static void
 dmxBEDnDHideProxyWindow (ScreenPtr pScreen)
 {
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-    WindowPtr     pProxyWin = dmxScreen->pSelectionProxyWin[0];
+    WindowPtr     pProxyWin = dmxScreen->pInputOverlayWin;
 
     if (!pProxyWin->mapped)
 	return;
@@ -542,7 +542,7 @@ dmxBEDnDSpriteUpdate (ScreenPtr pScreen,
 		      int       rootY)
 {
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-    WindowPtr     pProxyWin = dmxScreen->pSelectionProxyWin[0];
+    WindowPtr     pProxyWin = dmxScreen->pInputOverlayWin;
 
     if (event != dmxScreen->rootWin)
     {
@@ -572,13 +572,12 @@ dmxBEDnDSpriteUpdate (ScreenPtr pScreen,
 		int j;
 
 		FOR_NSCREENS_BACKWARD(j) {
-		    ConfigureWindow (dmxScreens[j].pSelectionProxyWin[0],
+		    ConfigureWindow (dmxScreens[j].pInputOverlayWin,
 				     CWX | CWY | CWWidth | CWHeight |
 				     CWStackMode,
 				     vlist,
 				     serverClient);
-		    MapWindow (dmxScreens[j].pSelectionProxyWin[0],
-			       serverClient);
+		    MapWindow (dmxScreens[j].pInputOverlayWin, serverClient);
 
 		    dmxScreens[j].dndSource = None;
 		    dmxScreens[j].dndTarget = None;
@@ -635,7 +634,7 @@ dmxDnDUpdatePosition (DMXScreenInfo *dmxScreen,
     event.u.u.type   = ClientMessage | 0x80;
     event.u.u.detail = 32;
     
-    event.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
+    event.u.clientMessage.u.l.longs0 = dmxScreens[0].inputOverlayWid;
 
     if (pWin)
     {
@@ -893,7 +892,7 @@ dmxDnDGetTypePropReply (ScreenPtr           pScreen,
 	    for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
 		data[i] = dmxAtom (dmxScreen, data[i]);
 
-	    ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
+	    ChangeWindowProperty (dmxScreens[0].pInputOverlayWin,
 				  dmxScreen->xdndTypeListAtom,
 				  XA_ATOM,
 				  32,
@@ -947,7 +946,7 @@ dmxDnDGetActionListPropReply (ScreenPtr           pScreen,
 	    for (i = 0; i < xcb_get_property_value_length (xproperty); i++)
 		data[i] = dmxAtom (dmxScreen, data[i]);
 
-	    ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
+	    ChangeWindowProperty (dmxScreens[0].pInputOverlayWin,
 				  dmxScreen->xdndActionListAtom,
 				  XA_ATOM,
 				  32,
@@ -978,7 +977,7 @@ dmxDnDGetActionDescriptionPropReply (ScreenPtr           pScreen,
 	if (xproperty->format                    == 8 &&
 	    dmxAtom (dmxScreen, xproperty->type) == XA_STRING)
 	{
-	    ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
+	    ChangeWindowProperty (dmxScreens[0].pInputOverlayWin,
 				  dmxScreen->xdndActionDescriptionAtom,
 				  XA_STRING,
 				  8,
@@ -1129,7 +1128,7 @@ dmxDnDDropMessage (ScreenPtr pScreen,
 	event.u.clientMessage.window   = dmxScreen->dndTarget;
 	event.u.clientMessage.u.l.type = dmxScreen->xdndDropAtom;
 
-	event.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
+	event.u.clientMessage.u.l.longs0 = dmxScreens[0].inputOverlayWid;
 	event.u.clientMessage.u.l.longs1 = 0;
 	event.u.clientMessage.u.l.longs2 = currentTime.milliseconds;
 	event.u.clientMessage.u.l.longs3 = 0;
@@ -1211,7 +1210,7 @@ dmxDnDStatusMessage (ScreenPtr pScreen,
 	x.u.u.detail                 = 32;
 	x.u.clientMessage.window     = dmxScreens[0].dndWindow;
 	x.u.clientMessage.u.l.type   = dmxScreens[0].xdndStatusAtom;
-	x.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
+	x.u.clientMessage.u.l.longs0 = dmxScreens[0].inputOverlayWid;
 	x.u.clientMessage.u.l.longs1 = 0;
 	x.u.clientMessage.u.l.longs2 = 0;
 	x.u.clientMessage.u.l.longs3 = 0;
@@ -1258,7 +1257,7 @@ dmxDnDFinishedMessage (ScreenPtr pScreen,
 	x.u.u.detail                 = 32;
 	x.u.clientMessage.window     = dmxScreens[0].dndWindow;
 	x.u.clientMessage.u.l.type   = dmxScreens[0].xdndFinishedAtom;
-	x.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
+	x.u.clientMessage.u.l.longs0 = dmxScreens[0].inputOverlayWid;
 	x.u.clientMessage.u.l.longs1 = 0;
 	x.u.clientMessage.u.l.longs2 = 0;
 	x.u.clientMessage.u.l.longs3 = 0;
@@ -1599,7 +1598,7 @@ dmxDnDClientMessageEvent (xEvent *event)
 		    x.u.clientMessage.u.l.type   =
 			dmxScreens[0].xdndFinishedAtom;
 		    x.u.clientMessage.u.l.longs0 =
-			dmxScreens[0].selectionProxyWid[0];
+			dmxScreens[0].inputOverlayWid;
 		    x.u.clientMessage.u.l.longs1 = 0;
 		    x.u.clientMessage.u.l.longs2 = 0;
 		    x.u.clientMessage.u.l.longs3 = 0;
diff --git a/hw/dmx/dmxrandr.c b/hw/dmx/dmxrandr.c
index 7851681..41e7624 100644
--- a/hw/dmx/dmxrandr.c
+++ b/hw/dmx/dmxrandr.c
@@ -1145,7 +1145,7 @@ dmxScreenEventCheckRR (ScreenPtr           pScreen,
 		       DefaultScreen (dmxScreen->beDisplay));
 
     /* only call RRGetInfo when server is fully initialized */
-    if (dmxScreens[0].selectionProxyWid[0])
+    if (dmxScreens[0].inputOverlayWid)
 	RRGetInfo (screenInfo.screens[0]);
 
     return TRUE;
diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index 6d0b953..745d3ce 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -1319,9 +1319,9 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
 {
     DMXScreenInfo *dmxScreen = &dmxScreens[idx];
 
-    /* Free selection proxy window tree */
-    if (dmxScreen->selectionProxyWid[0])
-	FreeResource (dmxScreen->selectionProxyWid[0], RT_NONE);
+        /* Free input overlay window tree */
+    if (dmxScreen->inputOverlayWid)
+	FreeResource (dmxScreen->inputOverlayWid, RT_NONE);
 
     /* Reset the proc vectors */
     if (idx == 0) {
diff --git a/hw/dmx/dmxselection.c b/hw/dmx/dmxselection.c
index e2e16c8..76113f4 100644
--- a/hw/dmx/dmxselection.c
+++ b/hw/dmx/dmxselection.c
@@ -43,7 +43,7 @@
 #include "panoramiXsrv.h"
 #endif
 
-#define DMX_SELECTION_TIMEOUT (2 * 1000) /* 60 seconds */
+#define DMX_SELECTION_TIMEOUT (30 * 1000) /* 30 seconds */
 
 typedef struct _DMXSelection {
     struct _DMXSelection *next;
@@ -153,8 +153,7 @@ dmxSelectionDeleteProp (DMXSelection *s)
 static int
 dmxSelectionDeleteReq (DMXSelection *s)
 {
-    WindowPtr pWin;
-    int       i;
+    int i;
 
     for (i = 0; i < dmxNumScreens; i++)
     {
@@ -170,11 +169,33 @@ dmxSelectionDeleteReq (DMXSelection *s)
 	}
     }
 
-    if (s->wid && dixLookupWindow (&pWin,
-				   s->wid,
-				   serverClient,
-				   DixReadAccess) == Success)
-	DeleteProperty (serverClient, pWin, s->property);
+    if (s->wid)
+    {
+
+#ifdef PANORAMIX
+	if (!noPanoramiXExtension)
+	{
+	    PanoramiXRes *win;
+
+	    win = (PanoramiXRes *) SecurityLookupIDByType (serverClient,
+							   s->wid,
+							   XRT_WINDOW,
+							   DixDestroyAccess);
+
+	    if (win)
+	    {
+		int j;
+
+		FOR_NSCREENS_BACKWARD(j) {
+		    FreeResource (win->info[j].id, RT_NONE);
+		}
+	    }
+	}
+	else
+#endif
+
+	    FreeResource (s->wid, RT_NONE);
+    }
 
     if (s->timer)
 	TimerFree (s->timer);
@@ -191,9 +212,10 @@ dmxSelectionCallback (OsTimerPtr timer,
     DMXSelection *r = (DMXSelection *) arg;
     DMXSelection *s;
 
-    dmxLog (dmxWarning,
-	    "selection conversion for %s timed out\n",
-	    NameForAtom (r->selection));
+    if (time)
+	dmxLog (dmxWarning,
+		"selection conversion for %s timed out\n",
+		NameForAtom (r->selection));
 
     for (s = convHead; s; s = s->next)
 	if (s == r)
@@ -230,9 +252,13 @@ dmxAppendSelection (DMXSelection **head,
 	for (last = NULL, p = *head; p; p = p->next)
 	{
 	    /* avoid duplicates */
-	    if (p->timer && p->selection == s->selection)
+	    if (p->selection == s->selection &&
+		p->requestor == s->requestor)
 	    {
-		TimerForce (p->timer);
+		if (p->timer)
+		    TimerCancel (p->timer);
+
+		dmxSelectionCallback (s->timer, 0, p);
 		break;
 	    }
 
@@ -421,7 +447,7 @@ dmxSelectionClear (ScreenPtr pScreen,
 			 NoEventMask /* CantBeFiltered */, NullGrab);
 
 	pSel->lastTimeChanged = currentTime;
-	pSel->window = dmxScreen->selectionProxyWid[0];
+	pSel->window = dmxScreen->inputOverlayWid;
 	pSel->pWin = NULL;
 	pSel->client = NullClient;
 
@@ -509,7 +535,7 @@ dmxSelectionPropertyReply (ScreenPtr           pScreen,
 		    event.u.selectionNotify.property = s->property;
 	    }
 
-	    if (s->selection)
+	    if (s->target)
 	    {
 		event.u.u.type = SelectionNotify | 0x80;
 		event.u.selectionNotify.time = s->time;
@@ -527,7 +553,7 @@ dmxSelectionPropertyReply (ScreenPtr           pScreen,
 		if (xproperty->value_len != 0)
 		{
 		    /* don't send another selection notify event */
-		    s->selection = None;
+		    s->target = None;
 		    dmxSelectionResetTimer (s);
 		    return;
 		}
@@ -634,6 +660,16 @@ dmxSelectionDestroyNotify (ScreenPtr pScreen,
 	return TRUE;
     }
 
+    for (s = propHead; s; s = s->next)
+	if (s->value[pScreen->myNum].out == window)
+	    break;
+
+    if (s)
+    {
+	s->value[pScreen->myNum].out = None;
+	return TRUE;
+    }
+
     return FALSE;
 }
 
@@ -683,7 +719,8 @@ dmxSelectionPropertyNotify (ScreenPtr pScreen,
     else
     {
 	for (s = reqHead; s; s = s->next)
-	    if (s->value[pScreen->myNum].out == window)
+	    if (s->value[pScreen->myNum].out == window &&
+		s->property                  == dmxAtom (dmxScreen, xProperty))
 		break;
 
 	if (s)
@@ -755,23 +792,61 @@ dmxConvertSelection (ScreenPtr    pScreen,
 
     if (pSel)
     {
+	XID       overrideRedirect = TRUE;
 	WindowPtr pProxy = NullWindow;
-	int       i;
+	int       result;
 
-	for (i = 1; i < DMX_N_SELECTION_PROXY; i++)
+#ifdef PANORAMIX
+	if (!noPanoramiXExtension)
 	{
-	    DMXSelection *r;
+	    PanoramiXRes *newWin;
+	    int          j;
 
-	    pProxy = dmxScreens[0].pSelectionProxyWin[i];
+	    if (!(newWin = (PanoramiXRes *) xalloc (sizeof (PanoramiXRes))))
+		return FALSE;
 
-	    for (r = reqHead; pProxy && r; r = r->next)
-		if (r->wid == pProxy->drawable.id)
-		    pProxy = NullWindow;
+	    newWin->type = XRT_WINDOW;
+	    newWin->u.win.visibility = VisibilityNotViewable;
+	    newWin->u.win.class = InputOnly;
+	    newWin->u.win.root = FALSE;
+	    for (j = 0; j < PanoramiXNumScreens; j++)
+		newWin->info[j].id = FakeClientID (0);
 
-	    if (pProxy)
-		break;
+	    FOR_NSCREENS_BACKWARD(j) {
+		pProxy = CreateWindow (newWin->info[j].id,
+				       dmxScreens[j].pInputOverlayWin,
+				       0, 0, 1, 1, 0, InputOnly, 
+				       CWOverrideRedirect, &overrideRedirect,
+				       0, serverClient, CopyFromParent, 
+				       &result);
+		if (result != Success)
+		    return FALSE;
+		if (!AddResource (pProxy->drawable.id, RT_WINDOW, pProxy))
+		    return FALSE;
+
+		s->value[j].in = DMX_GET_WINDOW_PRIV (pProxy)->window;
+	    }
+	    
+	    AddResource (newWin->info[0].id, XRT_WINDOW, newWin);
 	}
+	else
+#endif
+	
+	{
+	    pProxy = CreateWindow (FakeClientID (0),
+				   dmxScreens[0].pInputOverlayWin,
+				   0, 0, 1, 1, 0, InputOnly, 
+				   CWOverrideRedirect, &overrideRedirect,
+				   0, serverClient, CopyFromParent, 
+				   &result);
+	    if (result != Success)
+		return FALSE;
+	    if (!AddResource (pProxy->drawable.id, RT_WINDOW, pProxy))
+		return FALSE;
 
+	    s->value[0].in = DMX_GET_WINDOW_PRIV (pProxy)->window;
+	}
+	
 	if (pProxy)
 	{
 	    xEvent event;
@@ -784,23 +859,14 @@ dmxConvertSelection (ScreenPtr    pScreen,
 	    event.u.selectionRequest.target = s->target;
 	    event.u.selectionRequest.property = s->property;
 
+	    s->wid       = pProxy->drawable.id;
+	    s->requestor = pProxy->drawable.id;
+
 	    if (TryClientEvents (pSel->client, NULL, &event, 1,
 				 NoEventMask,
 				 NoEventMask /* CantBeFiltered */,
 				 NullGrab))
 	    {
-		int j;
-
-		s->wid = pProxy->drawable.id;
-
-		for (j = 0; j < dmxNumScreens; j++)
-		{
-		    WindowPtr     pWin = dmxScreens[j].pSelectionProxyWin[i];
-		    dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin);
-			    
-		    s->value[j].in = pWinPriv->window;
-		}
-
 		if (multipleLength)
 		    ChangeWindowProperty (pProxy,
 					  s->property,
@@ -815,14 +881,8 @@ dmxConvertSelection (ScreenPtr    pScreen,
 		return TRUE;
 	    }
 	}
-	else
-	{
-	    /* TODO: wait for proxy window to become available */
-	    dmxLog (dmxWarning,
-		    "dmxSelectionRequest: no proxy window available "
-		    "for conversion of %s selection\n",
-		    NameForAtom (s->selection));
-	}
+
+	dmxSelectionDeleteReq (s);
     }
 	
     return FALSE;
@@ -866,14 +926,14 @@ dmxMultipleTargetPropertyReply (ScreenPtr           pScreen,
     xevent.pad0 = 0;
     xevent.sequence = 0;
     xevent.time = s->time;
-    xevent.requestor = s->requestor;
+    xevent.requestor = s->value[pScreen->myNum].out;
     xevent.selection = dmxBESelectionAtom (dmxScreen, s->selection);
     xevent.target = dmxBEAtom (dmxScreen, s->target);
     xevent.property = 0;
 
     xcb_send_event (dmxScreen->connection,
 		    FALSE,
-		    s->requestor,
+		    s->value[pScreen->myNum].out,
 		    0,
 		    (const char *) &xevent);
 
@@ -909,7 +969,7 @@ dmxSelectionRequest (ScreenPtr pScreen,
 	    if (s)
 	    {
 		s->wid       = 0;
-		s->requestor = requestor;
+		s->requestor = 0;
 		s->selection = selection;
 		s->target    = target;
 		s->property  = property;
@@ -984,116 +1044,63 @@ dmxSelectionPropertyChangeCheck (WindowPtr pWin,
 
     if (nUnits == -1)
     {
-	for (s = propHead; s; s = s->next)
-	    if (s->wid == pWin->drawable.id)
-		break;
-
-	if (s && s->incr)
-	    TimerCancel (s->timer);
-    }
-    else if (nUnits == 0)
-    {
 	for (s = reqHead; s; s = s->next)
-	    if (s->wid == pWin->drawable.id)
+	    if (s->requestor == pWin->drawable.id &&
+		s->property  == property)
 		break;
 
-	/* end of incremental selection conversion */
-	if (s && s->incr)
-	    dmxSelectionDeleteProp (dmxUnhookSelection (&reqHead, s));
-    }
-}
+	if (s)
+	{
+	    if (s->incr)
+		TimerCancel (s->timer);
+	    else
+		dmxSelectionDeleteReq (dmxUnhookSelection (&reqHead, s));
 
-Bool
-dmxCreateSelectionProxies (void)
-{
-    WindowPtr pWin;
-    WindowPtr pParent;
-    XID       selectionProxyWid;
-    XID       overrideRedirect = TRUE;
-    int	      result;
-    int       i;
-    Atom      xdndVersion = 5;
-
-    for (i = 0; i < DMX_N_SELECTION_PROXY; i++)
-    {
-	if (dmxScreens[0].selectionProxyWid[i])
-	    continue;
+	    return;
+	}
 
-	selectionProxyWid = FakeClientID (0);
+	for (s = propHead; s; s = s->next)
+	    if (s->requestor == pWin->drawable.id &&
+		s->property  == property)
+		break;
 
-#ifdef PANORAMIX
-	if (!noPanoramiXExtension)
+	if (s && s->incr)
 	{
-	    PanoramiXRes *newWin;
-	    int          j;
-
-	    if(!(newWin = (PanoramiXRes *) xalloc (sizeof (PanoramiXRes))))
-		return BadAlloc;
+	    int i;
 
-	    newWin->type = XRT_WINDOW;
-	    newWin->u.win.visibility = VisibilityNotViewable;
-	    newWin->u.win.class = InputOnly;
-	    newWin->u.win.root = FALSE;
-	    newWin->info[0].id = selectionProxyWid;
-	    for(j = 1; j < PanoramiXNumScreens; j++)
-		newWin->info[j].id = FakeClientID (0);
+	    TimerCancel (s->timer);
 
-	    FOR_NSCREENS_BACKWARD(j) {
-		if (i)
-		    pParent = dmxScreens[j].pSelectionProxyWin[0];
-		else
-		    pParent = WindowTable[j];
+	    for (i = 0; i < dmxNumScreens; i++)
+		if (s->value[i].out)
+		    break;
 
-		pWin = CreateWindow (newWin->info[j].id, pParent,
-				     0, 0, 1, 1, 0, InputOnly, 
-				     CWOverrideRedirect, &overrideRedirect,
-				     0, serverClient, CopyFromParent, 
-				     &result);
-		if (result != Success)
-		    return FALSE;
-		if (!AddResource (pWin->drawable.id, RT_WINDOW, pWin))
-		    return FALSE;
+	    /* owner doesn't exist anymore */
+	    if (i == dmxNumScreens)
+	    {
+		ChangeWindowProperty (pWin,
+				      s->property,
+				      XA_ATOM,
+				      32,
+				      PropModeReplace,
+				      0,
+				      NULL,
+				      TRUE);
 
-		dmxScreens[j].selectionProxyWid[i] = selectionProxyWid;
-		dmxScreens[j].pSelectionProxyWin[i] = pWin;
+		dmxSelectionDeleteProp (dmxUnhookSelection (&propHead, s));
 	    }
-
-	    AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
-	}
-	else
-#endif
-	
-	{
-	    if (i)
-		pParent = dmxScreens[0].pSelectionProxyWin[0];
-	    else
-		pParent = WindowTable[0];
-
-	    pWin = CreateWindow (selectionProxyWid, pParent,
-				 0, 0, 1, 1, 0, InputOnly, 
-				 CWOverrideRedirect, &overrideRedirect,
-				 0, serverClient, CopyFromParent, 
-				 &result);
-	    if (result != Success)
-		return FALSE;
-	    if (!AddResource (pWin->drawable.id, RT_WINDOW, pWin))
-		return FALSE;
-
-	    dmxScreens[0].selectionProxyWid[i] = selectionProxyWid;
-	    dmxScreens[0].pSelectionProxyWin[i] = pWin;
 	}
     }
+    else if (nUnits == 0)
+    {
+	for (s = reqHead; s; s = s->next)
+	    if (s->requestor == pWin->drawable.id &&
+		s->property  == property)
+		break;
 
-    ChangeWindowProperty (dmxScreens[0].pSelectionProxyWin[0],
-			  dmxScreens[0].xdndAwareAtom,
-			  XA_ATOM,
-			  32,
-			  PropModeReplace,
-			  1,
-			  &xdndVersion,
-			  TRUE);
-
-    return TRUE;
+	/* end of incremental selection conversion */
+	if (s && s->incr)
+	    dmxSelectionDeleteReq (dmxUnhookSelection (&reqHead, s));
+    }
 }
 
 static int (*dmxSaveProcVector[256]) (ClientPtr);
@@ -1236,7 +1243,7 @@ dmxProcGetSelectionOwner (ClientPtr client)
 
 	/* at least one back-end server has an owner for this selection */
 	if (j >= 0)
-	    reply.owner = dmxScreens[0].selectionProxyWid[0];
+	    reply.owner = dmxScreens[0].inputOverlayWid;
     }
 #endif
 
@@ -1289,7 +1296,7 @@ dmxProcConvertSelection (ClientPtr client)
 	return BadAlloc;
 
     s->wid       = 0;
-    s->requestor = 0;
+    s->requestor = stuff->requestor;
     s->selection = stuff->selection;
     s->target    = stuff->target;
     s->property  = stuff->property;
@@ -1427,7 +1434,7 @@ dmxProcSendEvent (ClientPtr client)
 	    DMXSelection *s;
 
 	    for (s = reqHead; s; s = s->next)
-		if (s->wid       == stuff->destination &&
+		if (s->requestor == stuff->destination &&
 		    s->selection == stuff->event.u.selectionNotify.selection)
 		    break;
 
@@ -1455,7 +1462,7 @@ dmxProcSendEvent (ClientPtr client)
 		    xevent.pad0 = 0;
 		    xevent.sequence = 0;
 		    xevent.time = s->time;
-		    xevent.requestor = s->requestor;
+		    xevent.requestor = s->value[i].out;
 		    xevent.selection = dmxBESelectionAtom (dmxScreen,
 							   s->selection);
 		    if (target)
@@ -1469,13 +1476,13 @@ dmxProcSendEvent (ClientPtr client)
 			xevent.property = None;
 
 		    xcb_change_window_attributes (dmxScreen->connection,
-						  s->requestor,
+						  s->value[i].out,
 						  XCB_CW_EVENT_MASK,
 						  &value);
 
 		    xcb_send_event (dmxScreen->connection,
 				    FALSE,
-				    s->requestor,
+				    s->value[i].out,
 				    0,
 				    (const char *) &xevent);
 
@@ -1498,7 +1505,7 @@ dmxProcSendEvent (ClientPtr client)
 	    return BadValue;
 	}
 
-	if (stuff->destination == dmxScreens[0].selectionProxyWid[0])
+	if (stuff->destination == dmxScreens[0].inputOverlayWid)
 	    dmxDnDClientMessageEvent (&stuff->event);
 
 	break;
diff --git a/hw/dmx/dmxselection.h b/hw/dmx/dmxselection.h
index 5e7e28b..afa7762 100644
--- a/hw/dmx/dmxselection.h
+++ b/hw/dmx/dmxselection.h
@@ -70,9 +70,6 @@ dmxSelectionPropertyChangeCheck (WindowPtr pWin,
 				 Atom      property,
 				 int       nUnits);
 
-Bool
-dmxCreateSelectionProxies (void);
-
 void
 dmxInitSelections (void);
 
commit 2fa16f2e292c010a2c5a002b1ea1a9ff191e4cfb
Author: David Reveman <davidr at novell.com>
Date:   Fri Nov 7 11:22:44 2008 -0500

    Add alternative window support to dmxGetImage.

diff --git a/hw/dmx/dmxgcops.c b/hw/dmx/dmxgcops.c
index df86f58..3499c86 100644
--- a/hw/dmx/dmxgcops.c
+++ b/hw/dmx/dmxgcops.c
@@ -545,39 +545,67 @@ void dmxPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
  * Miscellaneous drawing commands
  */
 
-/** When Xinerama is active, the client pixmaps are always obtained from
- * screen 0.  When screen 0 is detached, the pixmaps must be obtained
- * from any other screen that is not detached.  Usually, this is screen
- * 1. */
-static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
+static DMXScreenInfo *
+dmxGetAlternateWindow (DrawablePtr pDrawable,
+		       int         i,
+		       XID         *draw)
 {
+
+#ifdef PANORAMIX
+    PanoramiXRes  *pXinWin;
+    DMXScreenInfo *dmxScreen = &dmxScreens[i];
+            
+    if (noPanoramiXExtension) return NULL;
+    if (!dmxScreen->beDisplay) return NULL;
+    
+    if ((pXinWin = (PanoramiXRes *) LookupIDByType (pDrawable->id,
+						    XRT_WINDOW)))
+    {
+	WindowPtr     pSrc;
+	dmxWinPrivPtr pSrcPriv;
+            
+	pSrc = (WindowPtr) LookupIDByType (pXinWin->info[i].id, RT_WINDOW);
+	pSrcPriv = DMX_GET_WINDOW_PRIV (pSrc);
+	if (pSrcPriv->window)
+	{
+	    *draw = pSrcPriv->window;
+	    return dmxScreen;
+	}
+    }
+#endif
+
+    return NULL;
+}
+
+static DMXScreenInfo *
+dmxGetAlternatePixmap (DrawablePtr pDrawable,
+		       int         i,
+		       XID         *draw)
+{
+
 #ifdef PANORAMIX
     PanoramiXRes  *pXinPix;
-    int           i;
-    DMXScreenInfo *dmxScreen;
+    DMXScreenInfo *dmxScreen = &dmxScreens[i];
             
-    if (noPanoramiXExtension)               return NULL;
-    if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
+    if (noPanoramiXExtension) return NULL;
+    if (!dmxScreen->beDisplay) return NULL;
     
-    if (!(pXinPix = (PanoramiXRes *)LookupIDByType(pDrawable->id, XRT_PIXMAP)))
-        return NULL;
-
-    for (i = 1; i < PanoramiXNumScreens; i++) {
-        dmxScreen = &dmxScreens[i];
-        if (dmxScreen->beDisplay) {
-            PixmapPtr     pSrc;
-            dmxPixPrivPtr pSrcPriv;
+    if ((pXinPix = (PanoramiXRes *) LookupIDByType (pDrawable->id,
+						    XRT_PIXMAP)))
+    {
+	PixmapPtr     pSrc;
+	dmxPixPrivPtr pSrcPriv;
             
-            pSrc = (PixmapPtr)LookupIDByType(pXinPix->info[i].id,
-                                             RT_PIXMAP);
-            pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
-            if (pSrcPriv->pixmap) {
-                *draw = pSrcPriv->pixmap;
-                return dmxScreen;
-            }
-        }
+	pSrc = (PixmapPtr) LookupIDByType (pXinPix->info[i].id, RT_PIXMAP);
+	pSrcPriv = DMX_GET_PIXMAP_PRIV (pSrc);
+	if (pSrcPriv->pixmap)
+	{
+	    *draw = pSrcPriv->pixmap;
+	    return dmxScreen;
+	}
     }
 #endif
+
     return NULL;
 }
 
@@ -589,9 +617,9 @@ static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
 void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
 		 unsigned int format, unsigned long planeMask, char *pdstLine)
 {
-    DMXScreenInfo         *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
-    Drawable              draw;
-    xcb_get_image_reply_t *reply;
+    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+    Drawable      draw;
+    int           i = 0;
 
     /* Cannot get image from unviewable window */
     if (pDrawable->type == DRAWABLE_WINDOW) {
@@ -606,72 +634,90 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
 		return;
 	    }
 	}
-	DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
+	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
 	if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
-	    return;
+	    draw = None;
     } else {
 	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
-	if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
-            /* Try to find the pixmap on a non-detached Xinerama screen */
-            dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
-            if (!dmxScreen) return;
-        }
+	if (DMX_GCOPS_OFFSCREEN(pDrawable))
+	    draw = None;
     }
-
-    reply = xcb_get_image_reply (dmxScreen->connection,
-				 xcb_get_image (dmxScreen->connection,
-						format,
-						draw,
-						sx, sy, w, h,
-						planeMask),
-				 NULL);
-    if (reply)
+    
+    while (i < dmxNumScreens)
     {
-	const xcb_setup_t *setup = xcb_get_setup (dmxScreen->connection);
-	uint32_t          bytes = xcb_get_image_data_length (reply);
-	uint8_t           *data = xcb_get_image_data (reply);
-
-	/* based on code in xcb_image.c, Copyright (C) 2007 Bart Massey */
-	switch (format) {
-	case XCB_IMAGE_FORMAT_XY_PIXMAP:
-	    planeMask &= xcb_mask (reply->depth);
-	    if (planeMask != xcb_mask (reply->depth))
-	    {
-		uint32_t rpm = planeMask;
-		uint8_t  *src_plane = data;
-		uint8_t  *dst_plane = (uint8_t *) pdstLine;
-		uint32_t scanline_pad = setup->bitmap_format_scanline_pad;
-		uint32_t stride = xcb_roundup (w, scanline_pad) >> 3;
-		uint32_t size = h * stride;
-		int      i;
-
-		if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
-		    rpm = xcb_bit_reverse (planeMask, reply->depth);
-
-		for (i = 0; i < reply->depth; i++)
+	xcb_get_image_reply_t *reply;
+
+	if (!draw)
+	{
+	    if (pDrawable->type == DRAWABLE_WINDOW)
+		dmxScreen = dmxGetAlternateWindow (pDrawable, i++, &draw);
+	    else
+		dmxScreen = dmxGetAlternatePixmap (pDrawable, i++, &draw);
+
+	    if (!dmxScreen) continue;
+	}
+
+	reply = xcb_get_image_reply (dmxScreen->connection,
+				     xcb_get_image (dmxScreen->connection,
+						    format,
+						    draw,
+						    sx, sy, w, h,
+						    planeMask),
+				     NULL);
+	if (reply)
+	{
+	    const xcb_setup_t *setup = xcb_get_setup (dmxScreen->connection);
+	    uint32_t          bytes = xcb_get_image_data_length (reply);
+	    uint8_t           *data = xcb_get_image_data (reply);
+
+	    /* based on code in xcb_image.c, Copyright (C) 2007 Bart Massey */
+	    switch (format) {
+	    case XCB_IMAGE_FORMAT_XY_PIXMAP:
+		planeMask &= xcb_mask (reply->depth);
+		if (planeMask != xcb_mask (reply->depth))
 		{
-		    if (rpm & 1)
-		    {
-			memcpy (dst_plane, src_plane, size);
-			src_plane += size;
-		    }
-		    else
+		    uint32_t rpm = planeMask;
+		    uint8_t  *src_plane = data;
+		    uint8_t  *dst_plane = (uint8_t *) pdstLine;
+		    uint32_t scanline_pad = setup->bitmap_format_scanline_pad;
+		    uint32_t stride = xcb_roundup (w, scanline_pad) >> 3;
+		    uint32_t size = h * stride;
+		    int      i;
+
+		    if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
+			rpm = xcb_bit_reverse (planeMask, reply->depth);
+
+		    for (i = 0; i < reply->depth; i++)
 		    {
-			memset (dst_plane, 0, size);
+			if (rpm & 1)
+			{
+			    memcpy (dst_plane, src_plane, size);
+			    src_plane += size;
+			}
+			else
+			{
+			    memset (dst_plane, 0, size);
+			}
+
+			dst_plane += size;
 		    }
-
-		    dst_plane += size;
+		    break;
 		}
+
+		/* fall through */
+	    case XCB_IMAGE_FORMAT_Z_PIXMAP:
+		memmove (pdstLine, data, bytes);
+	    default:
 		break;
 	    }
 
-	    /* fall through */
-	case XCB_IMAGE_FORMAT_Z_PIXMAP:
-	    memmove (pdstLine, data, bytes);
-	default:
+	    free (reply);
 	    break;
 	}
 
-	free (reply);
+	if (pDrawable->type != DRAWABLE_WINDOW)
+	    break;
+
+	draw = None;
     }
 }
commit fc99433dbd7b3c89c84da9d6d61d085983160b7a
Author: David Reveman <davidr at novell.com>
Date:   Thu Nov 6 18:53:43 2008 -0500

    Call XineramaReinitData when changing screen size.

diff --git a/hw/dmx/dmxrandr.c b/hw/dmx/dmxrandr.c
index e40c850..7851681 100644
--- a/hw/dmx/dmxrandr.c
+++ b/hw/dmx/dmxrandr.c
@@ -706,6 +706,7 @@ dmxRRScreenSetSize (ScreenPtr pScreen,
 				      0, 0, width, height);
 
 	dmxSetWidthHeight (width, height);
+	XineramaReinitData (pScreen);
         dmxConnectionBlockCallback ();
     }
     else
commit 1e560d6adbad717557bd28a3de8a7b16abd12986
Author: David Reveman <davidr at novell.com>
Date:   Thu Nov 6 13:52:02 2008 -0500

    Never enter dmxDispatch through dmxGetImage as it might be
    called when sending a client reply.

diff --git a/hw/dmx/dmxgcops.c b/hw/dmx/dmxgcops.c
index 18da865..df86f58 100644
--- a/hw/dmx/dmxgcops.c
+++ b/hw/dmx/dmxgcops.c
@@ -589,10 +589,9 @@ static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
 void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
 		 unsigned int format, unsigned long planeMask, char *pdstLine)
 {
-    DMXScreenInfo          *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
-    Drawable               draw;
-    xcb_get_image_cookie_t cookie;
-    xcb_get_image_reply_t  *reply;
+    DMXScreenInfo         *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+    Drawable              draw;
+    xcb_get_image_reply_t *reply;
 
     /* Cannot get image from unviewable window */
     if (pDrawable->type == DRAWABLE_WINDOW) {
@@ -619,22 +618,13 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
         }
     }
 
-    cookie = xcb_get_image (dmxScreen->connection,
-			    format,
-			    draw,
-			    sx, sy, w, h,
-			    planeMask);
-
-    do {
-	dmxDispatch ();
-
-	if (xcb_poll_for_reply (dmxScreen->connection,
-				cookie.sequence,
-				(void **) &reply,
-				NULL))
-	    break;
-    } while (dmxWaitForResponse () && dmxScreen->alive);
-
+    reply = xcb_get_image_reply (dmxScreen->connection,
+				 xcb_get_image (dmxScreen->connection,
+						format,
+						draw,
+						sx, sy, w, h,
+						planeMask),
+				 NULL);
     if (reply)
     {
 	const xcb_setup_t *setup = xcb_get_setup (dmxScreen->connection);


More information about the xorg-commit mailing list