summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-03-31 23:55:25 -0700
committerKristian Høgsberg <krh@bitplanet.net>2014-04-01 10:30:42 -0700
commit73698d41e41ce76bef2d9a90b46ac0c24ae148dd (patch)
tree5b3071927bc4315321cc9872361b5763caf3806c
parent9d20d18fb9dcc74bfa5392a2da40fd41b3e640d3 (diff)
Make XYToWindow a screen function
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>
-rw-r--r--dix/events.c46
-rw-r--r--include/input.h1
-rw-r--r--include/scrnintstr.h4
-rw-r--r--mi/mi.h4
-rw-r--r--mi/miscrinit.c1
-rw-r--r--mi/miwindow.c66
6 files changed, 79 insertions, 43 deletions
diff --git a/dix/events.c b/dix/events.c
index f05dada3d..125a0ee29 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -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);
}
/**
diff --git a/include/input.h b/include/input.h
index 36463f2d1..cbf949b53 100644
--- a/include/input.h
+++ b/include/input.h
@@ -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,
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 86da78966..5197c79f5 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -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 950ee3812..1209a16c4 100644
--- 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 */ ,
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index 6aed52f51..00c15f713 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -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);
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 697ffbc26..951b8c519 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -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);
+}