From 91ab237358c6e33da854914d3de493a9cbea7637 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Nov 2012 11:21:16 -0800 Subject: [PATCH 1/5] input: Pull TouchListener declaration to top-level No reason to have a struct declared inside another struct Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- include/inputstr.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/include/inputstr.h b/include/inputstr.h index 17cee9854..a9d46cc32 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -298,6 +298,15 @@ typedef struct _ValuatorClassRec { int v_scroll_axis; /* vert smooth-scrolling axis */ } ValuatorClassRec; +typedef struct _TouchListener { + XID listener; /* grabs/event selection IDs receiving + * events for this touch */ + enum TouchListenerType type; + enum TouchListenerState state; + enum InputLevel level; /* matters only for emulating touches */ + WindowPtr window; +} TouchListener; + typedef struct _TouchPointInfo { uint32_t client_id; /* touch ID as seen in client events */ int sourceid; /* Source device's ID for this touchpoint */ @@ -306,14 +315,7 @@ typedef struct _TouchPointInfo { * but still owned by a grab */ SpriteRec sprite; /* window trace for delivery */ ValuatorMask *valuators; /* last recorded axis values */ - struct _TouchListener { - XID listener; /* grabs/event selection IDs receiving - * events for this touch */ - enum TouchListenerType type; - enum TouchListenerState state; - enum InputLevel level; /* matters only for emulating touches */ - WindowPtr window; - } *listeners; + TouchListener *listeners; /* set of listeners */ int num_listeners; int num_grabs; /* number of open grabs on this touch * which have not accepted or rejected */ From 9ad0fdb135a1c336771aee1f6eab75a6ad874aff Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Nov 2012 11:21:17 -0800 Subject: [PATCH 2/5] input: Record grab pointer in TouchListener This places a pointer to the grab related to a TouchListener directly in the TouchListener structure rather than hoping to find the grab later on using the resource ID. Passive grabs have resource ID in the resource DB so they can be removed when a client exits, and those resource IDs get copied when activated, but implicit grabs are constructed on-the-fly and have no resource DB entry. Signed-off-by: Keith Packard Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xi/exevents.c | 25 +++++-------------------- dix/events.c | 1 + dix/touch.c | 22 +++++++++++++++------- include/input.h | 2 +- include/inputstr.h | 1 + 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 58fe49363..22bb5639a 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1187,7 +1187,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, TouchOwnershipEvent *ev) { Bool was_owner = (resource == ti->listeners[0].listener); - void *grab; int i; /* Send a TouchEnd event to the resource being removed, but only if they @@ -1202,11 +1201,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, /* Remove the resource from the listener list, updating * ti->num_listeners, as well as ti->num_grabs if it was a grab. */ - if (TouchRemoveListener(ti, resource)) { - if (dixLookupResourceByType(&grab, resource, RT_PASSIVEGRAB, - serverClient, DixGetAttrAccess) == Success) - ti->num_grabs--; - } + TouchRemoveListener(ti, resource); /* If the current owner was removed and there are further listeners, deliver * the TouchOwnership or TouchBegin event to the new owner. */ @@ -1300,21 +1295,10 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, if (listener->type == LISTENER_GRAB || listener->type == LISTENER_POINTER_GRAB) { - rc = dixLookupResourceByType((pointer *) grab, listener->listener, - RT_PASSIVEGRAB, - serverClient, DixSendAccess); - if (rc != Success) { - /* the grab doesn't exist but we have a grabbing listener - this - * is an implicit/active grab */ - rc = dixLookupClient(client, listener->listener, serverClient, - DixSendAccess); - if (rc != Success) - return FALSE; - *grab = dev->deviceGrab.grab; - if (!*grab) - return FALSE; - } + *grab = listener->grab; + + BUG_RETURN_VAL(!*grab, FALSE); *client = rClient(*grab); *win = (*grab)->window; @@ -1467,6 +1451,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, */ l = &ti->listeners[ti->num_listeners - 1]; l->listener = devgrab->resource; + l->grab = devgrab; if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin) l->type = LISTENER_POINTER_GRAB; diff --git a/dix/events.c b/dix/events.c index 73593626e..bea68cc51 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1438,6 +1438,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse) ti->listeners[0].type = LISTENER_POINTER_GRAB; else ti->listeners[0].type = LISTENER_GRAB; + ti->listeners[0].grab = grab; } } } diff --git a/dix/touch.c b/dix/touch.c index d890b6227..99f105b2e 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -677,13 +677,17 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource) void TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level, enum TouchListenerType type, enum TouchListenerState state, - WindowPtr window) + WindowPtr window, + GrabPtr grab) { ti->listeners[ti->num_listeners].listener = resource; ti->listeners[ti->num_listeners].level = level; ti->listeners[ti->num_listeners].state = state; ti->listeners[ti->num_listeners].type = type; ti->listeners[ti->num_listeners].window = window; + ti->listeners[ti->num_listeners].grab = grab; + if (grab) + ti->num_grabs++; ti->num_listeners++; } @@ -702,6 +706,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource) if (ti->listeners[i].listener == resource) { int j; + if (ti->listeners[i].grab) { + ti->listeners[i].grab = NULL; + ti->num_grabs--; + } + for (j = i; j < ti->num_listeners - 1; j++) ti->listeners[j] = ti->listeners[j + 1]; ti->num_listeners--; @@ -733,8 +742,7 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, } TouchAddListener(ti, grab->resource, grab->grabtype, - type, LISTENER_AWAITING_BEGIN, grab->window); - ti->num_grabs++; + type, LISTENER_AWAITING_BEGIN, grab->window, grab); } /** @@ -790,7 +798,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, TouchEventHistoryAllocate(ti); TouchAddListener(ti, iclients->resource, XI2, - type, LISTENER_AWAITING_BEGIN, win); + type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } @@ -806,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, TouchEventHistoryAllocate(ti); TouchAddListener(ti, iclients->resource, XI, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, - win); + win, NULL); return TRUE; } } @@ -821,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, TouchEventHistoryAllocate(ti); TouchAddListener(ti, win->drawable.id, CORE, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, - win); + win, NULL); return TRUE; } @@ -832,7 +840,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, TouchEventHistoryAllocate(ti); TouchAddListener(ti, oclients->resource, CORE, - type, LISTENER_AWAITING_BEGIN, win); + type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } } diff --git a/include/input.h b/include/input.h index 23a20b59d..79739e274 100644 --- a/include/input.h +++ b/include/input.h @@ -567,7 +567,7 @@ extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource); extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level, enum TouchListenerType type, - enum TouchListenerState state, WindowPtr window); + enum TouchListenerState state, WindowPtr window, GrabPtr grab); extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource); extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev); diff --git a/include/inputstr.h b/include/inputstr.h index a9d46cc32..32d7b621c 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -305,6 +305,7 @@ typedef struct _TouchListener { enum TouchListenerState state; enum InputLevel level; /* matters only for emulating touches */ WindowPtr window; + GrabPtr grab; } TouchListener; typedef struct _TouchPointInfo { From f59499b5d05fde83813709e9848152951592120d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 30 Oct 2012 12:44:08 +1000 Subject: [PATCH 3/5] dix: add resource type to touch listeners Instead of guessing what resource type the listener is and what property to retrieve, store the resource type in the listener directly. Breaks XIT test cases: TouchGrabTestMultipleTaps.PassiveGrabPointerEmulationMultipleTouchesFastSuccession Fixes https://bugs.freedesktop.org/show_bug.cgi?id=56557 Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard Reviewed-by: Chase Douglas --- Xi/exevents.c | 11 ++++------- dix/touch.c | 18 ++++++++++-------- include/input.h | 2 +- include/inputstr.h | 1 + 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 22bb5639a..74f3610cc 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1305,13 +1305,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, *mask = (*grab)->xi2mask; } else { - if (listener->level == CORE) - rc = dixLookupWindow(win, listener->listener, - serverClient, DixSendAccess); - else - rc = dixLookupResourceByType((pointer *) win, listener->listener, - RT_INPUTCLIENT, - serverClient, DixSendAccess); + rc = dixLookupResourceByType((pointer *) win, listener->listener, + listener->resource_type, + serverClient, DixSendAccess); if (rc != Success) return FALSE; @@ -1452,6 +1448,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, l = &ti->listeners[ti->num_listeners - 1]; l->listener = devgrab->resource; l->grab = devgrab; + //l->resource_type = RT_NONE; if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin) l->type = LISTENER_POINTER_GRAB; diff --git a/dix/touch.c b/dix/touch.c index 99f105b2e..0db842c65 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -675,12 +675,13 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource) * Add the resource to this touch's listeners. */ void -TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level, - enum TouchListenerType type, enum TouchListenerState state, - WindowPtr window, +TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type, + enum InputLevel level, enum TouchListenerType type, + enum TouchListenerState state, WindowPtr window, GrabPtr grab) { ti->listeners[ti->num_listeners].listener = resource; + ti->listeners[ti->num_listeners].resource_type = resource_type; ti->listeners[ti->num_listeners].level = level; ti->listeners[ti->num_listeners].state = state; ti->listeners[ti->num_listeners].type = type; @@ -741,7 +742,8 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti, type = LISTENER_POINTER_GRAB; } - TouchAddListener(ti, grab->resource, grab->grabtype, + /* grab listeners are always RT_NONE since we keep the grab pointer */ + TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype, type, LISTENER_AWAITING_BEGIN, grab->window, grab); } @@ -797,7 +799,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership)) TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, XI2, + TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2, type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } @@ -812,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, XI, + TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; @@ -827,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, /* window owner */ if (IsMaster(dev) && (win->eventMask & core_filter)) { TouchEventHistoryAllocate(ti); - TouchAddListener(ti, win->drawable.id, CORE, + TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE, LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; @@ -839,7 +841,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, oclients->resource, CORE, + TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE, type, LISTENER_AWAITING_BEGIN, win, NULL); return TRUE; } diff --git a/include/input.h b/include/input.h index 79739e274..f53ed9905 100644 --- a/include/input.h +++ b/include/input.h @@ -565,7 +565,7 @@ extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev); extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource); extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource); -extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, +extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type, enum InputLevel level, enum TouchListenerType type, enum TouchListenerState state, WindowPtr window, GrabPtr grab); extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource); diff --git a/include/inputstr.h b/include/inputstr.h index 32d7b621c..fc21913e1 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -301,6 +301,7 @@ typedef struct _ValuatorClassRec { typedef struct _TouchListener { XID listener; /* grabs/event selection IDs receiving * events for this touch */ + int resource_type; /* listener's resource type */ enum TouchListenerType type; enum TouchListenerState state; enum InputLevel level; /* matters only for emulating touches */ From 32a6d8a6b59c42f8d65002d7ca1cafb1957b656f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 20 Dec 2012 16:25:43 +1000 Subject: [PATCH 4/5] dix: check for the right device's xi2 mask events.c: In function 'DeactivatePointerGrab': events.c:1524:51: warning: 'dev' may be used uninitialized in this function [-Wuninitialized dev is unset when we get here, the device to check is "mouse". Introduced in ece8157a59751b3ed492fb2e1eb8d5f20221e195. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- dix/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index bea68cc51..b742f6787 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1522,7 +1522,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse) emulate a ButtonRelease here. So pretend the listener already has the end event */ if (grab->grabtype == CORE || grab->grabtype == XI || - !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)) + !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) ti->listeners[0].state = LISTENER_HAS_END; TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); } From 0e1ab433f4048b3367bb2f01d16cd00502538e4d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 4 Jan 2013 12:26:58 +1000 Subject: [PATCH 5/5] dix: remove already-moved hunk Should've been removed in bc1f90a615018c05994fae3e678dd2341256cd82a, but got left here due to a botched rebase. Fixes stray button events sent to clients after deactivating an async pointer grab on a pointer-emulating-touch. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- dix/events.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dix/events.c b/dix/events.c index b742f6787..a46aaf660 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1551,15 +1551,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse) ReattachToOldMaster(mouse); ComputeFreezes(); - - /* If an explicit grab was deactivated, we must remove it from the head of - * all the touches' listener lists. */ - for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) { - TouchPointInfoPtr ti = mouse->touch->touches + i; - - if (ti->active && TouchResourceIsOwner(ti, grab_resource)) - TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); - } } /**