[PATCH 5/6] events: Make XYToWindow a screen function pointer
Kristian Høgsberg
krh at bitplanet.net
Tue Mar 25 14:57:16 PDT 2014
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.
Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
---
dix/events.c | 99 +++++-----------------------------------------------
dix/touch.c | 10 ++++--
include/cursor.h | 2 ++
include/scrnintstr.h | 4 +++
mi/mi.h | 3 ++
mi/miscrinit.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 124 insertions(+), 93 deletions(-)
diff --git a/dix/events.c b/dix/events.c
index f05dada..601c1a4 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -565,7 +565,7 @@ XineramaConstrainCursor(DeviceIntPtr pDev)
(*pScreen->ConstrainCursor) (pDev, pScreen, &newBox);
}
-static Bool
+Bool
XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin)
{
SpritePtr pSprite = pDev->spriteInfo->sprite;
@@ -1302,6 +1302,7 @@ static void
ComputeFreezes(void)
{
DeviceIntPtr replayDev = syncEvents.replayDev;
+ ScreenPtr pScreen;
WindowPtr w;
GrabPtr grab;
DeviceIntPtr dev;
@@ -1318,8 +1319,9 @@ ComputeFreezes(void)
syncEvents.replayDev = (DeviceIntPtr) NULL;
- w = XYToWindow(replayDev->spriteInfo->sprite,
- event->root_x, event->root_y);
+ pScreen = RootWindow(replayDev->spriteInfo->sprite)->drawable.pScreen;
+ w = (*pScreen->XYToWindow) (replayDev, replayDev->spriteInfo->sprite,
+ event->root_x, event->root_y);
if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) {
if (IsTouchEvent((InternalEvent *) event)) {
TouchPointInfoPtr ti =
@@ -2835,92 +2837,6 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent)
return deliveries;
}
-static Bool
-PointInBorderSize(WindowPtr pWin, int x, int y)
-{
- BoxRec box;
-
- if (RegionContainsPoint(&pWin->borderSize, x, y, &box))
- return TRUE;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension &&
- XineramaSetWindowPntrs(inputInfo.pointer, pWin)) {
- SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite;
- int i;
-
- FOR_NSCREENS_FORWARD_SKIP(i) {
- if (RegionContainsPoint(&pSprite->windows[i]->borderSize,
- x + screenInfo.screens[0]->x -
- screenInfo.screens[i]->x,
- y + screenInfo.screens[0]->y -
- screenInfo.screens[i]->y, &box))
- return TRUE;
- }
- }
-#endif
- return FALSE;
-}
-
-/**
- * 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
-XYToWindow(SpritePtr pSprite, int x, int y)
-{
- WindowPtr pWin;
- BoxRec box;
-
- 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);
-}
-
/**
* Ungrab a currently FocusIn grabbed device and grab the device on the
* given window. If the win given is the NoneWin, the device is ungrabbed if
@@ -3017,6 +2933,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
{
WindowPtr prevSpriteWin, newSpriteWin;
SpritePtr pSprite = pDev->spriteInfo->sprite;
+ ScreenPtr pScreen;
verify_internal_event((InternalEvent *) ev);
@@ -3096,7 +3013,9 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
ev->root_y = pSprite->hot.y;
}
- newSpriteWin = XYToWindow(pSprite, pSprite->hot.x, pSprite->hot.y);
+ pScreen = RootWindow(pSprite)->drawable.pScreen;
+ newSpriteWin =
+ (*pScreen->XYToWindow) (pDev, pSprite, pSprite->hot.x, pSprite->hot.y);
if (newSpriteWin != prevSpriteWin) {
int sourceid;
diff --git a/dix/touch.c b/dix/touch.c
index 1eeed78..d9131eb 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -573,13 +573,17 @@ TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
{
TouchClassPtr t = sourcedev->touch;
SpritePtr sprite = &ti->sprite;
+ ScreenPtr screen;
+ WindowPtr root;
if (t->mode == XIDirectTouch) {
/* Focus immediately under the touchpoint in direct touch mode.
* XXX: Do we need to handle crossing screens here? */
- sprite->spriteTrace[0] =
- sourcedev->spriteInfo->sprite->hotPhys.pScreen->root;
- XYToWindow(sprite, ev->device_event.root_x, ev->device_event.root_y);
+ root = sourcedev->spriteInfo->sprite->hotPhys.pScreen->root;
+ sprite->spriteTrace[0] = root;
+ screen = root->drawable.pScreen;
+ (*screen->XYToWindow) (sourcedev, sprite, ev->device_event.root_x,
+ ev->device_event.root_y);
}
else if (!TouchBuildDependentSpriteTrace(sourcedev, sprite))
return FALSE;
diff --git a/include/cursor.h b/include/cursor.h
index 9da08af..d1467dd 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -131,6 +131,8 @@ extern _X_EXPORT void GetSpritePosition(struct _DeviceIntRec * /* pDev */ ,
#ifdef PANORAMIX
extern _X_EXPORT int XineramaGetCursorScreen(struct _DeviceIntRec *pDev);
+extern _X_EXPORT Bool XineramaSetWindowPntrs(DeviceIntPtr pDev,
+ WindowPtr pWin);
#endif /* PANORAMIX */
#endif /* CURSOR_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 86da789..412617b 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)(DeviceIntPtr pDev,
+ 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..192f708 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -537,4 +537,7 @@ extern _X_EXPORT void miPolyFillArc(DrawablePtr /*pDraw */ ,
xArc * /*parcs */
);
+extern _X_EXPORT WindowPtr miSpriteTrace(SpritePtr pSprite, int x, int y
+ );
+
#endif /* MI_H */
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index 6aed52f..edf5cae 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -38,6 +38,12 @@ from The Open Group.
#include "pixmapstr.h"
#include "dix.h"
#include "miline.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
#ifdef MITSHM
#include <X11/extensions/shm.h>
#include "shmint.h"
@@ -202,6 +208,98 @@ miSetScreenPixmap(PixmapPtr pPix)
pPix->drawable.pScreen->devPrivate = (void *) pPix;
}
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (RegionContainsPoint(&pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension &&
+ XineramaSetWindowPntrs(inputInfo.pointer, pWin)) {
+ SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite;
+ int i;
+
+ FOR_NSCREENS_FORWARD_SKIP(i) {
+ if (RegionContainsPoint(&pSprite->windows[i]->borderSize,
+ x + screenInfo.screens[0]->x -
+ screenInfo.screens[i]->x,
+ y + screenInfo.screens[0]->y -
+ screenInfo.screens[i]->y, &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+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.
+ */
+static WindowPtr
+miXYToWindow(DeviceIntPtr master, SpritePtr pSprite, int x, int y)
+{
+ pSprite->spriteTraceGood = 1; /* root window still there */
+ return miSpriteTrace(pSprite, x, y);
+}
+
Bool
miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
int xsize, int ysize, /* in pixels */
@@ -272,6 +370,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);
--
1.9.0
More information about the xorg-devel
mailing list