diff options
Diffstat (limited to 'libevdev/libevdev.c')
| -rw-r--r-- | libevdev/libevdev.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 7ba4629..958580f 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -551,9 +551,12 @@ out: static int sync_mt_state(struct libevdev *dev, int create_events) { + struct input_event *ev; + struct input_absinfo abs_info; int rc; int axis, slot; int ioctl_success = 0; + int last_reported_slot = 0; struct mt_state { int code; int val[MAX_SLOTS]; @@ -599,14 +602,18 @@ sync_mt_state(struct libevdev *dev, int create_events) } } - for (slot = 0; create_events && slot < min(dev->num_slots, MAX_SLOTS); slot++) { - struct input_event *ev; + if (!create_events) { + rc = 0; + goto out; + } + for (slot = 0; slot < min(dev->num_slots, MAX_SLOTS); slot++) { if (!bit_is_set(slot_update, AXISBIT(slot, ABS_MT_SLOT))) continue; ev = queue_push(dev); init_event(dev, ev, EV_ABS, ABS_MT_SLOT, slot); + last_reported_slot = slot; for (axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) { if (axis == ABS_MT_SLOT || @@ -620,6 +627,20 @@ sync_mt_state(struct libevdev *dev, int create_events) } } + /* add one last slot event to make sure the client is on the same + slot as the kernel */ + + rc = ioctl(dev->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); + if (rc < 0) + goto out; + + dev->current_slot = abs_info.value; + + if (dev->current_slot != last_reported_slot) { + ev = queue_push(dev); + init_event(dev, ev, EV_ABS, ABS_MT_SLOT, dev->current_slot); + } + #undef AXISBIT rc = 0; |
