From: Rob Bradford <[email protected]>

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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to