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 <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-02-13 16:50:17 +10:00
parent b2ec3cb7d4
commit b64f94f9c4

View file

@ -44,6 +44,21 @@ enum event_filter_status {
EVENT_FILTER_DISCARD, /**< Discard current event */ 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 int sync_mt_state(struct libevdev *dev, int create_events);
static inline int* static inline int*
@ -659,13 +674,10 @@ sync_mt_state(struct libevdev *dev, int create_events)
struct input_absinfo abs_info; struct input_absinfo abs_info;
int rc; int rc;
int last_reported_slot = 0; int last_reported_slot = 0;
unsigned long slot_update[dev->num_slots][NLONGS(ABS_CNT)]; struct slot_change_state changes[dev->num_slots];
unsigned long tracking_id_changes[NLONGS(dev->num_slots)];
int need_tracking_id_changes = 0; int need_tracking_id_changes = 0;
memset(slot_update, 0, sizeof(slot_update)); memset(changes, 0, sizeof(changes));
memset(tracking_id_changes, 0, sizeof(tracking_id_changes));
for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) { for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) {
/* EVIOCGMTSLOTS required format */ /* EVIOCGMTSLOTS required format */
@ -687,20 +699,31 @@ sync_mt_state(struct libevdev *dev, int create_events)
int val_before = *slot_value(dev, slot, axis), int val_before = *slot_value(dev, slot, axis),
val_after = mt_state.val[slot]; 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) if (val_before == val_after)
continue; 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; *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 */ /* 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) { if (need_tracking_id_changes) {
for (int slot = 0; slot < dev->num_slots; slot++) { for (int slot = 0; slot < dev->num_slots; slot++) {
if (!bit_is_set(tracking_id_changes, slot)) if (changes[slot].state != TOUCH_CHANGED)
continue; continue;
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); 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++) { 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; continue;
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot); 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)) !libevdev_has_event_code(dev, EV_ABS, axis))
continue; continue;
if (bit_is_set(slot_update[slot], axis)) if (bit_is_set(changes[slot].axes, axis))
queue_push_event(dev, EV_ABS, axis, queue_push_event(dev, EV_ABS, axis,
*slot_value(dev, slot, axis)); *slot_value(dev, slot, axis));
} }