[PATCH 2/2] evdev: Swap the X and Y absolute when the quirk is set

Rob Bradford rob at robster.org.uk
Fri Sep 21 10:20:31 PDT 2012


From: Rob Bradford <rob at linux.intel.com>

We do this by storing the relative x and y absolute position in the device
structure and then applying the scale (and addition of the output position) to
put them in screen coordinates later.
---
 src/evdev.c | 30 +++++++++++++++++++-----------
 src/evdev.h |  2 +-
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 8848736..7aa4c13 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -126,22 +126,17 @@ static inline void
 evdev_process_absolute_motion(struct evdev_device *device,
 			      struct input_event *e)
 {
-	const int screen_width = device->output->current->width;
-	const int screen_height = device->output->current->height;
-
 	switch (e->code) {
 	case ABS_X:
 		device->abs.x =
-			(e->value - device->abs.min_x) * screen_width /
-			(device->abs.max_x - device->abs.min_x) +
-			device->output->x;
+			(double)(e->value - device->abs.min_x) /
+			(device->abs.max_x - device->abs.min_x);
 		device->pending_events |= EVDEV_ABSOLUTE_MOTION;
 		break;
 	case ABS_Y:
 		device->abs.y =
-			(e->value - device->abs.min_y) * screen_height /
-			(device->abs.max_y - device->abs.min_y) +
-			device->output->y;
+			(double)(e->value - device->abs.min_y) /
+			(device->abs.max_y - device->abs.min_y);
 		device->pending_events |= EVDEV_ABSOLUTE_MOTION;
 		break;
 	}
@@ -248,9 +243,22 @@ evdev_flush_motion(struct evdev_device *device, uint32_t time)
 		device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
 	}
 	if (device->pending_events & EVDEV_ABSOLUTE_MOTION) {
+		int x, y;
+		const int screen_width = device->output->current->width;
+		const int screen_height = device->output->current->height;
+
+		if (device->quirks & EVDEV_QUIRK_SWAP_AXES) {
+			x = device->output->x + device->abs.y * screen_width;
+			y = device->output->y + device->abs.x * screen_height;
+		} else {
+			x = device->output->x + device->abs.x * screen_width;
+			y = device->output->y + device->abs.y * screen_height;
+		}
+
+
 		notify_motion(master, time,
-			      wl_fixed_from_int(device->abs.x),
-			      wl_fixed_from_int(device->abs.y));
+			      wl_fixed_from_int(x),
+			      wl_fixed_from_int(y));
 		device->pending_events &= ~EVDEV_ABSOLUTE_MOTION;
 	}
 }
diff --git a/src/evdev.h b/src/evdev.h
index 9ae62db..e47adc3 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -60,7 +60,7 @@ struct evdev_device {
 	int fd;
 	struct {
 		int min_x, max_x, min_y, max_y;
-		int32_t x, y;
+		double x, y;
 	} abs;
 
 	struct {
-- 
1.7.11.2



More information about the wayland-devel mailing list