summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-05-31 14:52:57 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-06-02 08:01:43 +1000
commitfaf7a6107f5a5eb81a58a3879f7b7034803e043f (patch)
tree469ee68b029bd17a2453fd6276d9d4c278960af5 /src
parent031b7fb79b7af7bfc20315d6ba46dbf686be2dc6 (diff)
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 <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/evdev-mt-touchpad.c59
-rw-r--r--src/evdev-mt-touchpad.h5
2 files changed, 64 insertions, 0 deletions
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
@@ -245,6 +245,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;
} accel;