Make XYToWindow a screen function
authorKeith Packard <keithp@keithp.com>
Tue, 1 Apr 2014 06:55:25 +0000 (23:55 -0700)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 1 Apr 2014 17:30:42 +0000 (10:30 -0700)
This allows DDXen to override the window picking to account for
native windows not seen by the X server.  The bulk of the picking logic
is exposed as a new helper function, miSpriteTrace().  This function
completes the sprite trace filled out by the caller, and can be set up
to start the search from a given toplevel window.

v2: Leave existing XYToWindow API in place for API compatibility

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
dix/events.c
include/input.h
include/scrnintstr.h
mi/mi.h
mi/miscrinit.c
mi/miwindow.c

index f05dada..125a0ee 100644 (file)
@@ -2835,7 +2835,7 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent)
     return deliveries;
 }
 
-static Bool
+Bool
 PointInBorderSize(WindowPtr pWin, int x, int y)
 {
     BoxRec box;
@@ -2876,49 +2876,9 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
 WindowPtr
 XYToWindow(SpritePtr pSprite, int x, int y)
 {
-    WindowPtr pWin;
-    BoxRec box;
+    ScreenPtr pScreen = RootWindow(pSprite)->drawable.pScreen;
 
-    pSprite->spriteTraceGood = 1;       /* root window still there */
-    pWin = RootWindow(pSprite)->firstChild;
-    while (pWin) {
-        if ((pWin->mapped) &&
-            (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
-            (x < pWin->drawable.x + (int) pWin->drawable.width +
-             wBorderWidth(pWin)) &&
-            (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
-            (y < pWin->drawable.y + (int) pWin->drawable.height +
-             wBorderWidth(pWin))
-            /* When a window is shaped, a further check
-             * is made to see if the point is inside
-             * borderSize
-             */
-            && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
-            && (!wInputShape(pWin) ||
-                RegionContainsPoint(wInputShape(pWin),
-                                    x - pWin->drawable.x,
-                                    y - pWin->drawable.y, &box))
-#ifdef ROOTLESS
-            /* In rootless mode windows may be offscreen, even when
-             * they're in X's stack. (E.g. if the native window system
-             * implements some form of virtual desktop system).
-             */
-            && !pWin->rootlessUnhittable
-#endif
-            ) {
-            if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
-                pSprite->spriteTraceSize += 10;
-                pSprite->spriteTrace = realloc(pSprite->spriteTrace,
-                                               pSprite->spriteTraceSize *
-                                               sizeof(WindowPtr));
-            }
-            pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
-            pWin = pWin->firstChild;
-        }
-        else
-            pWin = pWin->nextSib;
-    }
-    return DeepestSpriteWin(pSprite);
+    return (*pScreen->XYToWindow)(pScreen, pSprite, x, y);
 }
 
 /**
index 36463f2..cbf949b 100644 (file)
@@ -607,6 +607,7 @@ extern int GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type);
 void FixUpEventFromWindow(SpritePtr pSprite,
                           xEvent *xE,
                           WindowPtr pWin, Window child, Bool calcChild);
+extern Bool PointInBorderSize(WindowPtr pWin, int x, int y);
 extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
 extern int EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win);
 extern Bool ActivatePassiveGrab(DeviceIntPtr dev, GrabPtr grab,
index 86da789..5197c79 100644 (file)
@@ -353,6 +353,9 @@ typedef Bool (*StopPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr);
 
 typedef Bool (*ReplaceScanoutPixmapProcPtr)(DrawablePtr, PixmapPtr, Bool);
 
+typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
+                                       SpritePtr pSprite, int x, int y);
+
 typedef struct _Screen {
     int myNum;                  /* index of this instance in Screens[] */
     ATOM id;
@@ -513,6 +516,7 @@ typedef struct _Screen {
     struct xorg_list offload_head;
 
     ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
+    XYToWindowProcPtr XYToWindow;
 } ScreenRec;
 
 static inline RegionPtr
diff --git a/mi/mi.h b/mi/mi.h
index 950ee38..1209a16 100644 (file)
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -507,6 +507,10 @@ extern _X_EXPORT void miMarkUnrealizedWindow(WindowPtr /*pChild */ ,
 extern _X_EXPORT void miSegregateChildren(WindowPtr pWin, RegionPtr pReg,
                                           int depth);
 
+extern _X_EXPORT WindowPtr miSpriteTrace(SpritePtr pSprite, int x, int y);
+
+extern _X_EXPORT WindowPtr miXYToWindow(ScreenPtr pScreen, SpritePtr pSprite, int x, int y);
+
 /* mizerarc.c */
 
 extern _X_EXPORT void miZeroPolyArc(DrawablePtr /*pDraw */ ,
index 6aed52f..00c15f7 100644 (file)
@@ -272,6 +272,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
     pScreen->ChangeBorderWidth = miChangeBorderWidth;
     pScreen->SetShape = miSetShape;
     pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
+    pScreen->XYToWindow = miXYToWindow;
 
     miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
 
index 697ffbc..951b8c5 100644 (file)
@@ -57,6 +57,7 @@ SOFTWARE.
 #include "scrnintstr.h"
 #include "pixmapstr.h"
 #include "mivalidate.h"
+#include "inputstr.h"
 
 void
 miClearToBackground(WindowPtr pWin,
@@ -758,3 +759,68 @@ miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
             miSegregateChildren(pChild, pReg, depth);
     }
 }
+
+WindowPtr
+miSpriteTrace(SpritePtr pSprite, int x, int y)
+{
+    WindowPtr pWin;
+    BoxRec box;
+
+    pWin = DeepestSpriteWin(pSprite);
+    while (pWin) {
+        if ((pWin->mapped) &&
+            (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
+            (x < pWin->drawable.x + (int) pWin->drawable.width +
+             wBorderWidth(pWin)) &&
+            (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
+            (y < pWin->drawable.y + (int) pWin->drawable.height +
+             wBorderWidth(pWin))
+            /* When a window is shaped, a further check
+             * is made to see if the point is inside
+             * borderSize
+             */
+            && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+            && (!wInputShape(pWin) ||
+                RegionContainsPoint(wInputShape(pWin),
+                                    x - pWin->drawable.x,
+                                    y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+            /* In rootless mode windows may be offscreen, even when
+             * they're in X's stack. (E.g. if the native window system
+             * implements some form of virtual desktop system).
+             */
+            && !pWin->rootlessUnhittable
+#endif
+            ) {
+            if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
+                pSprite->spriteTraceSize += 10;
+                pSprite->spriteTrace = realloc(pSprite->spriteTrace,
+                                               pSprite->spriteTraceSize *
+                                               sizeof(WindowPtr));
+            }
+            pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+            pWin = pWin->firstChild;
+        }
+        else
+            pWin = pWin->nextSib;
+    }
+    return DeepestSpriteWin(pSprite);
+}
+
+/**
+ * Traversed from the root window to the window at the position x/y. While
+ * traversing, it sets up the traversal history in the spriteTrace array.
+ * After completing, the spriteTrace history is set in the following way:
+ *   spriteTrace[0] ... root window
+ *   spriteTrace[1] ... top level window that encloses x/y
+ *       ...
+ *   spriteTrace[spriteTraceGood - 1] ... window at x/y
+ *
+ * @returns the window at the given coordinates.
+ */
+WindowPtr
+miXYToWindow(ScreenPtr pScreen, SpritePtr pSprite, int x, int y)
+{
+    pSprite->spriteTraceGood = 1;       /* root window still there */
+    return miSpriteTrace(pSprite, x, y);
+}