[PATCH libinput] evdev: init axis range warnings for touch devices too

Peter Hutterer peter.hutterer at who-t.net
Tue Nov 29 01:22:00 UTC 2016


Move the code from the touchpad code into the more generic evdev code

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 76 +++++++++----------------------------------------
 src/evdev-mt-touchpad.h |  5 ----
 src/evdev.c             |  6 ++++
 src/evdev.h             | 65 ++++++++++++++++++++++++++++++++++++++++++
 test/log.c              | 50 ++++++++++++++++++++++++++++++++
 5 files changed, 134 insertions(+), 68 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 7b8514c..0492851 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -279,39 +279,6 @@ 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,
@@ -321,14 +288,18 @@ tp_process_absolute(struct tp_dispatch *tp,
 
 	switch(e->code) {
 	case ABS_MT_POSITION_X:
-		tp_check_axis_range(tp, e->code, e->value);
+		evdev_device_check_abs_axis_range(tp->device,
+						  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);
+		evdev_device_check_abs_axis_range(tp->device,
+						  e->code,
+						  e->value);
 		t->point.y = e->value;
 		t->millis = time;
 		t->dirty = true;
@@ -363,14 +334,18 @@ tp_process_absolute_st(struct tp_dispatch *tp,
 
 	switch(e->code) {
 	case ABS_X:
-		tp_check_axis_range(tp, e->code, e->value);
+		evdev_device_check_abs_axis_range(tp->device,
+						  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);
+		evdev_device_check_abs_axis_range(tp->device,
+						  e->code,
+						  e->value);
 		t->point.y = e->value;
 		t->millis = time;
 		t->dirty = true;
@@ -2241,32 +2216,10 @@ tp_init_hysteresis(struct tp_dispatch *tp)
 	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)
 {
-	int width, height;
-
 	tp->base.interface = &tp_interface;
 	tp->device = device;
 
@@ -2278,10 +2231,7 @@ tp_init(struct tp_dispatch *tp,
 	if (!tp_init_slots(tp, device))
 		return false;
 
-	width = device->abs.dimensions.x;
-	height = device->abs.dimensions.y;
-
-	tp_init_range_warnings(tp, device, width, height);
+	evdev_device_init_abs_range_warnings(device);
 
 	tp->reports_distance = libevdev_has_event_code(device->evdev,
 						       EV_ABS,
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index f4ad090..db0a51a 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -248,11 +248,6 @@ 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;
diff --git a/src/evdev.c b/src/evdev.c
index 1e3cc90..afb5e34 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -852,11 +852,13 @@ fallback_process_touch(struct fallback_dispatch *dispatch,
 			dispatch->pending_event = EVDEV_ABSOLUTE_MT_UP;
 		break;
 	case ABS_MT_POSITION_X:
+		evdev_device_check_abs_axis_range(device, e->code, e->value);
 		dispatch->mt.slots[dispatch->mt.slot].point.x = e->value;
 		if (dispatch->pending_event == EVDEV_NONE)
 			dispatch->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
 		break;
 	case ABS_MT_POSITION_Y:
+		evdev_device_check_abs_axis_range(device, e->code, e->value);
 		dispatch->mt.slots[dispatch->mt.slot].point.y = e->value;
 		if (dispatch->pending_event == EVDEV_NONE)
 			dispatch->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
@@ -870,11 +872,13 @@ fallback_process_absolute_motion(struct fallback_dispatch *dispatch,
 {
 	switch (e->code) {
 	case ABS_X:
+		evdev_device_check_abs_axis_range(device, e->code, e->value);
 		dispatch->abs.point.x = e->value;
 		if (dispatch->pending_event == EVDEV_NONE)
 			dispatch->pending_event = EVDEV_ABSOLUTE_MOTION;
 		break;
 	case ABS_Y:
+		evdev_device_check_abs_axis_range(device, e->code, e->value);
 		dispatch->abs.point.y = e->value;
 		if (dispatch->pending_event == EVDEV_NONE)
 			dispatch->pending_event = EVDEV_ABSOLUTE_MOTION;
@@ -1716,6 +1720,8 @@ fallback_dispatch_init_abs(struct fallback_dispatch *dispatch,
 	dispatch->abs.point.x = device->abs.absinfo_x->value;
 	dispatch->abs.point.y = device->abs.absinfo_y->value;
 	dispatch->abs.seat_slot = -1;
+
+	evdev_device_init_abs_range_warnings(device);
 }
 
 static struct evdev_dispatch *
diff --git a/src/evdev.h b/src/evdev.h
index 3ad385e..b5a54a2 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -162,6 +162,11 @@ struct evdev_device {
 		struct matrix usermatrix; /* as supplied by the caller */
 
 		struct device_coords dimensions;
+
+		struct {
+			struct device_coords min, max;
+			struct ratelimit range_warn_limit;
+		} warning_range;
 	} abs;
 
 	struct {
@@ -298,6 +303,11 @@ struct fallback_dispatch {
 	struct {
 		struct device_coords point;
 		int32_t seat_slot;
+
+		struct {
+			struct device_coords min, max;
+			struct ratelimit range_warn_limit;
+		} warning_range;
 	} abs;
 
 	struct {
@@ -639,4 +649,59 @@ evdev_device_mm_to_units(const struct evdev_device *device,
 
 	return units;
 }
+
+static inline void
+evdev_device_init_abs_range_warnings(struct evdev_device *device)
+{
+	const struct input_absinfo *x, *y;
+	int width, height;
+
+	x = device->abs.absinfo_x;
+	y = device->abs.absinfo_y;
+	width = device->abs.dimensions.x;
+	height = device->abs.dimensions.y;
+
+	device->abs.warning_range.min.x = x->minimum - 0.05 * width;
+	device->abs.warning_range.min.y = y->minimum - 0.05 * height;
+	device->abs.warning_range.max.x = x->maximum + 0.05 * width;
+	device->abs.warning_range.max.y = y->maximum + 0.05 * height;
+
+	/* One warning every 5 min is enough */
+	ratelimit_init(&device->abs.warning_range.range_warn_limit,
+		       s2us(3000),
+		       1);
+}
+
+static inline void
+evdev_device_check_abs_axis_range(struct evdev_device *device,
+				  unsigned int code,
+				  int value)
+{
+	int min, max;
+
+	switch(code) {
+	case ABS_X:
+	case ABS_MT_POSITION_X:
+		min = device->abs.warning_range.min.x;
+		max = device->abs.warning_range.max.x;
+		break;
+	case ABS_Y:
+	case ABS_MT_POSITION_Y:
+		min = device->abs.warning_range.min.y;
+		max = device->abs.warning_range.max.y;
+		break;
+	default:
+		return;
+	}
+
+	if (value < min || value > max) {
+		log_info_ratelimit(evdev_libinput_context(device),
+				   &device->abs.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);
+	}
+}
+
 #endif /* EVDEV_H */
diff --git a/test/log.c b/test/log.c
index 9dca152..9988267 100644
--- a/test/log.c
+++ b/test/log.c
@@ -140,11 +140,61 @@ START_TEST(log_priority)
 }
 END_TEST
 
+static int axisrange_log_handler_called = 0;
+
+static void
+axisrange_warning_log_handler(struct libinput *libinput,
+			      enum libinput_log_priority priority,
+			      const char *format,
+			      va_list args)
+{
+	axisrange_log_handler_called++;
+	litest_assert_notnull(format);
+	litest_assert_notnull(strstr(format, "is outside expected range"));
+}
+
+START_TEST(log_axisrange_warning)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput *li = dev->libinput;
+	const struct input_absinfo *abs;
+	int axis = _i; /* looped test */
+
+	litest_touch_down(dev, 0, 90, 100);
+	litest_drain_events(li);
+
+	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO);
+	libinput_log_set_handler(li, axisrange_warning_log_handler);
+
+	abs = libevdev_get_abs_info(dev->evdev, axis);
+
+	for (int i = 0; i < 100; i++) {
+		litest_event(dev, EV_ABS,
+			     ABS_MT_POSITION_X + axis,
+			     abs->maximum * 2 + i);
+		litest_event(dev, EV_ABS, axis, abs->maximum * 2);
+		litest_event(dev, EV_SYN, SYN_REPORT, 0);
+		libinput_dispatch(li);
+	}
+
+	/* Expect only one message per 5 min */
+	ck_assert_int_eq(axisrange_log_handler_called, 1);
+
+	litest_restore_log_handler(li);
+	axisrange_log_handler_called = 0;
+}
+END_TEST
+
 void
 litest_setup_tests_log(void)
 {
+	struct range axes = { ABS_X, ABS_Y + 1};
+
 	litest_add_no_device("log:defaults", log_default_priority);
 	litest_add_no_device("log:logging", log_handler_invoked);
 	litest_add_no_device("log:logging", log_handler_NULL);
 	litest_add_no_device("log:logging", log_priority);
+
+	litest_add_ranged("log:warnings", log_axisrange_warning, LITEST_TOUCH, LITEST_ANY, &axes);
+	litest_add_ranged("log:warnings", log_axisrange_warning, LITEST_TOUCHPAD, LITEST_ANY, &axes);
 }
-- 
2.9.3



More information about the wayland-devel mailing list