[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