This cannot ever be unset on any real device, but coverity is unhappy and
that's not making me happy.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Clang doesn't support variable length arrays inside a struct so we could
either make our life complicated or just assume no-one is using more than 256
slots and hard-code that. Let's go for the easy solution until someone
notices.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Where at least one touch ends during SYN_DROPPED, we send out two event
frames: one with all applicable touch sequences ending (tracking id -1) and
the second one with the whole device state *and* the applicable touch
sequences starting (tracking id != -1).
This requires us to also update the BTN_TOOL_ bits correctly so that they are
correct after the first frame. For that we count the number of previously
known touches and send a 0 event for the matching BTN_TOOL_ bit, together with
a 1 event for the currently known touches.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The previous event processing had subtle issues with touches stopping during
SYN_DROPPED. All of the device state was processed in the same frame, but if
any touch changed tracking ID during SYN_DROPPED, an inserted SYN_REPORT
resulted in a weird split of events:
- the first frame had all key/sw/abs updates including those slots that
changed tracking ID, but not the ones that were fully terminated.
- the second frame had only the slots states for newly started touches **and**
the slot state for touches terminated during SYN_DROPPED but not restarted.
In other words, where three fingers were on the touchpad and slot 0 was lifted
and put down again and slot 1 was lifted but *not* put down again, our frames
contained:
- frame 1: terminate slot 0, BTN_TOOL_TRIPLETAP 0, BTN_TOOL_DOUBLETAP 1
- frame 2: start slot 0, terminate slot 1
Where there was no touch changing tracking ID, only one frame was generated.
The BTN_TOOL updates were buggy, they may not match the number of fingers down
as seen on a frame-by-frame basis. This triggered libinput bug
https://gitlab.freedesktop.org/libinput/libinput/issues/422
This patch changes the above example to
- frame 1: terminate slot 0, terminate slot 1
- frame 2: start slot 0, BTN_TOOL_TRIPLETAP 0, BTN_TOOL_DOUBLETAP 1
Notably, the first frame no longer contains the BTN_TOOL bits. This patch is
one of two, the BTN_TOOL sync bits are part of a follow-up patch.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Go from:
if (a != b)
continue;
foo;
to:
if (a == b) {
foo;
}
Basically just an indentation change after the condition inversion, makes the
follow-up patch easier to review.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
In the near future, we will need to handle slot termination *before* any other
state synchronization. So let's start splitting things up.
This is functionally equivalent though dropping the need_tracking_id_changes
variable means we run through all slots now to check if we need to terminate
one of them. Given the normal number of slots on a device and that this should
only ever run very rarely anyway... meh.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Keep a better state of each touch before/after the SYN_DROPPED. Most of this
is currently unused, it's functionally the same as before but the new code
serves to increase readability and it can be passed around easier this way.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Replace it with a stack-allocated one. This saves us a bunch of confusing
allocations and size calculations.
And in the process use uint32_t/int32_t to ensure the struct is actually the
expected size.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
v3.4 was released in 2012, every kernel since has that ioctl. So instead of
assuming you're running new libevdev on an 8 year old kernel, let's assume
that any error from the ioctl() is an actual error and handle it accordingly.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is a GNU C extension, and is not available in ISO C.
Instead, just explicitly initialize other indices to -1.
Signed-off-by: Michael Forney <mforney@mforney.org>
Statement expressions are a GNU C extension and are not available
in ISO C.
On compilers that don't have them, define these macros as plain
conditional expressions, since they are only ever used with expressions
that have no side-effects.
The statement-expression version is still retained as an added
safety measure on GNU-compatible compilers.
Signed-off-by: Michael Forney <mforney@mforney.org>
That code did not compile because those functions were only renamed in
header and code back then, but not in the example.
Fixes: ab2f20bfd6 ("Revamp the API once again")
Signed-off-by: Alexander Dahl <ada@thorsis.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The id_* fields are 16 bits in linux/input.h and we mirror
the kernel API here. Even though we accept an int for this
fields in ABI the value is truncated at 16 bits.
Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Previously, enabling or disabling ABS_MT_SLOT would not change the actual
slots, it was treated as a normal bitflag. This means we couldn't initialize a
libevdev context from scratch and have it behave like a correct MT context.
Fixes#4
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This causes some weird rendering, let's split it into a list (which also
happens to be more readable).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Two new function pairs:
libevdev_event_code_from_code_name()
libevdev_event_type_from_code_name()
libevdev_event_code_from_code_name_n()
libevdev_event_type_from_code_name_n()
These functions look up event codes/types by the name of the event code only,
removing the need to figure out what event type an event code has. So if all
you have is "BTN_TOUCH", you can now look up the type and code for that,
without having to check the prefix yourself to guess at the type.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
With the previous approach, every libevdev_next_event() invocation triggered a
read() on the device fd. This is not efficient, the kernel provides whole
event frames at a time so we're guaranteed to have more events waiting unless
the current event is a SYN_REPORT.
Assuming a fast-enough client and e.g. a touchpad device with multiple axes
per frame, we'd thus trigger several unnecessary read() calls per event frame.
Drop this behavior, instead only trigger the read when our internal queue is
empty and we need more events.
Fallout:
- we don't have any warning about a too-slow sync, i.e. if a SYN_DROPPED
arrives while we're syncing, we don't get a warning in the log anymore.
the test for this was removed.
- the tests that required the specific behavior were rewritten accordingly
- a revoke on a kernel device doesn't return ENODEV until already-received
events have been processed
The above shouldn't be an issue for existing real-world clients.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
ABS_RESERVED was added to 4.20 for that reason, to keep that event code
reserved so we can't use it for anything else (and thus mess up the fake MT
detection).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
ABS_MT_TOOL_TYPE values are an enum, not a numerical value like all other
axes. So let's allow converting those values to string.
Fixes https://gitlab.freedesktop.org/libevdev/libevdev/issues/1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Some of the *_MAX names are duplicates and have a real define. These were not
resolved until now.
Fixes https://gitlab.freedesktop.org/libevdev/libevdev/issues/3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Two variable renames for less ambiguity
Two changes from an long if condition to a "if foo in [...]"
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
The struct input_event is not y2038 safe.
Update the struct according to the kernel patch:
https://lkml.org/lkml/2018/1/6/324
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
They have the same value, so the _MAX code would shadow the real code, causing
issues in any client that needs to get all event names from libevdev.
Specifically, the loop of:
for each code in 0 to max-for-type:
print(name)
would not show up the code (but the _MAX) code instead. This causes issues
with clients that rely on name resolution that works. And the _MAX values are
special values anyway.
Blacklist it in the script here, causing it to resolve from name to code, but
not from code to name (like other duplicated codes).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
They have the same value, so the _MAX code would shadow the real code, causing
issues in any client that needs to get all event names from libevdev.
Specifically, the loop of:
for each code in 0 to max-for-type:
print(name)
would not show up the code (but the _MAX) code instead. This causes issues
with clients that rely on name resolution that works. And the _MAX values are
special values anyway.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
leftover from when this was part of evemu
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Previously, calling grabbing a device after changing the fd was a no-op
because libevdev's grab state didn't match the fd:
libevdev_grab(LIBEVDEV_GRAB);
.. fd is grabbed
.. internal state is 'grabbed'
libevdev_change_fd();
.. new fd is ungrabbed
.. internal state is 'grabbed'
libevdev_grab(LIBEVDEV_GRAB);
.. argument matches internal state and we exit without grabbing the device
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>