[PATCH 1/2] evdev: Add support for device quirks and implement axes swapping

Rob Bradford rob at robster.org.uk
Tue Sep 18 08:44:57 PDT 2012


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

This quirk is designed for hardware that has the X and Y axes swapped for
absolute events.
---
 src/evdev.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-----------------
 src/evdev.h |  6 ++++++
 2 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 8848736..3f9d635 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -129,21 +129,41 @@ evdev_process_absolute_motion(struct evdev_device *device,
 	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;
-		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;
-		device->pending_events |= EVDEV_ABSOLUTE_MOTION;
-		break;
+	if (device->quirks & EVDEV_QUIRK_SWAP_AXES) {
+		switch (e->code) {
+		case ABS_X:
+			device->abs.y =
+				(e->value - device->abs.min_y) * screen_height /
+				(device->abs.max_y - device->abs.min_y) +
+				device->output->y;
+			device->pending_events |= EVDEV_ABSOLUTE_MOTION;
+			break;
+		case ABS_Y:
+			device->abs.x =
+				(e->value - device->abs.min_x) * screen_width /
+				(device->abs.max_x - device->abs.min_x) +
+				device->output->x;
+			device->pending_events |= EVDEV_ABSOLUTE_MOTION;
+			break;
+		}
+
+	} else {
+		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;
+			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;
+			device->pending_events |= EVDEV_ABSOLUTE_MOTION;
+			break;
+		}
 	}
 }
 
@@ -395,12 +415,22 @@ evdev_configure_device(struct evdev_device *device)
 		if (TEST_BIT(abs_bits, ABS_MT_SLOT)) {
 			ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_X),
 			      &absinfo);
-			device->abs.min_x = absinfo.minimum;
-			device->abs.max_x = absinfo.maximum;
+			if (device->quirks & EVDEV_QUIRK_SWAP_AXES) {
+				device->abs.min_y = absinfo.minimum;
+				device->abs.max_y = absinfo.maximum;
+			} else {
+				device->abs.min_x = absinfo.minimum;
+				device->abs.max_x = absinfo.maximum;
+			}
 			ioctl(device->fd, EVIOCGABS(ABS_MT_POSITION_Y),
 			      &absinfo);
-			device->abs.min_y = absinfo.minimum;
-			device->abs.max_y = absinfo.maximum;
+			if (device->quirks & EVDEV_QUIRK_SWAP_AXES) {
+				device->abs.min_x = absinfo.minimum;
+				device->abs.max_x = absinfo.maximum;
+			} else {
+				device->abs.min_y = absinfo.minimum;
+				device->abs.max_y = absinfo.maximum;
+			}
 			device->is_mt = 1;
 			device->mt.slot = 0;
 			device->caps |= EVDEV_TOUCH;
diff --git a/src/evdev.h b/src/evdev.h
index 85c4739..9ae62db 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -44,6 +44,11 @@ enum evdev_device_capability {
 	EVDEV_TOUCH = (1 << 4),
 };
 
+enum evdev_device_quirks {
+	EVDEV_QUIRK_NONE = 0,
+	EVDEV_QUIRK_SWAP_AXES = (1 << 0),
+};
+
 struct evdev_device {
 	struct weston_seat *seat;
 	struct wl_list link;
@@ -71,6 +76,7 @@ struct evdev_device {
 
 	enum evdev_event_type pending_events;
 	enum evdev_device_capability caps;
+	uint32_t quirks;
 
 	int is_mt;
 };
-- 
1.7.11.2



More information about the wayland-devel mailing list