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

View file

@ -59,7 +59,8 @@ struct slot_change_state {
unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */ 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* static inline int*
slot_value(const struct libevdev *dev, int slot, int axis) 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) if (rc != 0)
goto out; goto out;
if (dev->num_slots != -1) if (dev->num_slots != -1) {
sync_mt_state(dev, 0); struct slot_change_state unused[dev->num_slots];
sync_mt_state(dev, unused);
}
rc = init_event_queue(dev); rc = init_event_queue(dev);
if (rc < 0) { if (rc < 0) {
@ -669,13 +672,11 @@ out:
} }
static int 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 rc;
int last_reported_slot = 0;
struct slot_change_state changes[dev->num_slots]; struct slot_change_state changes[dev->num_slots];
int need_tracking_id_changes = 0;
memset(changes, 0, sizeof(changes)); 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 && } else if (val_before != -1 && val_after != -1 &&
val_before != val_after) { val_before != val_after) {
changes[slot].state = TOUCH_CHANGED; changes[slot].state = TOUCH_CHANGED;
need_tracking_id_changes = 1;
} else { } else {
changes[slot].state = TOUCH_OFF; changes[slot].state = TOUCH_OFF;
} }
@ -727,24 +727,36 @@ sync_mt_state(struct libevdev *dev, int create_events)
} }
} }
if (!create_events) { memcpy(changes_out, changes, sizeof(changes));
rc = 0; out:
goto out; return rc;
}
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;
for (int slot = 0; slot < dev->num_slots; slot++) {
if (changes[slot].state != TOUCH_CHANGED)
continue;
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot);
queue_push_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
last_reported_slot = slot;
touches_stopped = true;
} }
if (need_tracking_id_changes) { /* If any of the touches stopped, we need to split the sync state
for (int slot = 0; slot < dev->num_slots; slot++) { into two frames - one with all the stopped touches, one with the
if (changes[slot].state != TOUCH_CHANGED) new touches starting (if any) */
continue; if (touches_stopped)
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot);
queue_push_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
last_reported_slot = slot;
}
queue_push_event(dev, EV_SYN, SYN_REPORT, 0); queue_push_event(dev, EV_SYN, SYN_REPORT, 0);
}
for (int slot = 0; slot < dev->num_slots; slot++) { for (int slot = 0; slot < dev->num_slots; slot++) {
if (!bit_is_set(changes[slot].axes, ABS_MT_SLOT)) if (!bit_is_set(changes[slot].axes, ABS_MT_SLOT))
@ -859,8 +871,13 @@ sync_state(struct libevdev *dev)
if (rc == 0 && libevdev_has_event_type(dev, EV_ABS)) if (rc == 0 && libevdev_has_event_type(dev, EV_ABS))
rc = sync_abs_state(dev); rc = sync_abs_state(dev);
if (rc == 0 && dev->num_slots > -1 && if (rc == 0 && dev->num_slots > -1 &&
libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) {
rc = sync_mt_state(dev, 1); 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); dev->queue_nsync = queue_num_elements(dev);