From faf7a6107f5a5eb81a58a3879f7b7034803e043f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 31 May 2016 14:52:57 +1000 Subject: touchpad: warn if we have invalid touchpad ranges Quite a few bugs are caused by touchpad ranges being out of whack. If we get input events significantly outside the expected range (5% width/height as error margin) print a warning to the log. And add a new doc page to explain what is happening and how to fix it. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/evdev-mt-touchpad.h | 5 +++++ 2 files changed, 64 insertions(+) (limited to 'src') diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 61d955a6..a7b7a680 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -289,6 +289,39 @@ tp_get_delta(struct tp_touch *t) return tp_normalize_delta(t->tp, delta); } +static inline void +tp_check_axis_range(struct tp_dispatch *tp, + unsigned int code, + int value) +{ + int min, max; + + switch(code) { + case ABS_X: + case ABS_MT_POSITION_X: + min = tp->warning_range.min.x; + max = tp->warning_range.max.x; + break; + case ABS_Y: + case ABS_MT_POSITION_Y: + min = tp->warning_range.min.y; + max = tp->warning_range.max.y; + break; + default: + return; + } + + if (value < min || value > max) { + log_info_ratelimit(tp_libinput_context(tp), + &tp->warning_range.range_warn_limit, + "Axis %#x value %d is outside expected range [%d, %d]\n" + "See %s/absolute_coordinate_ranges.html for details\n", + code, value, min, max, + HTTP_DOC_LINK); + + } +} + static void tp_process_absolute(struct tp_dispatch *tp, const struct input_event *e, @@ -298,12 +331,14 @@ tp_process_absolute(struct tp_dispatch *tp, switch(e->code) { case ABS_MT_POSITION_X: + tp_check_axis_range(tp, e->code, e->value); t->point.x = e->value; t->millis = time; t->dirty = true; tp->queued |= TOUCHPAD_EVENT_MOTION; break; case ABS_MT_POSITION_Y: + tp_check_axis_range(tp, e->code, e->value); t->point.y = e->value; t->millis = time; t->dirty = true; @@ -339,12 +374,14 @@ tp_process_absolute_st(struct tp_dispatch *tp, switch(e->code) { case ABS_X: + tp_check_axis_range(tp, e->code, e->value); t->point.x = e->value; t->millis = time; t->dirty = true; tp->queued |= TOUCHPAD_EVENT_MOTION; break; case ABS_Y: + tp_check_axis_range(tp, e->code, e->value); t->point.y = e->value; t->millis = time; t->dirty = true; @@ -2063,6 +2100,26 @@ want_hysteresis: return; } +static void +tp_init_range_warnings(struct tp_dispatch *tp, + struct evdev_device *device, + int width, + int height) +{ + const struct input_absinfo *x, *y; + + x = device->abs.absinfo_x; + y = device->abs.absinfo_y; + + tp->warning_range.min.x = x->minimum - 0.05 * width; + tp->warning_range.min.y = y->minimum - 0.05 * height; + tp->warning_range.max.x = x->maximum + 0.05 * width; + tp->warning_range.max.y = y->maximum + 0.05 * height; + + /* One warning every 5 min is enough */ + ratelimit_init(&tp->warning_range.range_warn_limit, s2us(3000), 1); +} + static int tp_init(struct tp_dispatch *tp, struct evdev_device *device) @@ -2086,6 +2143,8 @@ tp_init(struct tp_dispatch *tp, height = device->abs.dimensions.y; diagonal = sqrt(width*width + height*height); + tp_init_range_warnings(tp, device, width, height); + tp->reports_distance = libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_DISTANCE); diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index cbc33aa4..1efe25c5 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -244,6 +244,11 @@ struct tp_dispatch { struct device_coords hysteresis_margin; + struct { + struct device_coords min, max; + struct ratelimit range_warn_limit; + } warning_range; + struct { double x_scale_coeff; double y_scale_coeff; -- cgit v1.2.3