From e1aed88be92c27d76bff1743f35f9915dea9264f Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 17:00:29 +0000 Subject: [PATCH 01/11] Input: Swap flags in DeviceEvents Swap flags for different-endian clients when delivering XI2 DeviceEvents. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- Xi/extinit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Xi/extinit.c b/Xi/extinit.c index 546ccb42e..82df7eb02 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -757,6 +757,7 @@ static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to) swapl(&to->mods.latched_mods, n); swapl(&to->mods.locked_mods, n); swapl(&to->mods.effective_mods, n); + swapl(&to->flags, n); ptr = (char*)(&to[1]); ptr += from->buttons_len * 4; From 2592effef5f171af3f01a2b5130d9747403140f6 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 13:42:06 +0000 Subject: [PATCH 02/11] Test: Input: Add helper function for failing EventToCore We have quite a few tests which involve checking that EventToCore fails for specific events, so refactor them into a separate function. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- test/input.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/test/input.c b/test/input.c index 1fe228c32..c389a403a 100644 --- a/test/input.c +++ b/test/input.c @@ -256,7 +256,7 @@ static void dix_event_to_core(int type) #undef test_event } -static void dix_event_to_core_conversion(void) +static void dix_event_to_core_fail(int evtype, int expected_rc) { DeviceEvent ev; xEvent core; @@ -265,25 +265,18 @@ static void dix_event_to_core_conversion(void) ev.header = 0xFF; ev.length = sizeof(DeviceEvent); - ev.type = 0; + ev.type = evtype; rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(rc == BadImplementation); + g_assert(rc == expected_rc); +} - ev.type = 1; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(rc == BadImplementation); - - ev.type = ET_ProximityOut + 1; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(rc == BadImplementation); - - ev.type = ET_ProximityIn; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(rc == BadMatch); - - ev.type = ET_ProximityOut; - rc = EventToCore((InternalEvent*)&ev, &core); - g_assert(rc == BadMatch); +static void dix_event_to_core_conversion(void) +{ + dix_event_to_core_fail(0, BadImplementation); + dix_event_to_core_fail(1, BadImplementation); + dix_event_to_core_fail(ET_ProximityOut + 1, BadImplementation); + dix_event_to_core_fail(ET_ProximityIn, BadMatch); + dix_event_to_core_fail(ET_ProximityOut, BadMatch); dix_event_to_core(ET_KeyPress); dix_event_to_core(ET_KeyRelease); From a083efe8715e8b29c9bd7f4e7bb429a94620bfc4 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 16:06:29 +0000 Subject: [PATCH 03/11] Test: Input: Check flags on DeviceEvent Add initial validation of acceptable flags for XI2 device events, and make sure they're swapped. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- test/xi2/protocol-eventconvert.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/xi2/protocol-eventconvert.c b/test/xi2/protocol-eventconvert.c index 211cce6ad..0478c33fe 100644 --- a/test/xi2/protocol-eventconvert.c +++ b/test/xi2/protocol-eventconvert.c @@ -272,6 +272,7 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out, int buttons, valuators; int i; unsigned char *ptr; + uint32_t flagmask = 0; FP3232 *values; if (swap) { @@ -297,6 +298,7 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out, swapl(&out->mods.latched_mods, n); swapl(&out->mods.locked_mods, n); swapl(&out->mods.effective_mods, n); + swapl(&out->flags, n); } g_assert(out->extension == 0); /* IReqCode defaults to 0 */ @@ -308,7 +310,15 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out, g_assert(out->deviceid == in->deviceid); g_assert(out->sourceid == in->sourceid); - g_assert(out->flags == 0); /* FIXME: we don't set the flags yet */ + switch (in->type) { + case ET_KeyPress: + flagmask = XIKeyRepeat; + break; + default: + flagmask = 0; + break; + } + g_assert((out->flags & ~flagmask) == 0); g_assert(out->root == in->root); g_assert(out->event == None); /* set in FixUpEventFromWindow */ From 06a103ad1d6a0ef6146c97a8c81dc7de1c0a0083 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 16:37:48 +0000 Subject: [PATCH 04/11] Test: Input: Test up to supported server, not protocol, events When building against a newer inputproto, the server may support fewer than XI_LASTEVENT events. We already have XI2LASTEVENT for the highest event number supported by the server, so use that instead. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- test/xi2/protocol-xiselectevents.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/xi2/protocol-xiselectevents.c b/test/xi2/protocol-xiselectevents.c index fe1c26df8..f951a14fe 100644 --- a/test/xi2/protocol-xiselectevents.c +++ b/test/xi2/protocol-xiselectevents.c @@ -131,7 +131,7 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) { int i, j; xXIEventMask *mask; - int nmasks = (XI_LASTEVENT + 7)/8; + int nmasks = (XI2LASTEVENT + 7)/8; unsigned char *bits; mask = (xXIEventMask*)&req[1]; @@ -150,14 +150,14 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) request_XISelectEvent(req, Success); /* Test 1: - * mask may be larger than needed for XI_LASTEVENT. + * mask may be larger than needed for XI2LASTEVENT. * Test setting each valid mask bit, while leaving unneeded bits 0. * -> Success */ bits = (unsigned char*)&mask[1]; mask->mask_len = (nmasks + 3)/4 * 10; memset(bits, 0, mask->mask_len * 4); - for (j = 0; j <= XI_LASTEVENT; j++) + for (j = 0; j <= XI2LASTEVENT; j++) { SetBit(bits, j); request_XISelectEvent(req, Success); @@ -165,7 +165,7 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) } /* Test 2: - * mask may be larger than needed for XI_LASTEVENT. + * mask may be larger than needed for XI2LASTEVENT. * Test setting all valid mask bits, while leaving unneeded bits 0. * -> Success */ @@ -173,21 +173,21 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) mask->mask_len = (nmasks + 3)/4 * 10; memset(bits, 0, mask->mask_len * 4); - for (j = 0; j <= XI_LASTEVENT; j++) + for (j = 0; j <= XI2LASTEVENT; j++) { SetBit(bits, j); request_XISelectEvent(req, Success); } /* Test 3: - * mask is larger than needed for XI_LASTEVENT. If any unneeded bit + * mask is larger than needed for XI2LASTEVENT. If any unneeded bit * is set -> BadValue */ bits = (unsigned char*)&mask[1]; mask->mask_len = (nmasks + 3)/4 * 10; memset(bits, 0, mask->mask_len * 4); - for (j = XI_LASTEVENT + 1; j < mask->mask_len * 4; j++) + for (j = XI2LASTEVENT + 1; j < mask->mask_len * 4; j++) { SetBit(bits, j); request_XISelectEvent(req, BadValue); @@ -200,7 +200,7 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) bits = (unsigned char*)&mask[1]; mask->mask_len = (nmasks + 3)/4; memset(bits, 0, mask->mask_len * 4); - for (j = 0; j <= XI_LASTEVENT; j++) + for (j = 0; j <= XI2LASTEVENT; j++) { SetBit(bits, j); request_XISelectEvent(req, Success); @@ -228,7 +228,7 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req) bits = (unsigned char*)&mask[1]; mask->mask_len = (nmasks + 3)/4; memset(bits, 0, mask->mask_len * 4); - for (j = 0; j <= XI_LASTEVENT; j++) + for (j = 0; j <= XI2LASTEVENT; j++) SetBit(bits, j); ClearBit(bits, XI_HierarchyChanged); for (j = 1; j < 6; j++) From 23c37ce1fe42e3da0609a566478e947843b05023 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 27 Dec 2010 12:48:42 +0000 Subject: [PATCH 05/11] Input: Export SpriteRec for use in public API Change its definition to be more in line with other structs, so we can use it from input.h. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- include/input.h | 1 + include/inputstr.h | 82 +++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/include/input.h b/include/input.h index 9f3227fb0..76f646f39 100644 --- a/include/input.h +++ b/include/input.h @@ -103,6 +103,7 @@ typedef struct _OtherClients *OtherClientsPtr; typedef struct _InputClients *InputClientsPtr; typedef struct _DeviceIntRec *DeviceIntPtr; typedef struct _ClassesRec *ClassesPtr; +typedef struct _SpriteRec *SpritePtr; typedef union _GrabMask GrabMask; typedef struct _EventList { diff --git a/include/inputstr.h b/include/inputstr.h index 44de9c44a..b74ee0454 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -203,6 +203,47 @@ typedef struct _GrabRec { unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE]; } GrabRec; +/** + * Sprite information for a device. + */ +typedef struct _SpriteRec { + CursorPtr current; + BoxRec hotLimits; /* logical constraints of hot spot */ + Bool confined; /* confined to screen */ + RegionPtr hotShape; /* additional logical shape constraint */ + BoxRec physLimits; /* physical constraints of hot spot */ + WindowPtr win; /* window of logical position */ + HotSpot hot; /* logical pointer position */ + HotSpot hotPhys; /* physical pointer position */ +#ifdef PANORAMIX + ScreenPtr screen; /* all others are in Screen 0 coordinates */ + RegionRec Reg1; /* Region 1 for confining motion */ + RegionRec Reg2; /* Region 2 for confining virtual motion */ + WindowPtr windows[MAXSCREENS]; + WindowPtr confineWin; /* confine window */ +#endif + /* The window trace information is used at dix/events.c to avoid having + * to compute all the windows between the root and the current pointer + * window each time a button or key goes down. The grabs on each of those + * windows must be checked. + * spriteTraces should only be used at dix/events.c! */ + WindowPtr *spriteTrace; + int spriteTraceSize; + int spriteTraceGood; + + /* Due to delays between event generation and event processing, it is + * possible that the pointer has crossed screen boundaries between the + * time in which it begins generating events and the time when + * those events are processed. + * + * pEnqueueScreen: screen the pointer was on when the event was generated + * pDequeueScreen: screen the pointer was on when the event is processed + */ + ScreenPtr pEnqueueScreen; + ScreenPtr pDequeueScreen; + +} SpriteRec; + typedef struct _KeyClassRec { int sourceid; CARD8 down[DOWN_LENGTH]; @@ -360,47 +401,6 @@ typedef struct _ClassesRec { } ClassesRec; -/** - * Sprite information for a device. - */ -typedef struct { - CursorPtr current; - BoxRec hotLimits; /* logical constraints of hot spot */ - Bool confined; /* confined to screen */ - RegionPtr hotShape; /* additional logical shape constraint */ - BoxRec physLimits; /* physical constraints of hot spot */ - WindowPtr win; /* window of logical position */ - HotSpot hot; /* logical pointer position */ - HotSpot hotPhys; /* physical pointer position */ -#ifdef PANORAMIX - ScreenPtr screen; /* all others are in Screen 0 coordinates */ - RegionRec Reg1; /* Region 1 for confining motion */ - RegionRec Reg2; /* Region 2 for confining virtual motion */ - WindowPtr windows[MAXSCREENS]; - WindowPtr confineWin; /* confine window */ -#endif - /* The window trace information is used at dix/events.c to avoid having - * to compute all the windows between the root and the current pointer - * window each time a button or key goes down. The grabs on each of those - * windows must be checked. - * spriteTraces should only be used at dix/events.c! */ - WindowPtr *spriteTrace; - int spriteTraceSize; - int spriteTraceGood; - - /* Due to delays between event generation and event processing, it is - * possible that the pointer has crossed screen boundaries between the - * time in which it begins generating events and the time when - * those events are processed. - * - * pEnqueueScreen: screen the pointer was on when the event was generated - * pDequeueScreen: screen the pointer was on when the event is processed - */ - ScreenPtr pEnqueueScreen; - ScreenPtr pDequeueScreen; - -} SpriteRec, *SpritePtr; - /* Device properties */ typedef struct _XIPropertyValue { From 10d6c3ca103ea155488cd2f29052334b5691e680 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 27 Dec 2010 13:06:03 +0000 Subject: [PATCH 06/11] Input: Make RootWindow() take a sprite instead of device GetCurrentRootWindow already works for the device case, although not as an lvalue. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/events.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/dix/events.c b/dix/events.c index f280f9d7a..c24d77240 100644 --- a/dix/events.c +++ b/dix/events.c @@ -256,7 +256,7 @@ EventSyncInfoRec syncEvents; /** * The root window the given device is currently on. */ -#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] +#define RootWindow(sprite) sprite->spriteTrace[0] static xEvent* swapEvent = NULL; static int swapEventLen = 0; @@ -879,7 +879,7 @@ CheckVirtualMotion( #ifdef PANORAMIX if (noPanoramiXExtension) /* No typo. Only set the root win if disabled */ #endif - RootWindow(pDev) = pSprite->hot.pScreen->root; + RootWindow(pDev->spriteInfo->sprite) = pSprite->hot.pScreen->root; } static void @@ -1012,7 +1012,7 @@ PostNewCursor(DeviceIntPtr pDev) WindowPtr GetCurrentRootWindow(DeviceIntPtr dev) { - return RootWindow(dev); + return RootWindow(dev->spriteInfo->sprite); } /** @@ -1511,7 +1511,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse) DoEnterLeaveEvents(mouse, mouse->id, grab->window, mouse->spriteInfo->sprite->win, NotifyUngrab); if (grab->confineTo) - ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE); + ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE); PostNewCursor(mouse); if (grab->cursor) FreeCursor(grab->cursor, (Cursor)0); @@ -2247,7 +2247,7 @@ FixUpEventFromWindow( event->evtype == XI_PropertyEvent) return; - event->root = RootWindow(pDev)->drawable.id; + event->root = GetCurrentRootWindow(pDev)->drawable.id; event->event = pWin->drawable.id; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { @@ -2268,7 +2268,7 @@ FixUpEventFromWindow( } else { - XE_KBPTR.root = RootWindow(pDev)->drawable.id; + XE_KBPTR.root = GetCurrentRootWindow(pDev)->drawable.id; XE_KBPTR.event = pWin->drawable.id; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { @@ -2564,7 +2564,7 @@ XYToWindow(DeviceIntPtr pDev, int x, int y) pSprite = pDev->spriteInfo->sprite; pSprite->spriteTraceGood = 1; /* root window still there */ - pWin = RootWindow(pDev)->firstChild; + pWin = GetCurrentRootWindow(pDev)->firstChild; while (pWin) { if ((pWin->mapped) && @@ -2737,7 +2737,8 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) { pSprite->hot.pScreen = pSprite->hotPhys.pScreen; - RootWindow(pDev) = pSprite->hot.pScreen->root; + RootWindow(pDev->spriteInfo->sprite) = + pSprite->hot.pScreen->root; } } @@ -2942,7 +2943,7 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) FatalError("Failed to allocate spriteTrace"); pSprite->spriteTraceSize = 32; - RootWindow(pDev) = pWin; + RootWindow(pDev->spriteInfo->sprite) = pWin; pSprite->spriteTraceGood = 1; pSprite->pEnqueueScreen = pScreen; @@ -4554,7 +4555,8 @@ ProcGrabPointer(ClientPtr client) if (grab) { if (grab->confineTo && !confineTo) - ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE); + ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, + FALSE); oldCursor = grab->cursor; } @@ -4883,7 +4885,7 @@ ProcQueryPointer(ClientPtr client) rep.mask = mouse->button ? (mouse->button->state) : 0; rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state); rep.length = 0; - rep.root = (RootWindow(mouse))->drawable.id; + rep.root = (GetCurrentRootWindow(mouse))->drawable.id; rep.rootX = pSprite->hot.x; rep.rootY = pSprite->hot.y; rep.child = None; @@ -5042,7 +5044,7 @@ ProcSendEvent(ClientPtr client) /* If the input focus is PointerRootWin, send the event to where the pointer is if possible, then perhaps propogate up to root. */ if (inputFocus == PointerRootWin) - inputFocus = RootWindow(dev); + inputFocus = GetCurrentRootWindow(dev); if (IsParent(inputFocus, pSprite->win)) { From 07a892cd8276f8092de95f1909f2ebec6f5fdf08 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 20 Sep 2010 15:03:04 +1000 Subject: [PATCH 07/11] Input: Pass sprite instead of device to FixUpEventFromWindow Since FixUpEventFromWindow only uses the sprite trace to determine the window stack, pass in a sprite instead of hardcoding the device sprite, so we can deliver to windows other than the one currently containing the sprite. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- Xi/exevents.c | 3 ++- dix/events.c | 43 +++++++++++++++++++++---------------------- include/input.h | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 8615fd456..327873e29 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1261,7 +1261,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, xi2event->group.effective_group = dev->key->xkbInfo->state.group; } - FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); + FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin, + None, FALSE); DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, GetEventFilter(dev, (xEvent*)xi2event), NullGrab); diff --git a/dix/events.c b/dix/events.c index c24d77240..df59a4e61 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2181,9 +2181,8 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, return 2; } -static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event) +static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event) { - SpritePtr pSprite = dev->spriteInfo->sprite; WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1]; Window child = None; @@ -2222,16 +2221,14 @@ static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event) */ void FixUpEventFromWindow( - DeviceIntPtr pDev, + SpritePtr pSprite, xEvent *xE, WindowPtr pWin, Window child, Bool calcChild) { - SpritePtr pSprite = pDev->spriteInfo->sprite; - if (calcChild) - child = FindChildForEvent(pDev, pWin); + child = FindChildForEvent(pSprite, pWin); if (XI2_EVENT(xE)) { @@ -2247,7 +2244,7 @@ FixUpEventFromWindow( event->evtype == XI_PropertyEvent) return; - event->root = GetCurrentRootWindow(pDev)->drawable.id; + event->root = RootWindow(pSprite)->drawable.id; event->event = pWin->drawable.id; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { @@ -2268,7 +2265,7 @@ FixUpEventFromWindow( } else { - XE_KBPTR.root = GetCurrentRootWindow(pDev)->drawable.id; + XE_KBPTR.root = RootWindow(pSprite)->drawable.id; XE_KBPTR.event = pWin->drawable.id; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { @@ -2374,6 +2371,7 @@ int DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, WindowPtr stopAt, DeviceIntPtr dev) { + SpritePtr pSprite = dev->spriteInfo->sprite; Window child = None; Mask filter; int deliveries = 0; @@ -2396,7 +2394,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, { /* XXX: XACE */ filter = GetEventFilter(dev, xi2); - FixUpEventFromWindow(dev, xi2, pWin, child, FALSE); + FixUpEventFromWindow(pSprite, xi2, pWin, child, FALSE); deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1, filter, grab); free(xi2); @@ -2414,7 +2412,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, if (rc == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success) { filter = GetEventFilter(dev, xE); - FixUpEventFromWindow(dev, xE, pWin, child, FALSE); + FixUpEventFromWindow(pSprite, xE, pWin, child, FALSE); deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter, grab); if (deliveries > 0) @@ -2432,7 +2430,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, if (rc == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) { filter = GetEventFilter(dev, &core); - FixUpEventFromWindow(dev, &core, pWin, child, FALSE); + FixUpEventFromWindow(pSprite, &core, pWin, child, FALSE); deliveries = DeliverEventsToWindow(dev, pWin, &core, 1, filter, grab); if (deliveries > 0) @@ -3368,6 +3366,7 @@ CheckPassiveGrabsOnWindow( DeviceEvent *event, BOOL checkCore) { + SpritePtr pSprite = device->spriteInfo->sprite; GrabPtr grab = wPassiveGrabs(pWin); GrabRec tempGrab; GrabInfoPtr grabinfo; @@ -3531,7 +3530,7 @@ CheckPassiveGrabsOnWindow( if (xE) { - FixUpEventFromWindow(device, xE, grab->window, None, TRUE); + FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); TryClientEvents(rClient(grab), device, xE, count, GetEventFilter(device, xE), @@ -3683,7 +3682,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) { /* XXX: XACE */ int filter = GetEventFilter(keybd, xi2); - FixUpEventFromWindow(ptr, xi2, focus, None, FALSE); + FixUpEventFromWindow(ptr->spriteInfo->sprite, xi2, focus, None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1, filter, NullGrab); if (deliveries > 0) @@ -3696,7 +3695,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) if (rc == Success && XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success) { - FixUpEventFromWindow(ptr, xE, focus, None, FALSE); + FixUpEventFromWindow(ptr->spriteInfo->sprite, xE, focus, None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, xE, count, GetEventFilter(keybd, xE), NullGrab); @@ -3712,7 +3711,8 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) rc = EventToCore(event, &core); if (rc == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) { - FixUpEventFromWindow(keybd, &core, focus, None, FALSE); + FixUpEventFromWindow(keybd->spriteInfo->sprite, &core, focus, + None, FALSE); deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, GetEventFilter(keybd, &core), NullGrab); @@ -3802,8 +3802,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, rc = EventToCore(event, &core); if (rc == Success) { - FixUpEventFromWindow(thisDev, &core, grab->window, - None, TRUE); + FixUpEventFromWindow(pSprite, &core, grab->window, None, TRUE); if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, &core, 1) || XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), @@ -3830,7 +3829,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, grab->xi2mask[XIAllMasterDevices][evtype/8] | grab->xi2mask[thisDev->id][evtype/8]; /* try XI2 event */ - FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE); + FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE); /* XXX: XACE */ deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask, GetEventFilter(thisDev, xi2), grab); @@ -3851,8 +3850,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, else mask = grab->eventMask; - FixUpEventFromWindow(thisDev, xi, grab->window, - None, TRUE); + FixUpEventFromWindow(pSprite, xi, grab->window, None, TRUE); if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, xi, count) || @@ -4198,7 +4196,7 @@ CoreEnterLeaveEvent( event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x; event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y; /* Counts on the same initial structure of crossing & button events! */ - FixUpEventFromWindow(mouse, &event, pWin, None, FALSE); + FixUpEventFromWindow(mouse->spriteInfo->sprite, &event, pWin, None, FALSE); /* Enter/Leave events always set child */ event.u.enterLeave.child = child; event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? @@ -4298,7 +4296,8 @@ DeviceEnterLeaveEvent( event->group.locked_group = kbd->key->xkbInfo->state.locked_group; } - FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE); + FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent*)event, pWin, + None, FALSE); filter = GetEventFilter(mouse, (xEvent*)event); diff --git a/include/input.h b/include/input.h index 76f646f39..a20f8a07a 100644 --- a/include/input.h +++ b/include/input.h @@ -528,7 +528,7 @@ extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs); /* misc event helpers */ extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event); extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev); -void FixUpEventFromWindow(DeviceIntPtr pDev, +void FixUpEventFromWindow(SpritePtr pSprite, xEvent *xE, WindowPtr pWin, Window child, From 690476250f58616d5156317e01ba547497f4331a Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 20 Sep 2010 15:03:05 +1000 Subject: [PATCH 08/11] Input: Pass sprite instead of device to XYToWindow, make non-static XYToWindow calculates the position of the cursor and updates the sprite trace, but does nothing else with the device. Pass a SpritePtr instead so we can update an alternate focus instead of hardcoding the device's sprite. Also make this function non-static, so we can use it elsewhere. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/events.c | 19 ++++++------------- include/input.h | 1 + 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/dix/events.c b/dix/events.c index df59a4e61..29033e2e5 100644 --- a/dix/events.c +++ b/dix/events.c @@ -332,12 +332,6 @@ IsMaster(DeviceIntPtr dev) return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD; } -static WindowPtr XYToWindow( - DeviceIntPtr pDev, - int x, - int y -); - /** * Max event opcode. */ @@ -1290,7 +1284,8 @@ ComputeFreezes(void) syncEvents.replayDev = (DeviceIntPtr)NULL; - w = XYToWindow(replayDev, event->root_x, event->root_y); + w = XYToWindow(replayDev->spriteInfo->sprite, + event->root_x, event->root_y); if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) { if (replayDev->focus && !IsPointerEvent((InternalEvent*)event)) @@ -2553,16 +2548,14 @@ PointInBorderSize(WindowPtr pWin, int x, int y) * * @returns the window at the given coordinates. */ -static WindowPtr -XYToWindow(DeviceIntPtr pDev, int x, int y) +WindowPtr +XYToWindow(SpritePtr pSprite, int x, int y) { WindowPtr pWin; BoxRec box; - SpritePtr pSprite; - pSprite = pDev->spriteInfo->sprite; pSprite->spriteTraceGood = 1; /* root window still there */ - pWin = GetCurrentRootWindow(pDev)->firstChild; + pWin = RootWindow(pSprite)->firstChild; while (pWin) { if ((pWin->mapped) && @@ -2775,7 +2768,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) ev->root_y = pSprite->hot.y; } - newSpriteWin = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y); + newSpriteWin = XYToWindow(pSprite, pSprite->hot.x, pSprite->hot.y); if (newSpriteWin != prevSpriteWin) { diff --git a/include/input.h b/include/input.h index a20f8a07a..c1db5444f 100644 --- a/include/input.h +++ b/include/input.h @@ -533,6 +533,7 @@ void FixUpEventFromWindow(SpritePtr pSprite, WindowPtr pWin, Window child, Bool calcChild); +extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y); extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win); /** From 30c8c7a86310139e79c9698caee21b3bd51936bd Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 12:13:29 +0000 Subject: [PATCH 09/11] Input: Handle grabs with no Xi 1.x equivalent Don't try to search for an Xi 1.x grab in CheckPassiveGrabsOnWindow for events with no Xi 1.x equivalent. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dix/events.c b/dix/events.c index 29033e2e5..45d9eabea 100644 --- a/dix/events.c +++ b/dix/events.c @@ -3415,9 +3415,9 @@ CheckPassiveGrabsOnWindow( tempGrab.detail.exact = event->detail.key; if (!match) { - tempGrab.type = GetXIType((InternalEvent*)event); tempGrab.grabtype = GRABTYPE_XI; - if (GrabMatchesSecond(&tempGrab, grab, FALSE)) + if ((tempGrab.type = GetXIType((InternalEvent*)event)) && + (GrabMatchesSecond(&tempGrab, grab, FALSE))) match = XI_MATCH; } From eb5aaf5eb819f1287ce40da79edbe07bafb2b5c0 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 28 Dec 2010 12:15:28 +0000 Subject: [PATCH 10/11] Input: Export GetEventMask Make it non-static, add to headers. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer Reviewed-by: Chase Douglas --- dix/events.c | 2 +- include/input.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index 45d9eabea..ff6e008ec 100644 --- a/dix/events.c +++ b/dix/events.c @@ -439,7 +439,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev))); } -static Mask +Mask GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) { /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ diff --git a/include/input.h b/include/input.h index c1db5444f..56992d134 100644 --- a/include/input.h +++ b/include/input.h @@ -526,6 +526,7 @@ extern _X_EXPORT InputAttributes *DuplicateInputAttributes(InputAttributes *attr extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs); /* misc event helpers */ +extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients); extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event); extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev); void FixUpEventFromWindow(SpritePtr pSprite, From ce74e7562dcc800306ff92b6d3c5ee885cd4763d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 7 Dec 2010 11:48:14 +0000 Subject: [PATCH 11/11] Input: Make CheckPassiveGrabsOnWindow return grab, export Change CheckPassiveGrabsOnWindow to return the GrabPtr it used (or NULL if none) rather than a boolean, and export it. Also add an additional boolean 'activate' parameter; use TRUE for existing behaviour, or FALSE to only find the grab and then return it. This will be used in forthcoming touch patches to find the grabs, rather than open-coding same. Signed-off-by: Daniel Stone Reviewed-by: Peter Hutterer --- dix/events.c | 30 +++++++++++++++--------------- include/dix.h | 7 +++++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/dix/events.c b/dix/events.c index ff6e008ec..4daed1403 100644 --- a/dix/events.c +++ b/dix/events.c @@ -209,10 +209,6 @@ static void CheckPhysLimits(DeviceIntPtr pDev, Bool generateEvents, Bool confineToScreen, ScreenPtr pScreen); -static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin, - DeviceIntPtr device, - DeviceEvent *event, - BOOL checkCore); /** Key repeat hack. Do not use but in TryClientEvents */ extern BOOL EventIsKeyRepeat(xEvent *event); @@ -2633,7 +2629,7 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); + rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); return rc; @@ -2670,10 +2666,9 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; event.detail.button = 0; - rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); + rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL); if (rc) DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); - return rc; } @@ -3344,20 +3339,23 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) /** * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a * passive grab set on the window to be activated. - * If a passive grab is activated, the event will be delivered to the client. + * If activate is true and a passive grab is found, it will be activated, + * and the event will be delivered to the client. * * @param pWin The window that may be subject to a passive grab. * @param device Device that caused the event. * @param event The current device event. * @param checkCore Check for core grabs too. + * @param activate If a grab is found, activate it and deliver the event. */ -static Bool +GrabPtr CheckPassiveGrabsOnWindow( WindowPtr pWin, DeviceIntPtr device, DeviceEvent *event, - BOOL checkCore) + BOOL checkCore, + BOOL activate) { SpritePtr pSprite = device->spriteInfo->sprite; GrabPtr grab = wPassiveGrabs(pWin); @@ -3369,7 +3367,7 @@ CheckPassiveGrabsOnWindow( int match = 0; if (!grab) - return FALSE; + return NULL; /* Fill out the grab details, but leave the type for later before * comparing */ tempGrab.window = pWin; @@ -3483,6 +3481,8 @@ CheckPassiveGrabsOnWindow( continue; } + if (!activate) + return grab; if (match & CORE_MATCH) { @@ -3540,10 +3540,10 @@ CheckPassiveGrabsOnWindow( if (match & (XI_MATCH | XI2_MATCH)) free(xE); /* on core match xE == &core */ - return TRUE; + return grab; } } - return FALSE; + return NULL; #undef CORE_MATCH #undef XI_MATCH #undef XI2_MATCH @@ -3609,7 +3609,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < focus->traceGood; i++) { pWin = focus->trace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) + if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) return TRUE; } @@ -3622,7 +3622,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor) for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) { pWin = device->spriteInfo->sprite->spriteTrace[i]; - if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) + if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE)) return TRUE; } diff --git a/include/dix.h b/include/dix.h index 7485e8ed4..12e4b5977 100644 --- a/include/dix.h +++ b/include/dix.h @@ -372,6 +372,13 @@ extern void AllowSome( extern void ReleaseActiveGrabs( ClientPtr client); +extern GrabPtr CheckPassiveGrabsOnWindow( + WindowPtr /* pWin */, + DeviceIntPtr /* device */, + DeviceEvent * /* event */, + BOOL /* checkCore */, + BOOL /* activate */); + extern _X_EXPORT int DeliverEventsToWindow( DeviceIntPtr /* pWin */, WindowPtr /* pWin */,