touchpad: move tp_init_thumb and tp_thumb_detect to the thumb file
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 18 Jun 2019 00:53:39 +0000 (10:53 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Mon, 15 Jul 2019 03:08:47 +0000 (13:08 +1000)
Extracted from Matt Mayfield's thumb detection patches.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev-mt-touchpad-thumb.c
src/evdev-mt-touchpad.c
src/evdev-mt-touchpad.h

index b207f02..3c9354c 100644 (file)
 #include "config.h"
 #include "evdev-mt-touchpad.h"
 
+#define THUMB_MOVE_TIMEOUT ms2us(300)
+
 bool
 tp_thumb_ignored(const struct tp_dispatch *tp, const struct tp_touch *t)
 {
        return t->thumb.state == THUMB_STATE_YES;
 }
+
+static inline const char*
+thumb_state_to_str(enum tp_thumb_state state)
+{
+       switch(state){
+       CASE_RETURN_STRING(THUMB_STATE_NO);
+       CASE_RETURN_STRING(THUMB_STATE_YES);
+       CASE_RETURN_STRING(THUMB_STATE_MAYBE);
+       }
+
+       return NULL;
+}
+
+void
+tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
+{
+       enum tp_thumb_state state = t->thumb.state;
+
+       /* once a thumb, always a thumb, once ruled out always ruled out */
+       if (!tp->thumb.detect_thumbs ||
+           t->thumb.state != THUMB_STATE_MAYBE)
+               return;
+
+       if (t->point.y < tp->thumb.upper_thumb_line) {
+               /* if a potential thumb is above the line, it won't ever
+                * label as thumb */
+               t->thumb.state = THUMB_STATE_NO;
+               goto out;
+       }
+
+       /* If the thumb moves by more than 7mm, it's not a resting thumb */
+       if (t->state == TOUCH_BEGIN) {
+               t->thumb.initial = t->point;
+       } else if (t->state == TOUCH_UPDATE) {
+               struct device_float_coords delta;
+               struct phys_coords mm;
+
+               delta = device_delta(t->point, t->thumb.initial);
+               mm = tp_phys_delta(tp, delta);
+               if (length_in_mm(mm) > 7) {
+                       t->thumb.state = THUMB_STATE_NO;
+                       goto out;
+               }
+       }
+
+       /* If the finger is below the upper thumb line and we have another
+        * finger in the same area, neither finger is a thumb (unless we've
+        * already labeled it as such).
+        */
+       if (t->point.y > tp->thumb.upper_thumb_line &&
+           tp->nfingers_down > 1) {
+               struct tp_touch *other;
+
+               tp_for_each_touch(tp, other) {
+                       if (other->state != TOUCH_BEGIN &&
+                           other->state != TOUCH_UPDATE)
+                               continue;
+
+                       if (other->point.y > tp->thumb.upper_thumb_line) {
+                               t->thumb.state = THUMB_STATE_NO;
+                               if (other->thumb.state == THUMB_STATE_MAYBE)
+                                       other->thumb.state = THUMB_STATE_NO;
+                               break;
+                       }
+               }
+       }
+
+       /* Note: a thumb at the edge of the touchpad won't trigger the
+        * threshold, the surface area is usually too small. So we have a
+        * two-stage detection: pressure and time within the area.
+        * A finger that remains at the very bottom of the touchpad becomes
+        * a thumb.
+        */
+       if (tp->thumb.use_pressure &&
+           t->pressure > tp->thumb.pressure_threshold) {
+               t->thumb.state = THUMB_STATE_YES;
+       } else if (tp->thumb.use_size &&
+                (t->major > tp->thumb.size_threshold) &&
+                (t->minor < (tp->thumb.size_threshold * 0.6))) {
+               t->thumb.state = THUMB_STATE_YES;
+       } else if (t->point.y > tp->thumb.lower_thumb_line &&
+                tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE &&
+                t->thumb.first_touch_time + THUMB_MOVE_TIMEOUT < time) {
+               t->thumb.state = THUMB_STATE_YES;
+       }
+
+       /* now what? we marked it as thumb, so:
+        *
+        * - pointer motion must ignore this touch
+        * - clickfinger must ignore this touch for finger count
+        * - software buttons are unaffected
+        * - edge scrolling unaffected
+        * - gestures: unaffected
+        * - tapping: honour thumb on begin, ignore it otherwise for now,
+        *   this gets a tad complicated otherwise
+        */
+out:
+       if (t->thumb.state != state)
+               evdev_log_debug(tp->device,
+                         "thumb state: touch %d, %s → %s\n",
+                         t->index,
+                         thumb_state_to_str(state),
+                         thumb_state_to_str(t->thumb.state));
+}
+
+void
+tp_init_thumb(struct tp_dispatch *tp)
+{
+       struct evdev_device *device = tp->device;
+       double w = 0.0, h = 0.0;
+       struct device_coords edges;
+       struct phys_coords mm = { 0.0, 0.0 };
+       uint32_t threshold;
+       struct quirks_context *quirks;
+       struct quirks *q;
+
+       if (!tp->buttons.is_clickpad)
+               return;
+
+       /* if the touchpad is less than 50mm high, skip thumb detection.
+        * it's too small to meaningfully interact with a thumb on the
+        * touchpad */
+       evdev_device_get_size(device, &w, &h);
+       if (h < 50)
+               return;
+
+       tp->thumb.detect_thumbs = true;
+       tp->thumb.use_pressure = false;
+       tp->thumb.pressure_threshold = INT_MAX;
+
+       /* detect thumbs by pressure in the bottom 15mm, detect thumbs by
+        * lingering in the bottom 8mm */
+       mm.y = h * 0.85;
+       edges = evdev_device_mm_to_units(device, &mm);
+       tp->thumb.upper_thumb_line = edges.y;
+
+       mm.y = h * 0.92;
+       edges = evdev_device_mm_to_units(device, &mm);
+       tp->thumb.lower_thumb_line = edges.y;
+
+       quirks = evdev_libinput_context(device)->quirks;
+       q = quirks_fetch_for_device(quirks, device->udev_device);
+
+       if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE)) {
+               if (quirks_get_uint32(q,
+                                     QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD,
+                                     &threshold)) {
+                       tp->thumb.use_pressure = true;
+                       tp->thumb.pressure_threshold = threshold;
+               }
+       }
+
+       if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_TOUCH_MAJOR)) {
+               if (quirks_get_uint32(q,
+                                     QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
+                                     &threshold)) {
+                       tp->thumb.use_size = true;
+                       tp->thumb.size_threshold = threshold;
+               }
+       }
+
+       quirks_unref(q);
+
+       evdev_log_debug(device,
+                       "thumb: enabled thumb detection (area%s%s)\n",
+                       tp->thumb.use_pressure ? ", pressure" : "",
+                       tp->thumb.use_size ? ", size" : "");
+}
index 51b7ef7..929de21 100644 (file)
@@ -39,7 +39,6 @@
 #define DEFAULT_TRACKPOINT_EVENT_TIMEOUT ms2us(40)
 #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1 ms2us(200)
 #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2 ms2us(500)
-#define THUMB_MOVE_TIMEOUT ms2us(300)
 #define FAKE_FINGER_OVERFLOW (1 << 7)
 #define THUMB_IGNORE_SPEED_THRESHOLD 20 /* mm/s */
 
@@ -1156,110 +1155,6 @@ out:
                  palm_state);
 }
 
-static inline const char*
-thumb_state_to_str(enum tp_thumb_state state)
-{
-       switch(state){
-       CASE_RETURN_STRING(THUMB_STATE_NO);
-       CASE_RETURN_STRING(THUMB_STATE_YES);
-       CASE_RETURN_STRING(THUMB_STATE_MAYBE);
-       }
-
-       return NULL;
-}
-
-static void
-tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
-{
-       enum tp_thumb_state state = t->thumb.state;
-
-       /* once a thumb, always a thumb, once ruled out always ruled out */
-       if (!tp->thumb.detect_thumbs ||
-           t->thumb.state != THUMB_STATE_MAYBE)
-               return;
-
-       if (t->point.y < tp->thumb.upper_thumb_line) {
-               /* if a potential thumb is above the line, it won't ever
-                * label as thumb */
-               t->thumb.state = THUMB_STATE_NO;
-               goto out;
-       }
-
-       /* If the thumb moves by more than 7mm, it's not a resting thumb */
-       if (t->state == TOUCH_BEGIN) {
-               t->thumb.initial = t->point;
-       } else if (t->state == TOUCH_UPDATE) {
-               struct device_float_coords delta;
-               struct phys_coords mm;
-
-               delta = device_delta(t->point, t->thumb.initial);
-               mm = tp_phys_delta(tp, delta);
-               if (length_in_mm(mm) > 7) {
-                       t->thumb.state = THUMB_STATE_NO;
-                       goto out;
-               }
-       }
-
-       /* If the finger is below the upper thumb line and we have another
-        * finger in the same area, neither finger is a thumb (unless we've
-        * already labeled it as such).
-        */
-       if (t->point.y > tp->thumb.upper_thumb_line &&
-           tp->nfingers_down > 1) {
-               struct tp_touch *other;
-
-               tp_for_each_touch(tp, other) {
-                       if (other->state != TOUCH_BEGIN &&
-                           other->state != TOUCH_UPDATE)
-                               continue;
-
-                       if (other->point.y > tp->thumb.upper_thumb_line) {
-                               t->thumb.state = THUMB_STATE_NO;
-                               if (other->thumb.state == THUMB_STATE_MAYBE)
-                                       other->thumb.state = THUMB_STATE_NO;
-                               break;
-                       }
-               }
-       }
-
-       /* Note: a thumb at the edge of the touchpad won't trigger the
-        * threshold, the surface area is usually too small. So we have a
-        * two-stage detection: pressure and time within the area.
-        * A finger that remains at the very bottom of the touchpad becomes
-        * a thumb.
-        */
-       if (tp->thumb.use_pressure &&
-           t->pressure > tp->thumb.pressure_threshold) {
-               t->thumb.state = THUMB_STATE_YES;
-       } else if (tp->thumb.use_size &&
-                (t->major > tp->thumb.size_threshold) &&
-                (t->minor < (tp->thumb.size_threshold * 0.6))) {
-               t->thumb.state = THUMB_STATE_YES;
-       } else if (t->point.y > tp->thumb.lower_thumb_line &&
-                tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE &&
-                t->thumb.first_touch_time + THUMB_MOVE_TIMEOUT < time) {
-               t->thumb.state = THUMB_STATE_YES;
-       }
-
-       /* now what? we marked it as thumb, so:
-        *
-        * - pointer motion must ignore this touch
-        * - clickfinger must ignore this touch for finger count
-        * - software buttons are unaffected
-        * - edge scrolling unaffected
-        * - gestures: unaffected
-        * - tapping: honour thumb on begin, ignore it otherwise for now,
-        *   this gets a tad complicated otherwise
-        */
-out:
-       if (t->thumb.state != state)
-               evdev_log_debug(tp->device,
-                         "thumb state: touch %d, %s → %s\n",
-                         t->index,
-                         thumb_state_to_str(state),
-                         thumb_state_to_str(t->thumb.state));
-}
-
 static void
 tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
 {
@@ -3452,69 +3347,6 @@ tp_init_sendevents(struct tp_dispatch *tp,
                            tp_keyboard_timeout, tp);
 }
 
-static void
-tp_init_thumb(struct tp_dispatch *tp)
-{
-       struct evdev_device *device = tp->device;
-       double w = 0.0, h = 0.0;
-       struct device_coords edges;
-       struct phys_coords mm = { 0.0, 0.0 };
-       uint32_t threshold;
-       struct quirks_context *quirks;
-       struct quirks *q;
-
-       if (!tp->buttons.is_clickpad)
-               return;
-
-       /* if the touchpad is less than 50mm high, skip thumb detection.
-        * it's too small to meaningfully interact with a thumb on the
-        * touchpad */
-       evdev_device_get_size(device, &w, &h);
-       if (h < 50)
-               return;
-
-       tp->thumb.detect_thumbs = true;
-       tp->thumb.use_pressure = false;
-       tp->thumb.pressure_threshold = INT_MAX;
-
-       /* detect thumbs by pressure in the bottom 15mm, detect thumbs by
-        * lingering in the bottom 8mm */
-       mm.y = h * 0.85;
-       edges = evdev_device_mm_to_units(device, &mm);
-       tp->thumb.upper_thumb_line = edges.y;
-
-       mm.y = h * 0.92;
-       edges = evdev_device_mm_to_units(device, &mm);
-       tp->thumb.lower_thumb_line = edges.y;
-
-       quirks = evdev_libinput_context(device)->quirks;
-       q = quirks_fetch_for_device(quirks, device->udev_device);
-
-       if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE)) {
-               if (quirks_get_uint32(q,
-                                     QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD,
-                                     &threshold)) {
-                       tp->thumb.use_pressure = true;
-                       tp->thumb.pressure_threshold = threshold;
-               }
-       }
-
-       if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_TOUCH_MAJOR)) {
-               if (quirks_get_uint32(q,
-                                     QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
-                                     &threshold)) {
-                       tp->thumb.use_size = true;
-                       tp->thumb.size_threshold = threshold;
-               }
-       }
-
-       quirks_unref(q);
-
-       evdev_log_debug(device,
-                       "thumb: enabled thumb detection (area%s%s)\n",
-                       tp->thumb.use_pressure ? ", pressure" : "",
-                       tp->thumb.use_size ? ", size" : "");
-}
 
 static bool
 tp_pass_sanity_check(struct tp_dispatch *tp,
index 9c2d1f4..74006b4 100644 (file)
@@ -684,4 +684,10 @@ tp_clickpad_middlebutton_apply_config(struct evdev_device *device);
 bool
 tp_thumb_ignored(const struct tp_dispatch *tp, const struct tp_touch *t);
 
+void
+tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time);
+
+void
+tp_init_thumb(struct tp_dispatch *tp);
+
 #endif