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>
This commit is contained in:
Keith Packard 2014-03-31 23:55:25 -07:00 committed by Kristian Høgsberg
parent 9d20d18fb9
commit 73698d41e4
6 changed files with 79 additions and 43 deletions

View 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);
}
/**

View 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,

View 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

View File

@ -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 */ ,

View 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);

View 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);
}