diff options
-rw-r--r-- | src/evdev.c | 57 | ||||
-rw-r--r-- | src/evdev.h | 7 | ||||
-rw-r--r-- | src/udev-seat.c | 11 |
3 files changed, 63 insertions, 12 deletions
diff --git a/src/evdev.c b/src/evdev.c index 51b99e63..571fb0b6 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -141,16 +141,39 @@ evdev_process_absolute_motion(struct evdev_device *device, 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->pending_events |= EVDEV_ABSOLUTE_MOTION; + if (device->quirks & EVDEV_QUIRK_SWAP_AXES) { + device->abs.y = + (e->value - device->abs.min_y) * screen_height / + (device->abs.max_y - device->abs.min_y) + + device->output->y; + } else if (device->quirks & EVDEV_QUIRK_SWAP_XAXIS) { + device->abs.x = + (device->abs.max_x - (e->value - device->abs.min_x)) * screen_width / + (device->abs.max_x - device->abs.min_x) + + device->output->x; + } else { + /* Normally Process 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; case ABS_Y: - device->abs.y = - (e->value - device->abs.min_y) * screen_height / - (device->abs.max_y - device->abs.min_y); - device->pending_events |= EVDEV_ABSOLUTE_MOTION; + if (device->quirks & EVDEV_QUIRK_SWAP_AXES) { + device->abs.x = + (e->value - device->abs.min_x) * screen_width / + (device->abs.max_x - device->abs.min_x) + + device->output->x; + } else { + /* Normally Process 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; } } @@ -472,12 +495,22 @@ evdev_handle_device(struct evdev_device *device) TEST_BIT(abs_bits, ABS_MT_POSITION_Y)) { 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->caps |= EVDEV_TOUCH; diff --git a/src/evdev.h b/src/evdev.h index 524fa229..2eec5e5e 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -47,6 +47,12 @@ enum evdev_device_capability { EVDEV_TOUCH = (1 << 4), }; +enum evdev_device_quirks { + EVDEV_QUIRK_NONE = 0, + EVDEV_QUIRK_SWAP_AXES = (1 << 0), + EVDEV_QUIRK_SWAP_XAXIS = (2 << 0), +}; + struct evdev_device { struct weston_seat *seat; struct wl_list link; @@ -77,6 +83,7 @@ struct evdev_device { enum evdev_event_type pending_events; enum evdev_device_capability caps; + uint32_t quirks; int is_mt; }; diff --git a/src/udev-seat.c b/src/udev-seat.c index 771d9bcf..3c49f895 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -40,6 +40,16 @@ udev_seat_create(struct weston_compositor *c, const char *seat_name); static void udev_seat_destroy(struct udev_seat *seat); +static void +device_parse_quirks(struct evdev_device *evdev_device, + struct udev_device *udev_device) +{ + if (udev_device_get_property_value(udev_device, "WL_QUIRK_SWAP_AXES")) + evdev_device->quirks |= EVDEV_QUIRK_SWAP_AXES; + else if (udev_device_get_property_value(udev_device, "WL_QUIRK_SWAP_XAXIS")) + evdev_device->quirks |= EVDEV_QUIRK_SWAP_XAXIS; +} + static int device_added(struct udev_device *udev_device, struct udev_input *input) { @@ -114,6 +124,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) device->abs.calibration[5]); } + device_parse_quirks(device, udev_device); wl_list_insert(seat->devices_list.prev, &device->link); if (seat->base.output && seat->base.pointer) |