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

Hans de Goede hdegoede at redhat.com
Tue Nov 29 09:12:58 UTC 2016


Hi,

On 29-11-16 02:22, Peter Hutterer wrote:
> Move the code from the touchpad code into the more generic evdev code
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

Patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans


> ---
>  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);
>  }
>


More information about the wayland-devel mailing list