From: Keith Packard Date: Tue, 1 Apr 2014 06:55:25 +0000 (-0700) Subject: Make XYToWindow a screen function X-Git-Tag: upstream/1.15.99.902~5^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=73698d41e41ce76bef2d9a90b46ac0c24ae148dd;p=platform%2Fupstream%2Fxorg-server.git 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 Reviewed-by: Kristian Høgsberg --- diff --git a/dix/events.c b/dix/events.c index f05dada..125a0ee 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 36463f2..cbf949b 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 86da789..5197c79 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 950ee38..1209a16 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 6aed52f..00c15f7 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 697ffbc..951b8c5 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); +}