Drain all events before synchronizing after SYN_DROPPED
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 7 Apr 2014 05:16:28 +0000 (15:16 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 23 Apr 2014 22:17:01 +0000 (08:17 +1000)
commit050bca91a1e8dd2e46c219c0b282092cb053166c
tree64aa1d91e1ec7768fcaf034f4087868ee2393ca7
parent8b01184404dafb0dc121a1cdef066ea78ba6d21c
Drain all events before synchronizing after SYN_DROPPED

The kernel ring buffer drops all events on SYN_DROPPED, but then continues to
fill up again. So by the time we read the events, the kernel's client buffer is
essentially like this:
  SYN_DROPPED, ev1, ev2, ev3, ...., evN

The kernel's device state represents the device after evN, and that is what
the ioctls return. For EV_KEY, EV_SND, EV_LED and EV_SW the kernel removes
potential duplicates from the client buffer [1], it doesn't do so for EV_ABS.

So we can't actually sync while there are events on the wire because the
events represent an earlier state. So simply discard all events in the kernel
buffer, synchronize, and then start processing again. We lose some granularity
but at least the events are correct.

[1] http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/input/evdev.c?id=483180281f0ac60d1138710eb21f4b9961901294

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
libevdev/libevdev.c
libevdev/libevdev.h
test/test-libevdev-events.c