Expand the touch state handling during SYN_DROPPED
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 13 Feb 2020 06:50:17 +0000 (16:50 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 19 Feb 2020 00:31:53 +0000 (10:31 +1000)
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>
libevdev/libevdev.c

index 430add0dbcd34499b2d69bb8c54d75bdc0d82911..124e987209b35a1ee5cc2aaf495ce2fe1717e9f5 100644 (file)
@@ -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));
                }