From: Peter Hutterer Date: Thu, 13 Feb 2020 08:14:50 +0000 (+1000) Subject: Split the MT state syncing and event generation into two functions X-Git-Tag: libevdev-1.8.901~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e38e3ae7c8e1a1a1d15fa09b4b84efe1486cc8d7;p=platform%2Fupstream%2Flibevdev.git Split the MT state syncing and event generation into two functions 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 --- diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 124e987..aa2e964 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -59,7 +59,8 @@ struct slot_change_state { unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */ }; -static int sync_mt_state(struct libevdev *dev, int create_events); +static int sync_mt_state(struct libevdev *dev, + struct slot_change_state *changes_out); static inline int* slot_value(const struct libevdev *dev, int slot, int axis) @@ -533,8 +534,10 @@ libevdev_set_fd(struct libevdev* dev, int fd) if (rc != 0) goto out; - if (dev->num_slots != -1) - sync_mt_state(dev, 0); + if (dev->num_slots != -1) { + struct slot_change_state unused[dev->num_slots]; + sync_mt_state(dev, unused); + } rc = init_event_queue(dev); if (rc < 0) { @@ -669,13 +672,11 @@ out: } static int -sync_mt_state(struct libevdev *dev, int create_events) +sync_mt_state(struct libevdev *dev, + struct slot_change_state changes_out[dev->num_slots]) { - struct input_absinfo abs_info; int rc; - int last_reported_slot = 0; struct slot_change_state changes[dev->num_slots]; - int need_tracking_id_changes = 0; memset(changes, 0, sizeof(changes)); @@ -710,7 +711,6 @@ sync_mt_state(struct libevdev *dev, int create_events) } else if (val_before != -1 && val_after != -1 && val_before != val_after) { changes[slot].state = TOUCH_CHANGED; - need_tracking_id_changes = 1; } else { changes[slot].state = TOUCH_OFF; } @@ -727,25 +727,37 @@ sync_mt_state(struct libevdev *dev, int create_events) } } - if (!create_events) { - rc = 0; - goto out; - } + memcpy(changes_out, changes, sizeof(changes)); +out: + return rc; +} - if (need_tracking_id_changes) { - for (int slot = 0; slot < dev->num_slots; slot++) { - if (changes[slot].state != TOUCH_CHANGED) - continue; +static int +push_mt_sync_events(struct libevdev *dev, + const struct slot_change_state changes[dev->num_slots]) +{ + struct input_absinfo abs_info; + int last_reported_slot = 0; + int rc; + bool touches_stopped = false; - queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); - queue_push_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); + for (int slot = 0; slot < dev->num_slots; slot++) { + if (changes[slot].state != TOUCH_CHANGED) + continue; - last_reported_slot = slot; - } + queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); + queue_push_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); - queue_push_event(dev, EV_SYN, SYN_REPORT, 0); + last_reported_slot = slot; + touches_stopped = true; } + /* If any of the touches stopped, we need to split the sync state + into two frames - one with all the stopped touches, one with the + new touches starting (if any) */ + if (touches_stopped) + queue_push_event(dev, EV_SYN, SYN_REPORT, 0); + for (int slot = 0; slot < dev->num_slots; slot++) { if (!bit_is_set(changes[slot].axes, ABS_MT_SLOT)) continue; @@ -859,8 +871,13 @@ sync_state(struct libevdev *dev) if (rc == 0 && libevdev_has_event_type(dev, EV_ABS)) rc = sync_abs_state(dev); if (rc == 0 && dev->num_slots > -1 && - libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) - rc = sync_mt_state(dev, 1); + libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) { + struct slot_change_state changes[dev->num_slots]; + + rc = sync_mt_state(dev, changes); + if (rc == 0) + push_mt_sync_events(dev, changes); + } dev->queue_nsync = queue_num_elements(dev);