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 <k...@bitplanet.net> --- dix/events.c | 99 +++++----------------------------------------------- dix/touch.c | 10 ++++-- include/cursor.h | 2 ++ include/input.h | 1 - include/scrnintstr.h | 4 +++ mi/mi.h | 3 ++ mi/miscrinit.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 94 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/input.h b/include/input.h index 36463f2..322ddc0 100644 --- a/include/input.h +++ b/include/input.h @@ -607,7 +607,6 @@ extern int GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type); void FixUpEventFromWindow(SpritePtr pSprite, xEvent *xE, WindowPtr pWin, Window child, Bool calcChild); -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, InternalEvent *ev, InternalEvent *real_event); 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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel