From b64f94f9c4d06c9d5220b9cff14be2fa0fb504d4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 13 Feb 2020 16:50:17 +1000 Subject: [PATCH] Expand the touch state handling during SYN_DROPPED 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 --- libevdev/libevdev.c | 55 ++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 430add0..124e987 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -44,6 +44,21 @@ enum event_filter_status { EVENT_FILTER_DISCARD, /**< Discard current event */ }; +/* Keeps a record of touches during SYN_DROPPED */ +enum touch_state { + TOUCH_OFF, + TOUCH_STARTED, /* Started during SYN_DROPPED */ + TOUCH_STOPPED, /* Stopped during SYN_DROPPED */ + TOUCH_ONGOING, /* Existed before, still have same tracking ID */ + TOUCH_CHANGED, /* Existed before but have new tracking ID now, so + stopped + started in that slot */ +}; + +struct slot_change_state { + enum touch_state state; + unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */ +}; + static int sync_mt_state(struct libevdev *dev, int create_events); static inline int* @@ -659,13 +674,10 @@ sync_mt_state(struct libevdev *dev, int create_events) struct input_absinfo abs_info; int rc; int last_reported_slot = 0; - unsigned long slot_update[dev->num_slots][NLONGS(ABS_CNT)]; - unsigned long tracking_id_changes[NLONGS(dev->num_slots)]; - + struct slot_change_state changes[dev->num_slots]; int need_tracking_id_changes = 0; - memset(slot_update, 0, sizeof(slot_update)); - memset(tracking_id_changes, 0, sizeof(tracking_id_changes)); + memset(changes, 0, sizeof(changes)); for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) { /* EVIOCGMTSLOTS required format */ @@ -687,20 +699,31 @@ sync_mt_state(struct libevdev *dev, int create_events) int val_before = *slot_value(dev, slot, axis), val_after = mt_state.val[slot]; + if (axis == ABS_MT_TRACKING_ID) { + if (val_before == -1 && val_after != -1) { + changes[slot].state = TOUCH_STARTED; + } else if (val_before != -1 && val_after == -1) { + changes[slot].state = TOUCH_STOPPED; + } else if (val_before != -1 && val_after != -1 && + val_before == val_after) { + changes[slot].state = TOUCH_ONGOING; + } 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; + } + } + if (val_before == val_after) continue; - if (axis == ABS_MT_TRACKING_ID && - val_before != -1 && val_after != -1) { - set_bit(tracking_id_changes, slot); - need_tracking_id_changes = 1; - } - *slot_value(dev, slot, axis) = val_after; - set_bit(slot_update[slot], axis); + set_bit(changes[slot].axes, axis); /* note that this slot has updates */ - set_bit(slot_update[slot], ABS_MT_SLOT); + set_bit(changes[slot].axes, ABS_MT_SLOT); } } @@ -711,7 +734,7 @@ sync_mt_state(struct libevdev *dev, int create_events) if (need_tracking_id_changes) { for (int slot = 0; slot < dev->num_slots; slot++) { - if (!bit_is_set(tracking_id_changes, slot)) + if (changes[slot].state != TOUCH_CHANGED) continue; queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); @@ -724,7 +747,7 @@ sync_mt_state(struct libevdev *dev, int create_events) } for (int slot = 0; slot < dev->num_slots; slot++) { - if (!bit_is_set(slot_update[slot], ABS_MT_SLOT)) + if (!bit_is_set(changes[slot].axes, ABS_MT_SLOT)) continue; queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); @@ -735,7 +758,7 @@ sync_mt_state(struct libevdev *dev, int create_events) !libevdev_has_event_code(dev, EV_ABS, axis)) continue; - if (bit_is_set(slot_update[slot], axis)) + if (bit_is_set(changes[slot].axes, axis)) queue_push_event(dev, EV_ABS, axis, *slot_value(dev, slot, axis)); } -- 2.34.1