diff --git a/dix/dix_priv.h b/dix/dix_priv.h index c8abe051fc..c7770bbde4 100644 --- a/dix/dix_priv.h +++ b/dix/dix_priv.h @@ -807,4 +807,15 @@ static inline void SwapLongs(CARD32 *list, unsigned long count) { #define SwapRestL(stuff) \ SwapLongs((CARD32 *)(stuff + 1), (client->req_len - (sizeof(*stuff) >> 2))) +/* + * @brief lookup window by XID + * + * This globally looks for Window with given XID (all screens, all clients) + * and returns a pointer to it. If not found, returns NULL. + * + * Unlike ::dixLookupWindow() it doesn't scan only one given client, nor does + * it do any XACE calls. + */ +WindowPtr dixLookupWindowByXID(Window window); + #endif /* _XSERVER_DIX_PRIV_H */ diff --git a/dix/lookup.c b/dix/lookup.c index 406f702645..dee11b457a 100644 --- a/dix/lookup.c +++ b/dix/lookup.c @@ -39,3 +39,35 @@ ClientPtr dixClientForOtherClients(OtherClientsPtr pOtherClients) { return dixClientForXID(pOtherClients->resource); } + +struct window_xid_match { + WindowPtr pWin; + Window id; +}; + +static int dix_match_window_xid(WindowPtr pWin, void *ptr) +{ + struct window_xid_match *walk = (struct window_xid_match*) ptr; + + if (walk->id == pWin->drawable.id) { + walk->pWin = pWin; + return WT_STOPWALKING; + } + else + return WT_WALKCHILDREN; +} + +WindowPtr dixLookupWindowByXID(Window window) +{ + struct window_xid_match walk = { + .id = window, + }; + + for (int i = 0; i < screenInfo.numScreens; i++) { + WalkTree(screenInfo.screens[i], dix_match_window_xid, &walk); + if (walk.pWin) + break; + } + + return walk.pWin; +}