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:
parent
9d20d18fb9
commit
73698d41e4
46
dix/events.c
46
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
4
mi/mi.h
4
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 */ ,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user