[PATCH] Add pressure calculation for TOUCH/WIDTH touchpads

Ming-ting Yao Wei mwei at lxde.org
Fri Aug 14 00:34:59 PDT 2015


This patch is a simple ellipsis size thumb detection. By using MAJOR*MINOR we
can get what correspond to the pressure value, and we can find a suitable
pressure threshold that can separate thumbs from fingers.

Signed-off-by: Yao Wei <mwei at lxde.org>
---
 src/evdev-mt-touchpad.c | 39 ++++++++++++++++++++++++++++++++++++++-
 src/evdev-mt-touchpad.h |  7 +++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 872da98..2096dee 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -319,6 +319,14 @@ tp_process_absolute(struct tp_dispatch *tp,
 		t->dirty = true;
 		tp->queued |= TOUCHPAD_EVENT_MOTION;
 		break;
+	case ABS_MT_TOUCH_MAJOR:
+		t->ellipsis.major = e->value;
+		/* falls through, minor = major when major changes */
+	case ABS_MT_TOUCH_MINOR:
+		t->ellipsis.minor = e->value;
+		t->dirty = true;
+		tp->queued |= TOUCHPAD_EVENT_MOTION;
+		break;
 	}
 }
 
@@ -697,8 +705,18 @@ tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
 	 * A finger that remains at the very bottom of the touchpad becomes
 	 * a thumb.
 	 */
-	if (t->pressure > tp->thumb.threshold)
+	if (tp->thumb.pressure_detection && t->pressure > tp->thumb.threshold)
 		t->thumb.state = THUMB_STATE_YES;
+	else if (tp->thumb.ellipsis_detection) {
+		log_debug(tp_libinput_context(tp),
+			  "ellipsis: major %d, minor %d => %d, threshold is %d\n",
+			  t->ellipsis.major,
+			  t->ellipsis.minor,
+			  t->ellipsis.major * t->ellipsis.minor,
+			  tp->thumb.threshold);
+		if (t->ellipsis.major * t->ellipsis.minor > tp->thumb.threshold)
+			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)
@@ -1783,6 +1801,25 @@ tp_init_thumb(struct tp_dispatch *tp)
 	tp->thumb.upper_thumb_line = ymax - yres * 15;
 	tp->thumb.lower_thumb_line = ymax - yres * 8;
 
+	abs = libevdev_get_abs_info(device->evdev, ABS_MT_TOUCH_MAJOR);
+	if (!abs)
+		goto pressure;
+
+	/* Use ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR as pressure
+	 * detection.
+	 * Use MacBookPro11,1 (13" Retina, Mid-2014) as reference,
+	 * The ABS_MT_TOUCH_MAJOR * ABS_MT_TOUCH_MINOR should not
+	 * exceed 350000. However, this need a test if higher res
+	 * touchpads exhibit higher threshold value */
+
+	tp->thumb.detect_thumbs = true;
+	tp->thumb.ellipsis_detection = true;
+	tp->thumb.threshold = 350000.0;
+
+	goto out; /* skip pressure detection */
+
+pressure:
+
 	abs = libevdev_get_abs_info(device->evdev, ABS_MT_PRESSURE);
 	if (!abs)
 		goto out;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 3bd8425..110f824 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -215,6 +215,11 @@ struct tp_touch {
 		uint64_t first_touch_time;
 		struct device_coords initial;
 	} thumb;
+
+	struct {
+		int major;
+		int minor;
+	} ellipsis;
 };
 
 struct tp_dispatch {
@@ -347,6 +352,8 @@ struct tp_dispatch {
 
 	struct {
 		bool detect_thumbs;
+		bool pressure_detection;
+		bool ellipsis_detection;
 		int threshold;
 		int upper_thumb_line;
 		int lower_thumb_line;
-- 
2.5.0



More information about the wayland-devel mailing list