[PATCH libinput] touchpad: move the pressure range to a hwdb entry

Peter Hutterer peter.hutterer at who-t.net
Thu Apr 20 04:59:23 UTC 2017


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c            | 44 +++++++++++++++++++++++++++-----------
 src/libinput-util.c                | 36 +++++++++++++++++++++++++++++++
 src/libinput-util.h                |  1 +
 test/test-misc.c                   | 43 +++++++++++++++++++++++++++++++++++++
 udev/90-libinput-model-quirks.hwdb |  2 ++
 udev/parse_hwdb.py                 |  8 ++++++-
 6 files changed, 121 insertions(+), 13 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index eb950a2..99963e6 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -2372,8 +2372,9 @@ tp_init_pressure(struct tp_dispatch *tp,
 		 struct evdev_device *device)
 {
 	const struct input_absinfo *abs;
-	unsigned int range;
 	unsigned int code = ABS_PRESSURE;
+	const char *prop;
+	int hi, lo;
 
 	if (tp->has_mt)
 		code = ABS_MT_PRESSURE;
@@ -2383,25 +2384,44 @@ tp_init_pressure(struct tp_dispatch *tp,
 		return;
 	}
 
-	tp->pressure.use_pressure = true;
-
 	abs = libevdev_get_abs_info(device->evdev, code);
 	assert(abs);
 
-	range = abs->maximum - abs->minimum;
+	prop = udev_device_get_property_value(device->udev_device,
+					      "LIBINPUT_ATTR_PRESSURE_RANGE");
+	if (prop) {
+		if (!parse_pressure_range_property(prop, &hi, &lo)) {
+			evdev_log_bug_client(device,
+				     "discarding invalid pressure range '%s'\n",
+				     prop);
+			return;
+		}
 
-	if (device->model_flags & EVDEV_MODEL_ELANTECH_TOUCHPAD) {
-		tp->pressure.high = 24;
-		tp->pressure.low = 10;
-	} else if (device->model_flags & EVDEV_MODEL_CYAPA) {
-		tp->pressure.high = 10;
-		tp->pressure.low = 8;
+		if (hi == 0 && lo == 0) {
+			evdev_log_info(device,
+			       "pressure-based touch detection disabled\n");
+			return;
+		}
 	} else {
+		unsigned int range = abs->maximum - abs->minimum;
+
 		/* Approximately the synaptics defaults */
-		tp->pressure.high = abs->minimum + 0.12 * range;
-		tp->pressure.low = abs->minimum + 0.10 * range;
+		hi = abs->minimum + 0.12 * range;
+		lo = abs->minimum + 0.10 * range;
 	}
 
+	if (hi > abs->maximum || hi < abs->minimum ||
+	    lo > abs->maximum || lo < abs->minimum) {
+		evdev_log_bug_libinput(device,
+			       "discarding out-of-bounds pressure range %d:%d\n",
+			       hi, lo);
+		return;
+	}
+
+	tp->pressure.use_pressure = true;
+	tp->pressure.high = hi;
+	tp->pressure.low = lo;
+
 	evdev_log_debug(device,
 			"using pressure-based touch detection\n");
 }
diff --git a/src/libinput-util.c b/src/libinput-util.c
index 351bbe4..38594fa 100644
--- a/src/libinput-util.c
+++ b/src/libinput-util.c
@@ -360,6 +360,42 @@ parse_tpkbcombo_layout_poperty(const char *prop,
 }
 
 /**
+ * Parses a string of the format "a:b" where both a and b must be integer
+ * numbers and a > b. Also allowed is the special string vaule "none" which
+ * amounts to unsetting the property.
+ *
+ * @param prop The value of the property
+ * @param hi Set to the first digit or 0 in case of 'none'
+ * @param lo Set to the second digit or 0 in case of 'none'
+ * @return true on success, false otherwise
+ */
+bool
+parse_pressure_range_property(const char *prop, int *hi, int *lo)
+{
+	int first, second;
+
+	if (!prop)
+		return false;
+
+	if (streq(prop, "none")) {
+		*hi = 0;
+		*lo = 0;
+		return true;
+	}
+
+	if (sscanf(prop, "%d:%d", &first, &second) != 2)
+		return false;
+
+	if (second >= first)
+		return false;
+
+	*hi = first;
+	*lo = second;
+
+	return true;
+}
+
+/**
  * Return the next word in a string pointed to by state before the first
  * separator character. Call repeatedly to tokenize a whole string.
  *
diff --git a/src/libinput-util.h b/src/libinput-util.h
index 3fe0a02..4e97e01 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -393,6 +393,7 @@ int parse_mouse_wheel_click_count_property(const char *prop);
 double parse_trackpoint_accel_property(const char *prop);
 bool parse_dimension_property(const char *prop, size_t *width, size_t *height);
 bool parse_calibration_property(const char *prop, float calibration[6]);
+bool parse_pressure_range_property(const char *prop, int *hi, int *lo);
 
 enum tpkbcombo_layout {
 	TPKBCOMBO_LAYOUT_UNKNOWN,
diff --git a/test/test-misc.c b/test/test-misc.c
index 3f4b229..5101dcf 100644
--- a/test/test-misc.c
+++ b/test/test-misc.c
@@ -1001,6 +1001,48 @@ START_TEST(calibration_prop_parser)
 }
 END_TEST
 
+struct parser_test_pressure_range {
+	char *tag;
+	bool success;
+	int hi, lo;
+};
+
+START_TEST(pressure_range_prop_parser)
+{
+	struct parser_test_pressure_range tests[] = {
+		{ "10:8", true, 10, 8 },
+		{ "100:-1", true, 100, -1 },
+		{ "-203813:-502023", true, -203813, -502023 },
+		{ "238492:28210", true, 238492, 28210 },
+		{ "none", true, 0, 0 },
+		{ "0:0", false, 0, 0 },
+		{ "", false, 0, 0 },
+		{ "abcd", false, 0, 0 },
+		{ "10:30:10", false, 0, 0 },
+		{ NULL, false, 0, 0 }
+	};
+	int i;
+	int hi, lo;
+	bool success;
+
+	for (i = 0; tests[i].tag != NULL; i++) {
+		hi = lo = 0xad;
+		success = parse_pressure_range_property(tests[i].tag, &hi, &lo);
+		ck_assert(success == tests[i].success);
+		if (success) {
+			ck_assert_int_eq(hi, tests[i].hi);
+			ck_assert_int_eq(lo, tests[i].lo);
+		} else {
+			ck_assert_int_eq(hi, 0xad);
+			ck_assert_int_eq(lo, 0xad);
+		}
+	}
+
+	success = parse_pressure_range_property(NULL, NULL, NULL);
+	ck_assert(success == false);
+}
+END_TEST
+
 START_TEST(time_conversion)
 {
 	ck_assert_int_eq(us(10), 10);
@@ -1275,6 +1317,7 @@ litest_setup_tests_misc(void)
 	litest_add_no_device("misc:parser", dimension_prop_parser);
 	litest_add_no_device("misc:parser", reliability_prop_parser);
 	litest_add_no_device("misc:parser", calibration_prop_parser);
+	litest_add_no_device("misc:parser", pressure_range_prop_parser);
 	litest_add_no_device("misc:parser", safe_atoi_test);
 	litest_add_no_device("misc:parser", safe_atod_test);
 	litest_add_no_device("misc:parser", strsplit_test);
diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb
index 5370e36..9454fde 100644
--- a/udev/90-libinput-model-quirks.hwdb
+++ b/udev/90-libinput-model-quirks.hwdb
@@ -88,6 +88,7 @@ libinput:name:* Touchpad:dmi:*svnDellInc.:*
 ##########################################
 libinput:name:*ETPS/2 Elantech Touchpad*:dmi:*
  LIBINPUT_ATTR_RESOLUTION_HINT=31x31
+ LIBINPUT_ATTR_PRESSURE_RANGE=24:8
  LIBINPUT_MODEL_ELANTECH_TOUCHPAD=1
 
 ##########################################
@@ -114,6 +115,7 @@ libinput:name:Atmel maXTouch Touchpad:dmi:*svn*GOOGLE*:pn*Samus*
 
 libinput:name:Cypress APA Trackpad ?cyapa?:dmi:*
  LIBINPUT_MODEL_CYAPA=1
+ LIBINPUT_ATTR_PRESSURE_RANGE=10:8
 
 ##########################################
 # HP
diff --git a/udev/parse_hwdb.py b/udev/parse_hwdb.py
index 2a342bf..97f04f4 100755
--- a/udev/parse_hwdb.py
+++ b/udev/parse_hwdb.py
@@ -112,7 +112,13 @@ def property_grammar():
                          Suppress('=') -
                          tpkbcombo_tags('VALUE')]
 
-    grammar = Or(model_props + size_props + reliability + tpkbcombo)
+    pressure_range = INTEGER('X') + Suppress(':') + INTEGER('Y')
+    pressure_prop = [ Literal('LIBINPUT_ATTR_PRESSURE_RANGE')('NAME') -
+                      Suppress('=') -
+                      Group(pressure_range('SETTINGS*')) ]
+
+    grammar = Or(model_props + size_props + reliability + tpkbcombo +
+                 pressure_prop)
 
     return grammar
 
-- 
2.9.3



More information about the wayland-devel mailing list