evdev: send old valuator inside event frame when the other is missing
authorTiago Vignatti <tiago.vignatti@intel.com>
Thu, 8 Dec 2011 10:18:16 +0000 (12:18 +0200)
committerJonas Ådahl <jadahl@gmail.com>
Sun, 10 Nov 2013 16:51:26 +0000 (17:51 +0100)
when a motion is being performed on ts device, only one axis can be sent
through the evdev bytestream whereas the other could be omitted. For instance:

   -------------- SYN_REPORT ------------
   type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 22208
   type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 631
   type 3 (EV_ABS), code 0 (ABS_X), value 22208
   -------------- SYN_REPORT ------------

on such case we'd have to send the compositor the old value of Y. Commit
f547bd36 introduced this bug cause it was sending zeroed coordinate and not
the old one.

Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
compositor/evdev.c

index 1755a95..c4a861f 100644 (file)
@@ -204,6 +204,20 @@ is_motion_event(struct input_event *e)
 }
 
 static void
+evdev_reset_accum(struct wl_input_device *device,
+                 struct evdev_motion_accumulator *accum)
+{
+       memset(accum, 0, sizeof *accum);
+
+       /* There are cases where only one axis on ts devices can be sent
+        * through the bytestream whereas the other could be omitted. For
+        * this, we have to save the old value that will be forwarded without
+        * modifications to the compositor. */
+       accum->x = device->x;
+       accum->y = device->y;
+}
+
+static void
 evdev_flush_motion(struct wl_input_device *device, uint32_t time,
                   struct evdev_motion_accumulator *accum)
 {
@@ -213,7 +227,7 @@ evdev_flush_motion(struct wl_input_device *device, uint32_t time,
        if (accum->type == EVDEV_ABSOLUTE_MOTION)
                notify_motion(device, time, accum->x, accum->y);
 
-       memset(accum, 0, sizeof *accum);
+       evdev_reset_accum(device, accum);
 }
 
 static int
@@ -236,7 +250,7 @@ evdev_input_device_data(int fd, uint32_t mask, void *data)
                return 1;
        }
 
-       memset(&accumulator, 0, sizeof accumulator);
+       evdev_reset_accum(&device->master->base.input_device, &accumulator);
 
        e = ev;
        end = (void *) ev + len;