[PATCH libinput 5/7] touchpad: Make anisotropic motion deltas isotropic

Jonas Ådahl jadahl at gmail.com
Mon May 26 14:27:28 PDT 2014


The x and y absolute axis may have different resolutions, meaning 1 unit
long motion delta on one axis is not physically as long as 1 unit motion
delta on the other axis.

In order to make these anisotropic input motion deltas output as isotropic
motion deltas, apply scaling to one of the axis making it have the same
dimension as the other, before passing it through the motion filter
which assumes all deltas are isotropic.

https://bugs.freedesktop.org/show_bug.cgi?id=79056

Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 src/evdev-mt-touchpad.c | 35 +++++++++++++++++++++++++++++++++--
 src/evdev-mt-touchpad.h |  3 +++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 751132c..6e5375c 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -84,8 +84,8 @@ tp_filter_motion(struct tp_dispatch *tp,
 {
 	struct motion_params motion;
 
-	motion.dx = *dx;
-	motion.dy = *dy;
+	motion.dx = *dx * tp->accel.x_scale_coeff;
+	motion.dy = *dy * tp->accel.y_scale_coeff;
 
 	filter_dispatch(tp->filter, &motion, tp, time);
 
@@ -671,11 +671,42 @@ tp_init_slots(struct tp_dispatch *tp,
 	return 0;
 }
 
+static void
+calculate_scale_coefficients(struct tp_dispatch *tp)
+{
+	int res_x, res_y;
+
+	if (tp->has_mt) {
+		res_x = libevdev_get_abs_resolution(tp->device->evdev,
+						    ABS_MT_POSITION_X);
+		res_y = libevdev_get_abs_resolution(tp->device->evdev,
+						    ABS_MT_POSITION_Y);
+	} else {
+		res_x = libevdev_get_abs_resolution(tp->device->evdev,
+						    ABS_X);
+		res_y = libevdev_get_abs_resolution(tp->device->evdev,
+						    ABS_Y);
+	}
+
+	if (res_x <= 0 || res_y <= 0) {
+		tp->accel.x_scale_coeff = 1.0;
+		tp->accel.y_scale_coeff = 1.0;
+	} else if (res_x > res_y) {
+		tp->accel.x_scale_coeff = res_y / (double) res_x;
+		tp->accel.y_scale_coeff = 1.0f;
+	} else {
+		tp->accel.y_scale_coeff = res_x / (double) res_y;
+		tp->accel.x_scale_coeff = 1.0f;
+	}
+}
+
 static int
 tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
 {
 	struct motion_filter *accel;
 
+	calculate_scale_coefficients(touchpad);
+
 	touchpad->accel.constant_factor =
 		DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
 	touchpad->accel.min_factor = DEFAULT_MIN_ACCEL_FACTOR;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 41e3ca4..6539149 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -151,6 +151,9 @@ struct tp_dispatch {
 		double constant_factor;
 		double min_factor;
 		double max_factor;
+
+		double x_scale_coeff;
+		double y_scale_coeff;
 	} accel;
 
 	struct {
-- 
1.9.1



More information about the wayland-devel mailing list