EmitTouchEnd calls DeliverTouchEvents directly instead of through
public.processInputProc. If a device is frozen, the TouchEnd is
processed while the device is waiting for a XAllowEvents and thus ends the
touch point (and the grab) before the client decided what to do with it. In
the case of ReplayPointer, this loses the event.
This is a hack, but making EmitTouchEnd use processInputProc breaks
approximately everything, especially the touch point is cleaned up during
ProcessTouchEvents. Working around that is a bigger hack than this.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If a device is frozen in results to a grab, we need to enqueue the events.
This makes things complicated, and hard to follow since touch events are now
replayed in the history, pushed into EnqueueEvent, then replayed later
during PlayReleasedEvents in response to an XAllowEvents.
While the device is frozen, no touch events are processed, so if there is a
touch client with ownership mask _below_ the grab this will delay the
delivery and potentially screw gesture recognition. However, this is the
behaviour we have already anyway if the top-most client is a sync pgrab or
there is a sync grab active on the device when the TouchBegin was generated.
(also note, such a client would only reliably work in case of ReplayPointer
anyway)
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If a touch is pending_finish and we just punted it to the next owner, that
client must receive a TouchEnd event.
If we just punted to the last owner and that owner not a touch grab, we need
to end the touch since this is the last event to be sent, and the client
cannot accept/reject this.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Delivering an event changes the state to LISTENER_IS_OWNER and we thus lose
the information of early acceptance.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
ActivateEarlyAccept() can only be called from a grabbing client, so we can
ignore the rest. And it's easy enough to get the client from that since
9ad0fdb135.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If a TouchBegin is sent to a core client, that client is now the owner.
By the time the TouchEnd is being processed, the client cannot replay
anymore, so we can assume that this is the final touch end and we can clean
up the touch record.
Note: DeliverTouchEmulatedEvent is called for all listeners and immediately
bails out if the client is not the owner and thus shouldn't yet get the
event. Thus, check the return code.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
ef64b5ee97 (which introduced the
TOUCH_CLIENT_ID check) has a wrong assumption that generated touch events
(TOUCH_CLIENT_ID) should not terminate passive grabs.
This is untrue, a TouchEnd may be generated in response to a TouchReject
higher up. If we _deliver_ an event to a client, terminate the passive grab.
This requires us to count the actually delivered events too (first hunk).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If we only have a single touch-grabbing client, setting the client as owner
would clean up the touch once the TouchEnd was processed. If the client then
calls XIAllowTouches() it will receive a BadValue for the touch ID (since
the internal record is already cleaned up).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If drivers supply incorrect values don't just quietly return False, spew to
the log so we can detect what's going on. All these cases are driver bugs
and should be fixed immediately.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Comment dates back to a pre-release version of XI2 that supported keysym
grabs. That never made it into a release, it was ditched before.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
The event struct is different, causing memory corruption on 1.13 and 1.14,
as can be witnessed in https://bugs.freedesktop.org/show_bug.cgi?id=56578
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The commit message to 6764471901 explains it,
but that doesn't stop the WTF moment when reading the code.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
We do the same thing here, compress them into one body.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Instead of accessing ti->listener[0] all the time.
No functional changes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
All callers currently ignore the new value, so this patch has no effect.
Inverse call graph:
DeliverTouchEmulatedEvent
DeliverEmulatedMotionEvent Ignores value
DeliverTouchBeginEvent
DeliverTouchEvent
DeliverTouchEvents Ignores value
DeliverTouchEndEvent
DeliverTouchEvent
DeliverTouchEvents Ignores value
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
mask[(MAX_VALUATORS + 7)/8] is larger than data[MAX_VALUATORS], so static
code checkers think we may be running OOB on the data array. Mask is
initialized to 0, so this should not happen, but change it anyway to shut up
code analyzer noise.
X.Org Bug 59939 <http://bugs.freedesktop.org/show_bug.cgi?id=59939>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
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 <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Chase Douglas <chase.douglas@ubuntu.com>
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 <keithp@keithp.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Conflicts:
Xi/xichangehierarchy.c
Small conflict with the patch from
Xi: don't use devices after removing them
Was easily resolved by hand.
Signed-off-by: Keith Packard <keithp@keithp.com>
If the grab_window is the barrier window and the client owns the grab,
deliver as normal grabbed event (respecting owner_events). Otherwise,
deliver as usual.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
This adds support for clients that would like to get a notification
every time a barrier is hit, and allows clients to temporarily release
a barrier so that pointers can go through them, without having to
destroy and recreate barriers.
Based on work by Chris Halse Rogers <chris.halse.rogers@canonical.com>
Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Once the TouchEnd appears on the device, the touch is done. If the client
still has a pointer grab, accept it to avoid clients with TouchOwnership
selections to wait indefinitely for the actual touch event.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
As before GetTouchEvents causes unwanted side effects. Add a new
function GetDixTouchEnd, which generates a touch event from the touch
point. We fill in the event's screen coordinates from the MD's current
sprite position.
Signed-off-by: Thomas Jaeger <ThJaeger@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Button mask should be out-of-band with the emulated
pointer events as touch devices don't truly have
"buttons". Even though, it's handy to have the modifier
mask from the paired keyboard on touch events.
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Ensure emulated pointer events contain the state that applies before the
event was processed, so the device state must be updated after delivering
such emulated events.
Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
exevents.c: In function 'ProcessTouchEvent':
exevents.c:1601:20: warning: too many arguments for format
Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
If a client is still waiting for the TouchBegin, don't deliver a TouchEnd
event.
X.Org Bug 55738 <http://bugs.freedesktop.org/show_bug.cgi?id=55738>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Thomas Jaeger <thjaeger@gmail.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
This flag is never set, so checking for it here means that we'll
never release the simulated mouse button press after the user touches
(and releases) the touchscreen for the first time.
Fixes a problem where the XO laptop touchpad became totally
unusable after touching the screen for the first time (since X then
behaved as if the mouse button was held down all the time).
Signed-off-by: Daniel Drake <dsd@laptop.org>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
When the owner of a touch accepts it, the other listeners must
receive a TouchEnd.
Even though there's code implementing the logic above in
ProcessTouchOwnershipEvent(), DeliverTouchEndEvent() was refusing to send
those TouchEnd events in this situatuation.
Signed-off-by: Daniel d'Andrada <daniel.dandrada@canonical.com>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Tested-by: Daniel Stone <daniel@fooishbar.org>
exevents.c: In function 'DeepCopyFeedbackClasses':
exevents.c:272:20: warning: declaration of 'classes' shadows a previous
local [-Wshadow]
exevents.c:245:16: warning: shadowed declaration is here [-Wshadow]
(and a few more like this)
exevents.c: In function 'DeliverTouchEmulatedEvent':
exevents.c:1442:27: warning: declaration of 'win' shadows a parameter
[-Wshadow]
exevents.c:1404:55: warning: shadowed declaration is here [-Wshadow]
exevents.c:1475:28: warning: declaration of 'listener' shadows a parameter
[-Wshadow]
exevents.c:1403:62: warning: shadowed declaration is here [-Wshadow]
xiselectev.c: In function 'ProcXISelectEvents':
xiselectev.c:178:34: warning: declaration of 'dummy' shadows a previous
local [-Wshadow]
xiselectev.c:91:18: warning: shadowed declaration is here [-Wshadow]
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
This is only called from the enterleave implementation, so move it and its
helper functions to there. No functional changes.
Fixes build error introduced in 31174565ec if
building with '-Werror=implicit-function-declaration'
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
If a touch is physically active, the pointer core state should reflect
that the first button is pressed. Currently, this only occurs when there
are active listeners of the touch sequence. By moving the device state
updating to the beginning of touch processing we ensure it is updated
according to the processed physical state no matter what.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Currently, the touch is only logically ended if the touch has physically
ended. If the touch hasn't physically ended, the touch record is never
ended. If there aren't any more listeners, we don't need to keep the dix
touch record around any more.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
As a special case, if a still physically active pointer emulated touch
has no listeners and the device is explicitly grabbed for pointer
events, create a new dix touch record for the grab only.
This allows for clients to "hand off" grabs. For example, when dragging
a window under compiz the window decorator sees the button press and
then ungrabs the implicit grab. It then tells compiz to grab the device,
and compiz then moves the window with the pointer motion. This is racy,
but is allowed by the input protocol for pointer events when there are
no other clients with a grab on the device.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
The function will be used for building a sprite for pointer emulation
after an explicit device grab. This commit refactors the code so that
TouchBuildSprite will function with any event type and moves the checks
to the caller.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Fake touch end events are generated by touch acceptance and rejection.
These should not cause implicit pointer grabs to be deactivated.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Fake end events are generated by touch acceptance or rejection. These
should not end the touch point.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
We still need to generate the touch ownership event to process the
ending of the touch event in the case where the owner has the end
already.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This is a bit of unimplemented code for touchscreen pointer emulation. A
pointer grabbing client currently never accepts the touch sequence. The
sequence must be accepted once any touch-derived event is irrevocably
delivered to a client.
The first pointer event, derived from a touch begin event, may be caught
in a sync grab and then replayed. This is essentially a revocable
delivery of an event. Thus, we must wait till a non-begin event is
delivered.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
The current code returns a reference to memory that may not actually be
an XI2 mask. Instead, only return a value when an XI2 client has
selected for events.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
The current code checks the core event mask as though it were an XI2
mask. This change fixes the checks so the proper client and event masks
are used.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Issue:
* Two sequential touches (i.e. down, up, down, up)
* Both are grabbed by a touch grab
* Both have a second listener in the form of a pointer grab or selection
* The second and first touches are rejected in that order
The first touch must be pointer emulated before the second touch, so the
second touch must be paused until the first touch is rejected or
accepted and all events are delivered to pointer clients.
This change ensures all pointer emulated events are emitted
sequentially. It necessarily imposes a delay on further touch events
when pointer grabs and selections are used, but there is no way around
it.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Just like when we deliver to a touch listener, we must convert a touch
end event to an update event for further clients. This also ensures that
the touch record is not deleted at the end of ProcessTouchEvent().
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
After the pointer grab is deactivated, the touch listener record is
updated at the end of DeliverTouchEmulatedEvent. However, the touch
record is ended when the grab is deactivated, so the update to the
listener record is in an array of memory that has been freed.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>