.gitignore                                                        |    1 
 configure.ac                                                      |   17 
 debian/changelog                                                  |   33 
 debian/control                                                    |    1 
 debian/libinput10.symbols                                         |   52 
 debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch |    2 
 debian/patches/touch-point-orientation-size.patch                 |   58 
 doc/Makefile.am                                                   |    1 
 doc/absolute-axes.dox                                             |   18 
 doc/device-configuration-via-udev.dox                             |    4 
 doc/gestures.dox                                                  |   38 
 doc/normalization-of-relative-motion.dox                          |    8 
 doc/page-hierarchy.dox                                            |    4 
 doc/pointer-acceleration.dox                                      |    6 
 doc/svg/gesture-2fg-ambiguity.svg                                 |  496 +
 doc/svg/pinch-gestures-softbuttons.svg                            |  365 
 doc/svg/tablet-axes.svg                                           |  564 +
 doc/svg/tablet-out-of-bounds.svg                                  |  271 
 doc/svg/tablet.svg                                                |  199 
 doc/tablet-support.dox                                            |  211 
 doc/tapping.dox                                                   |    6 
 doc/touchpad-tap-state-machine.svg                                | 1467 ++-
 src/Makefile.am                                                   |    4 
 src/evdev-mt-touchpad-buttons.c                                   |   27 
 src/evdev-mt-touchpad-edge-scroll.c                               |    5 
 src/evdev-mt-touchpad-gestures.c                                  |  395 -
 src/evdev-mt-touchpad-tap.c                                       |   57 
 src/evdev-mt-touchpad.c                                           |  237 
 src/evdev-mt-touchpad.h                                           |   51 
 src/evdev-tablet.c                                                | 1691 ++++
 src/evdev-tablet.h                                                |  204 
 src/evdev.c                                                       |   95 
 src/evdev.h                                                       |   26 
 src/filter.c                                                      |   94 
 src/filter.h                                                      |    3 
 src/libinput-private.h                                            |  100 
 src/libinput-util.h                                               |   56 
 src/libinput.c                                                    |  826 ++
 src/libinput.h                                                    | 1011 ++
 src/libinput.sym                                                  |   55 
 test/Makefile.am                                                  |   18 
 test/device.c                                                     |  103 
 test/gestures.c                                                   |  892 ++
 test/litest-device-anker-mouse-kbd.c                              |  225 
 test/litest-device-apple-internal-keyboard.c                      |  239 
 test/litest-device-cyborg-rat-5.c                                 |   71 
 test/litest-device-huion-pentablet.c                              |  113 
 test/litest-device-synaptics-hover.c                              |    2 
 test/litest-device-synaptics-i2c.c                                |  102 
 test/litest-device-wacom-bamboo-tablet.c                          |  119 
 test/litest-device-wacom-cintiq-24hd.c                            |  147 
 test/litest-device-wacom-cintiq-tablet.c                          |  158 
 test/litest-device-wacom-intuos-tablet.c                          |  163 
 test/litest-device-wacom-isdv4-tablet.c                           |  112 
 test/litest-device-waltop-tablet.c                                |  241 
 test/litest-device-yubikey.c                                      |  169 
 test/litest-int.h                                                 |    8 
 test/litest-selftest.c                                            |    4 
 test/litest.c                                                     |  188 
 test/litest.h                                                     |  597 +
 test/misc.c                                                       |  114 
 test/path.c                                                       |   60 
 test/pointer.c                                                    |   10 
 test/tablet.c                                                     | 3680 
++++++++++
 test/touchpad-tap.c                                               |  296 
 test/touchpad.c                                                   |  485 +
 test/udev.c                                                       |    5 
 test/valgrind.suppressions                                        |   18 
 tools/event-debug.c                                               |  234 
 tools/event-gui.c                                                 |  236 
 tools/libinput-list-devices.c                                     |   16 
 tools/shared.c                                                    |   16 
 tools/shared.h                                                    |    1 
 udev/90-libinput-model-quirks.hwdb                                |   28 
 udev/90-libinput-model-quirks.rules.in                            |    4 
 udev/libinput-model-quirks.c                                      |    6 
 76 files changed, 16196 insertions(+), 1443 deletions(-)

New commits:
commit f06b99ba73bf0f8d801d0167e0c29f9717a99541
Author: Timo Aaltonen <[email protected]>
Date:   Thu Mar 17 11:14:12 2016 +0200

    refresh patches, release to xenial

diff --git a/debian/changelog b/debian/changelog
index bb23bdb..a5d26d9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libinput (1.2.2-1ubuntu1) xenial; urgency=medium
+
+  * Merge from debian.
+  * patches: Refreshed.
+
+ -- Timo Aaltonen <[email protected]>  Thu, 17 Mar 2016 11:12:01 +0200
+
 libinput (1.2.2-1) unstable; urgency=medium
 
   * New upstream release.
diff --git a/debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch 
b/debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch
index e1fb1d6..0473fdf 100644
--- a/debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch
+++ b/debian/patches/fix-premature-flushing-of-evdev-event-on-mx4.patch
@@ -17,7 +17,7 @@ Signed-off-by: Andreas Pokorny <[email protected]>
 
 --- a/src/evdev.c
 +++ b/src/evdev.c
-@@ -654,16 +654,16 @@ evdev_process_key(struct evdev_device *d
+@@ -665,16 +665,16 @@ evdev_process_key(struct evdev_device *d
        if (e->value == 2)
                return;
  
diff --git a/debian/patches/touch-point-orientation-size.patch 
b/debian/patches/touch-point-orientation-size.patch
index 7094de7..298a460 100644
--- a/debian/patches/touch-point-orientation-size.patch
+++ b/debian/patches/touch-point-orientation-size.patch
@@ -37,7 +37,7 @@ Signed-off-by: Andreas Pokorny <[email protected]>
 
 --- a/doc/Makefile.am
 +++ b/doc/Makefile.am
-@@ -26,6 +26,7 @@ header_files = \
+@@ -27,6 +27,7 @@ header_files = \
        $(srcdir)/tapping.dox \
        $(srcdir)/test-suite.dox \
        $(srcdir)/tools.dox \
@@ -45,7 +45,7 @@ Signed-off-by: Andreas Pokorny <[email protected]>
        $(srcdir)/touchpads.dox
  
  diagram_files = \
-@@ -50,6 +51,7 @@ diagram_files = \
+@@ -51,6 +52,7 @@ diagram_files = \
        $(srcdir)/svg/thumb-detection.svg \
        $(srcdir)/svg/top-software-buttons.svg \
        $(srcdir)/svg/touchscreen-gestures.svg \
@@ -471,7 +471,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  
  enum evdev_key_type {
        EVDEV_KEY_TYPE_NONE,
-@@ -245,6 +249,100 @@ evdev_device_transform_y(struct evdev_de
+@@ -258,6 +262,100 @@ evdev_device_transform_y(struct evdev_de
        return scale_axis(device->abs.absinfo_y, y, height);
  }
  
@@ -572,7 +572,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  static inline void
  normalize_delta(struct evdev_device *device,
                const struct device_coords *delta,
-@@ -282,8 +380,15 @@ evdev_flush_pending_event(struct evdev_d
+@@ -295,8 +393,15 @@ evdev_flush_pending_event(struct evdev_d
        struct normalized_coords accel, unaccel;
        struct device_coords point;
        struct device_float_coords raw;
@@ -588,7 +588,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  
        switch (device->pending_event) {
        case EVDEV_NONE:
-@@ -324,7 +429,7 @@ evdev_flush_pending_event(struct evdev_d
+@@ -337,7 +442,7 @@ evdev_flush_pending_event(struct evdev_d
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
  
@@ -597,7 +597,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                        log_bug_kernel(libinput,
                                       "%s: Driver sent multiple touch down for 
the "
                                       "same slot",
-@@ -333,38 +438,50 @@ evdev_flush_pending_event(struct evdev_d
+@@ -346,38 +451,48 @@ evdev_flush_pending_event(struct evdev_d
                }
  
                seat_slot = ffs(~seat->slot_map) - 1;
@@ -610,7 +610,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                seat->slot_map |= 1 << seat_slot;
 -              point = device->mt.slots[slot].point;
 +              point = slot_data->point;
-               transform_absolute(device, &point);
+               evdev_transform_absolute(device, &point);
  
 -              touch_notify_touch_down(base, time, slot, seat_slot,
 -                                      &point);
@@ -629,16 +629,14 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
 -              seat_slot = device->mt.slots[slot].seat_slot;
 -              point = device->mt.slots[slot].point;
 +              seat_slot = slot_data->seat_slot;
-+
 +              point = slot_data->point;
  
                if (seat_slot == -1)
                        break;
  
-               transform_absolute(device, &point);
+               evdev_transform_absolute(device, &point);
 -              touch_notify_touch_motion(base, time, slot, seat_slot,
 -                                        &point);
-+
 +              touch_notify_touch_motion(base,
 +                                        time,
 +                                        slot,
@@ -658,9 +656,9 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  
                if (seat_slot == -1)
                        break;
-@@ -396,7 +513,13 @@ evdev_flush_pending_event(struct evdev_d
+@@ -409,7 +524,13 @@ evdev_flush_pending_event(struct evdev_d
                point = device->abs.point;
-               transform_absolute(device, &point);
+               evdev_transform_absolute(device, &point);
  
 -              touch_notify_touch_down(base, time, -1, seat_slot, &point);
 +              touch_notify_touch_down(base,
@@ -673,7 +671,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                break;
        case EVDEV_ABSOLUTE_MOTION:
                point = device->abs.point;
-@@ -408,8 +531,13 @@ evdev_flush_pending_event(struct evdev_d
+@@ -421,8 +542,13 @@ evdev_flush_pending_event(struct evdev_d
                        if (seat_slot == -1)
                                break;
  
@@ -689,7 +687,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                } else if (device->seat_caps & EVDEV_DEVICE_POINTER) {
                        pointer_notify_motion_absolute(base, time, &point);
                }
-@@ -583,8 +711,9 @@ evdev_process_touch(struct evdev_device
+@@ -596,8 +722,9 @@ evdev_process_touch(struct evdev_device
                    struct input_event *e,
                    uint64_t time)
  {
@@ -701,7 +699,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                if ((size_t)e->value >= device->mt.slots_len) {
                        log_bug_libinput(device->base.seat->libinput,
                                         "%s exceeds slots (%d of %zd)\n",
-@@ -595,8 +724,7 @@ evdev_process_touch(struct evdev_device
+@@ -608,8 +735,7 @@ evdev_process_touch(struct evdev_device
                }
                evdev_flush_pending_event(device, time);
                device->mt.slot = e->value;
@@ -711,7 +709,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                if (device->pending_event != EVDEV_NONE &&
                    device->pending_event != EVDEV_ABSOLUTE_MT_MOTION)
                        evdev_flush_pending_event(device, time);
-@@ -604,17 +732,34 @@ evdev_process_touch(struct evdev_device
+@@ -617,17 +743,34 @@ evdev_process_touch(struct evdev_device
                        device->pending_event = EVDEV_ABSOLUTE_MT_DOWN;
                else
                        device->pending_event = EVDEV_ABSOLUTE_MT_UP;
@@ -756,7 +754,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
        }
  }
  
-@@ -1969,6 +2114,20 @@ evdev_configure_mt_device(struct evdev_d
+@@ -1989,6 +2132,20 @@ evdev_configure_mt_device(struct evdev_d
                slots[slot].point.y = libevdev_get_slot_value(evdev,
                                                              slot,
                                                              
ABS_MT_POSITION_Y);
@@ -777,7 +775,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
        }
        device->mt.slots = slots;
        device->mt.slots_len = num_slots;
-@@ -2039,6 +2198,15 @@ evdev_configure_device(struct evdev_devi
+@@ -2060,6 +2217,15 @@ evdev_configure_device(struct evdev_devi
                return -1;
        }
  
@@ -795,7 +793,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  
 --- a/src/evdev.h
 +++ b/src/evdev.h
-@@ -113,6 +113,8 @@ enum evdev_device_model {
+@@ -119,6 +119,8 @@ enum evdev_device_model {
  struct mt_slot {
        int32_t seat_slot;
        struct device_coords point;
@@ -804,7 +802,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  };
  
  struct evdev_device {
-@@ -129,6 +131,8 @@ struct evdev_device {
+@@ -135,6 +137,8 @@ struct evdev_device {
        int fd;
        struct {
                const struct input_absinfo *absinfo_x, *absinfo_y;
@@ -813,7 +811,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
                int fake_resolution;
  
                struct device_coords point;
-@@ -350,6 +354,26 @@ double
+@@ -376,6 +380,26 @@ double
  evdev_device_transform_y(struct evdev_device *device,
                         double y,
                         uint32_t height);
@@ -854,7 +852,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  /*
   * A coordinate pair in device coordinates, capable of holding non discrete
   * values, this is necessary e.g. when device coordinates get averaged.
-@@ -396,14 +401,18 @@ touch_notify_touch_down(struct libinput_
+@@ -461,14 +466,18 @@ touch_notify_touch_down(struct libinput_
                        uint64_t time,
                        int32_t slot,
                        int32_t seat_slot,
@@ -877,7 +875,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  touch_notify_touch_up(struct libinput_device *device,
 --- a/src/libinput-util.h
 +++ b/src/libinput-util.h
-@@ -118,6 +118,12 @@ msleep(unsigned int ms)
+@@ -145,6 +145,12 @@ msleep(unsigned int ms)
        usleep(ms * 1000);
  }
  
@@ -901,7 +899,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  };
  
  struct libinput_event_gesture {
-@@ -732,6 +734,204 @@ libinput_event_touch_get_y(struct libinp
+@@ -758,6 +760,204 @@ libinput_event_touch_get_y(struct libinp
        return evdev_convert_to_mm(device->abs.absinfo_y, event->point.y);
  }
  
@@ -1106,7 +1104,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  LIBINPUT_EXPORT uint32_t
  libinput_event_gesture_get_time(struct libinput_event_gesture *event)
  {
-@@ -1512,7 +1712,9 @@ touch_notify_touch_down(struct libinput_
+@@ -2113,7 +2313,9 @@ touch_notify_touch_down(struct libinput_
                        uint64_t time,
                        int32_t slot,
                        int32_t seat_slot,
@@ -1117,7 +1115,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  {
        struct libinput_event_touch *touch_event;
  
-@@ -1528,6 +1730,8 @@ touch_notify_touch_down(struct libinput_
+@@ -2129,6 +2331,8 @@ touch_notify_touch_down(struct libinput_
                .slot = slot,
                .seat_slot = seat_slot,
                .point = *point,
@@ -1126,7 +1124,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
        };
  
        post_device_event(device, time,
-@@ -1540,7 +1744,9 @@ touch_notify_touch_motion(struct libinpu
+@@ -2141,7 +2345,9 @@ touch_notify_touch_motion(struct libinpu
                          uint64_t time,
                          int32_t slot,
                          int32_t seat_slot,
@@ -1137,7 +1135,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  {
        struct libinput_event_touch *touch_event;
  
-@@ -1556,6 +1762,8 @@ touch_notify_touch_motion(struct libinpu
+@@ -2157,6 +2363,8 @@ touch_notify_touch_motion(struct libinpu
                .slot = slot,
                .seat_slot = seat_slot,
                .point = *point,
@@ -1148,7 +1146,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
        post_device_event(device, time,
 --- a/src/libinput.h
 +++ b/src/libinput.h
-@@ -968,6 +968,228 @@ libinput_event_touch_get_y_transformed(s
+@@ -1151,6 +1151,228 @@ libinput_event_touch_get_y_transformed(s
  /**
   * @ingroup event_touch
   *
@@ -1379,7 +1377,7 @@ Signed-off-by: Andreas Pokorny 
<[email protected]>
  struct libinput_event *
 --- a/src/libinput.sym
 +++ b/src/libinput.sym
-@@ -173,6 +173,19 @@ LIBINPUT_0.21.0 {
+@@ -174,6 +174,19 @@ LIBINPUT_0.21.0 {
        libinput_event_touch_get_time_usec;
  } LIBINPUT_0.20.0;
  

commit 371db78d35361ec5b0f5b2c1d3b4c6862c317bd6
Author: Timo Aaltonen <[email protected]>
Date:   Thu Mar 17 10:55:12 2016 +0200

    release to unstable

diff --git a/debian/changelog b/debian/changelog
index f092320..f32c177 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libinput (1.2.2-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Timo Aaltonen <[email protected]>  Thu, 17 Mar 2016 10:49:19 +0200
+
 libinput (1.2.0-1) unstable; urgency=medium
 
   * New upstream release.

commit ae7b2f77720f19ce3b6924bb3ecf706cabd17587
Author: Peter Hutterer <[email protected]>
Date:   Tue Mar 15 10:23:42 2016 +1000

    configure.ac: libinput 1.2.2
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/configure.ac b/configure.ac
index 71255ed..7d73183 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.64])
 
 m4_define([libinput_major_version], [1])
 m4_define([libinput_minor_version], [2])
-m4_define([libinput_micro_version], [1])
+m4_define([libinput_micro_version], [2])
 m4_define([libinput_version],
           
[libinput_major_version.libinput_minor_version.libinput_micro_version])
 
@@ -31,7 +31,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
 # b) If interfaces have been changed or added, but binary compatibility has
 #    been preserved, change to C+1:0:A+1
 # c) If the interface is the same as the previous version, change to C:R+1:A
-LIBINPUT_LT_VERSION=17:3:7
+LIBINPUT_LT_VERSION=17:4:7
 AC_SUBST(LIBINPUT_LT_VERSION)
 
 AM_SILENT_RULES([yes])

commit a608d9dc2c70c7915fc94466ed27c1684f65409e
Author: Peter Hutterer <[email protected]>
Date:   Mon Mar 7 16:05:25 2016 +1000

    touchpad: add quirk for the T450 and T460 generation hardware
    
    The touchpad's sensors are too far apart (or the firmware interferes), 
causing
    in a jerky movement visible especially on slow motion. We get a bunch of
    normal motion events, then only ABS_MT_PRESSURE updates without x/y updates.
    After about one mm of movement x/y updates resume, with the first event
    covering the distance between the last motion event. That event is usually
    accelerated and thus causes a large jump. Subsequent events are sufficiently
    fine-grained again.
    
    This patch counts the number of non-motion events. Once we hit 10 in a row, 
we
    mark the first motion update as non-dirty, effectively discarding the motion
    and thus stopping the pointer jumps.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=94379
    
    Signed-off-by: Peter Hutterer <[email protected]>
    Tested-by: Benjamin Tissoires <[email protected]>

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 00d6539..d0a8e27 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -337,7 +337,7 @@ tp_process_absolute(struct tp_dispatch *tp,
        case ABS_MT_PRESSURE:
                t->pressure = e->value;
                t->dirty = true;
-               tp->queued |= TOUCHPAD_EVENT_MOTION;
+               tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
                break;
        }
 }
@@ -880,8 +880,10 @@ tp_position_fake_touches(struct tp_dispatch *tp)
 }
 
 static inline bool
-tp_need_motion_history_reset(struct tp_dispatch *tp)
+tp_need_motion_history_reset(struct tp_dispatch *tp, uint64_t time)
 {
+       bool rc = false;
+
        /* semi-mt finger postions may "jump" when nfingers changes */
        if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
                return true;
@@ -894,7 +896,29 @@ tp_need_motion_history_reset(struct tp_dispatch *tp)
                 tp->old_nfingers_down > tp->num_slots))
                return true;
 
-       return false;
+       /* Quirk: if we had multiple events without x/y axis
+          information, the next x/y event is going to be a jump. So we
+          reset that touch to non-dirty effectively swallowing that event
+          and restarting with the next event again.
+        */
+       if (tp->device->model_flags & EVDEV_MODEL_LENOVO_T450_TOUCHPAD) {
+               if (tp->queued & TOUCHPAD_EVENT_MOTION) {
+                       if (tp->quirks.nonmotion_event_count > 10) {
+                               struct tp_touch *t;
+
+                               tp_for_each_touch(tp, t)
+                               t->dirty = false;
+                               rc = true;
+                       }
+                       tp->quirks.nonmotion_event_count = 0;
+               }
+
+               if ((tp->queued & 
(TOUCHPAD_EVENT_OTHERAXIS|TOUCHPAD_EVENT_MOTION)) ==
+                   TOUCHPAD_EVENT_OTHERAXIS)
+                       tp->quirks.nonmotion_event_count++;
+       }
+
+       return rc;
 }
 
 static void
@@ -909,7 +933,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
        tp_unhover_touches(tp, time);
        tp_position_fake_touches(tp);
 
-       want_motion_reset = tp_need_motion_history_reset(tp);
+       want_motion_reset = tp_need_motion_history_reset(tp, time);
 
        for (i = 0; i < tp->ntouches; i++) {
                t = tp_get_touch(tp, i);
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index eae327b..1f05a03 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -41,6 +41,7 @@ enum touchpad_event {
        TOUCHPAD_EVENT_MOTION           = (1 << 0),
        TOUCHPAD_EVENT_BUTTON_PRESS     = (1 << 1),
        TOUCHPAD_EVENT_BUTTON_RELEASE   = (1 << 2),
+       TOUCHPAD_EVENT_OTHERAXIS        = (1 << 3),
 };
 
 enum touchpad_model {
@@ -353,6 +354,17 @@ struct tp_dispatch {
                int upper_thumb_line;
                int lower_thumb_line;
        } thumb;
+
+       struct {
+               /* A quirk used on the T450 series Synaptics hardware.
+                * Slowly moving the finger causes multiple events with only
+                * ABS_MT_PRESSURE but no x/y information. When the x/y
+                * event comes, it will be a jump of ~20 units. We use the
+                * below to count non-motion events to discard that first
+                * event with the jump.
+                */
+               unsigned int nonmotion_event_count;
+       } quirks;
 };
 
 #define tp_for_each_touch(_tp, _t) \
diff --git a/src/evdev.c b/src/evdev.c
index 51768fe..a5c965d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1680,6 +1680,7 @@ evdev_read_model_flags(struct evdev_device *device)
                { "LIBINPUT_MODEL_CYBORG_RAT", EVDEV_MODEL_CYBORG_RAT },
                { "LIBINPUT_MODEL_CYAPA", EVDEV_MODEL_CYAPA },
                { "LIBINPUT_MODEL_ALPS_RUSHMORE", EVDEV_MODEL_ALPS_RUSHMORE },
+               { "LIBINPUT_MODEL_LENOVO_T450_TOUCHPAD", 
EVDEV_MODEL_LENOVO_T450_TOUCHPAD },
                { NULL, EVDEV_MODEL_DEFAULT },
        };
        const struct model_map *m = model_map;
diff --git a/src/evdev.h b/src/evdev.h
index 482712b..4a5d807 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -113,6 +113,7 @@ enum evdev_device_model {
        EVDEV_MODEL_CYBORG_RAT = (1 << 14),
        EVDEV_MODEL_CYAPA = (1 << 15),
        EVDEV_MODEL_ALPS_RUSHMORE = (1 << 16),
+       EVDEV_MODEL_LENOVO_T450_TOUCHPAD= (1 << 17),
 };
 
 struct mt_slot {
diff --git a/udev/90-libinput-model-quirks.hwdb 
b/udev/90-libinput-model-quirks.hwdb
index eb2859e..d5978f7 100644
--- a/udev/90-libinput-model-quirks.hwdb
+++ b/udev/90-libinput-model-quirks.hwdb
@@ -100,6 +100,13 @@ libinput:name:Cypress APA Trackpad (cyapa):dmi:*
 libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX230*
  LIBINPUT_MODEL_LENOVO_X230=1
 
+# Lenovo T450/T460 and all other Lenovos of the *50 and *60 generation,
+# including the X1 Carbon 3rd gen
+libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??50*:
+libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??60*:
+libinput:name:SynPS/2 Synaptics 
TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX1Carbon3rd:*
+ LIBINPUT_MODEL_LENOVO_T450_TOUCHPAD=1
+
 ##########################################
 # Synaptics
 ##########################################

commit 5d904b63191538b46d7fe8443990b55c42de0205
Author: Peter Hutterer <[email protected]>
Date:   Mon Mar 7 10:12:13 2016 +1000

    tablet: reject mislabelled tablet devices
    
    The HUION 580 has a "consumer control" event node that has an ABS_VOLUME, 
keys
    and a REL_HWHEEL. It has the same VID/PID as the pen tablet and libwacom
    labels it as ID_INPUT_TABLET. This causes a crash later when we try to init
    pointer acceleration for a device that doesn't have axes.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1314955
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 0f6fa2c..7359881 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -1613,6 +1613,31 @@ tablet_init_left_handed(struct evdev_device *device)
 }
 
 static int
+tablet_reject_device(struct evdev_device *device)
+{
+       struct libevdev *evdev = device->evdev;
+       int rc = -1;
+
+       if (!libevdev_has_event_code(evdev, EV_ABS, ABS_X) ||
+           !libevdev_has_event_code(evdev, EV_ABS, ABS_Y))
+               goto out;
+
+       if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN))
+               goto out;
+
+       rc = 0;
+
+out:
+       if (rc) {
+               log_bug_libinput(device->base.seat->libinput,
+                                "Device '%s' does not meet tablet criteria. "
+                                "Ignoring this device.\n",
+                                device->devname);
+       }
+       return rc;
+}
+
+static int
 tablet_init(struct tablet_dispatch *tablet,
            struct evdev_device *device)
 {
@@ -1625,6 +1650,9 @@ tablet_init(struct tablet_dispatch *tablet,
        tablet->current_tool_type = LIBINPUT_TOOL_NONE;
        list_init(&tablet->tool_list);
 
+       if (tablet_reject_device(device))
+               return -1;
+
        tablet_init_calibration(tablet, device);
        tablet_init_proximity_threshold(tablet, device);
        rc = tablet_init_accel(tablet, device);

commit b4a74bcebc8f1d37b2ed78db3440435ead03299a
Author: Peter Hutterer <[email protected]>
Date:   Fri Mar 4 07:50:49 2016 +1000

    Assert that the interface is actually filled in.
    
    Had this in a private bug report recently. Missing hooks for open/close just
    segfault with little information to debug. Add an assert, this is 
definitely a
    bug in the caller and we don't need to recover from that.
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/src/libinput.c b/src/libinput.c
index 3c78905..1480878 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -1517,6 +1517,9 @@ libinput_init(struct libinput *libinput,
              const struct libinput_interface_backend *interface_backend,
              void *user_data)
 {
+       assert(interface->open_restricted != NULL);
+       assert(interface->close_restricted != NULL);
+
        libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);;
        if (libinput->epoll_fd < 0)
                return -1;
diff --git a/test/udev.c b/test/udev.c
index 30ae118..9296e94 100644
--- a/test/udev.c
+++ b/test/udev.c
@@ -52,7 +52,6 @@ const struct libinput_interface simple_interface = {
 START_TEST(udev_create_NULL)
 {
        struct libinput *li;
-       const struct libinput_interface interface;
        struct udev *udev;
 
        udev = udev_new();
@@ -60,13 +59,13 @@ START_TEST(udev_create_NULL)
        li = libinput_udev_create_context(NULL, NULL, NULL);
        ck_assert(li == NULL);
 
-       li = libinput_udev_create_context(&interface, NULL, NULL);
+       li = libinput_udev_create_context(&simple_interface, NULL, NULL);
        ck_assert(li == NULL);
 
        li = libinput_udev_create_context(NULL, NULL, udev);
        ck_assert(li == NULL);
 
-       li = libinput_udev_create_context(&interface, NULL, udev);
+       li = libinput_udev_create_context(&simple_interface, NULL, udev);
        ck_assert(li != NULL);
        ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1);
 

commit 00a9b05da71c9071cc910a1c5975165f2a8db9c6
Author: Peter Hutterer <[email protected]>
Date:   Thu Mar 3 08:33:22 2016 +1000

    test: add two path tests for invalid devices
    
    One test for an actual file (so far we only tested /tmp, the directory) and
    one for a kernel dev that returns a udev device and thus gets one step 
further
    in the error handling code.
    
    Plus, I saw test code doing this (opening /dev/uinput) and it crashed (for
    other reasons), so we might as well test it.
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/test/path.c b/test/path.c
index 0b04b19..7d7c445 100644
--- a/test/path.c
+++ b/test/path.c
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <libinput.h>
+#include <stdio.h>
 #include <unistd.h>
 
 #include "litest.h"
@@ -98,6 +99,63 @@ START_TEST(path_create_invalid)
 }
 END_TEST
 
+START_TEST(path_create_invalid_kerneldev)
+{
+       struct libinput *li;
+       struct libinput_device *device;
+       const char *path = "/dev/uinput";
+
+       open_func_count = 0;
+       close_func_count = 0;
+
+       li = libinput_path_create_context(&simple_interface, NULL);
+       ck_assert(li != NULL);
+       device = libinput_path_add_device(li, path);
+       ck_assert(device == NULL);
+
+       ck_assert_int_eq(open_func_count, 1);
+       ck_assert_int_eq(close_func_count, 1);
+
+       libinput_unref(li);
+       ck_assert_int_eq(close_func_count, 1);
+
+       open_func_count = 0;
+       close_func_count = 0;
+}
+END_TEST
+
+START_TEST(path_create_invalid_file)
+{
+       struct libinput *li;
+       struct libinput_device *device;
+       char path[] = "/tmp/litest_path_XXXXXX";
+       int fd;
+
+       fd = mkstemp(path);
+       ck_assert_int_ge(fd, 0);
+       close(fd);
+
+       open_func_count = 0;
+       close_func_count = 0;
+
+       li = libinput_path_create_context(&simple_interface, NULL);
+       unlink(path);
+
+       ck_assert(li != NULL);
+       device = libinput_path_add_device(li, path);
+       ck_assert(device == NULL);
+
+       ck_assert_int_eq(open_func_count, 0);
+       ck_assert_int_eq(close_func_count, 0);
+
+       libinput_unref(li);
+       ck_assert_int_eq(close_func_count, 0);
+
+       open_func_count = 0;
+       close_func_count = 0;
+}
+END_TEST
+
 START_TEST(path_create_destroy)
 {
        struct libinput *li;
@@ -882,6 +940,8 @@ litest_setup_tests(void)
 {
        litest_add_no_device("path:create", path_create_NULL);
        litest_add_no_device("path:create", path_create_invalid);
+       litest_add_no_device("path:create", path_create_invalid_file);
+       litest_add_no_device("path:create", path_create_invalid_kerneldev);
        litest_add_no_device("path:create", path_create_destroy);
        litest_add_no_device("path:create", path_set_user_data);
        litest_add_no_device("path:suspend", path_suspend);

commit a60afbeec39f7de4a03103dab26701b506dc93d0
Author: Peter Hutterer <[email protected]>
Date:   Wed Mar 2 11:48:59 2016 +1000

    touchpad: use the udev property over a compile-time vendor ID check
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 95d650a..00d6539 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1299,7 +1299,7 @@ tp_dwt_device_is_blacklisted(struct evdev_device *device)
                return true;
 
        /* Wacom makes touchpads, but not internal ones */
-       if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_WACOM)
+       if (device->model_flags & EVDEV_MODEL_WACOM_TOUCHPAD)
                return true;
 
        return false;

commit 2bb0678a00f9c089dc865d6ecd20be36446d1c06
Author: Peter Hutterer <[email protected]>
Date:   Wed Feb 10 09:24:51 2016 +1000

    tablet: sanitize button mask passing
    
    We have a struct, use it. Better than passing arrays and array lengths 
around.
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 22ea1eb..0f6fa2c 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -38,34 +38,27 @@
 
 static inline void
 tablet_get_pressed_buttons(struct tablet_dispatch *tablet,
-                          unsigned char *buttons,
-                          unsigned int buttons_len)
+                          struct button_state *buttons)
 {
        size_t i;
        const struct button_state *state = &tablet->button_state,
                                  *prev_state = &tablet->prev_button_state;
 
-       assert(buttons_len <= ARRAY_LENGTH(state->stylus_buttons));
-
-       for (i = 0; i < buttons_len; i++)
-               buttons[i] = state->stylus_buttons[i] &
-                                       ~(prev_state->stylus_buttons[i]);
+       for (i = 0; i < sizeof(buttons->bits); i++)
+               buttons->bits[i] = state->bits[i] & ~(prev_state->bits[i]);
 }
 
 static inline void
 tablet_get_released_buttons(struct tablet_dispatch *tablet,
-                           unsigned char *buttons,
-                           unsigned int buttons_len)
+                           struct button_state *buttons)
 {
        size_t i;
        const struct button_state *state = &tablet->button_state,
                                  *prev_state = &tablet->prev_button_state;
 
-       assert(buttons_len <= ARRAY_LENGTH(state->stylus_buttons));
-
-       for (i = 0; i < buttons_len; i++)
-               buttons[i] = prev_state->stylus_buttons[i] &
-                                       ~(state->stylus_buttons[i]);
+       for (i = 0; i < sizeof(buttons->bits); i++)
+               buttons->bits[i] = prev_state->bits[i] &
+                                       ~(state->bits[i]);
 }
 
 /* Merge the previous state with the current one so all buttons look like
@@ -77,10 +70,9 @@ tablet_force_button_presses(struct tablet_dispatch *tablet)
                            *prev_state = &tablet->prev_button_state;
        size_t i;
 
-       for (i = 0; i < sizeof(state->stylus_buttons); i++) {
-               state->stylus_buttons[i] = state->stylus_buttons[i] |
-                                               prev_state->stylus_buttons[i];
-               prev_state->stylus_buttons[i] = 0;
+       for (i = 0; i < sizeof(state->bits); i++) {
+               state->bits[i] = state->bits[i] | prev_state->bits[i];
+               prev_state->bits[i] = 0;
        }
 }
 
@@ -566,10 +558,10 @@ tablet_update_button(struct tablet_dispatch *tablet,
        }
 
        if (enable) {
-               set_bit(tablet->button_state.stylus_buttons, evcode);
+               set_bit(tablet->button_state.bits, evcode);
                tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
        } else {
-               clear_bit(tablet->button_state.stylus_buttons, evcode);
+               clear_bit(tablet->button_state.bits, evcode);
                tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
        }
 }
@@ -936,20 +928,19 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet,
                          struct evdev_device *device,
                          uint64_t time,
                          struct libinput_tablet_tool *tool,
-                         const unsigned char *buttons,
-                         unsigned int buttons_len,
+                         const struct button_state *buttons,
                          enum libinput_button_state state)
 {
        struct libinput_device *base = &device->base;
        size_t i;
-       size_t nbits = 8 * sizeof(buttons[0]) * buttons_len;
+       size_t nbits = 8 * sizeof(buttons->bits);
        enum libinput_tablet_tool_tip_state tip_state;
 
        tip_state = tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT) ?
                        LIBINPUT_TABLET_TOOL_TIP_DOWN : 
LIBINPUT_TABLET_TOOL_TIP_UP;
 
        for (i = 0; i < nbits; i++) {
-               if (!bit_is_set(buttons, i))
+               if (!bit_is_set(buttons->bits, i))
                        continue;
 
                tablet_notify_button(base,
@@ -969,21 +960,18 @@ tablet_notify_buttons(struct tablet_dispatch *tablet,
                      struct libinput_tablet_tool *tool,
                      enum libinput_button_state state)
 {
-       unsigned char 
buttons[ARRAY_LENGTH(tablet->button_state.stylus_buttons)];
+       struct button_state buttons;
 
        if (state == LIBINPUT_BUTTON_STATE_PRESSED)
-               tablet_get_pressed_buttons(tablet, buttons, sizeof(buttons));
+               tablet_get_pressed_buttons(tablet, &buttons);
        else
-               tablet_get_released_buttons(tablet,
-                                           buttons,
-                                           sizeof(buttons));
+               tablet_get_released_buttons(tablet, &buttons);
 
        tablet_notify_button_mask(tablet,
                                  device,
                                  time,
                                  tool,
-                                 buttons,
-                                 sizeof(buttons),
+                                 &buttons,
                                  state);
 }
 
@@ -1332,9 +1320,9 @@ tablet_flush(struct tablet_dispatch *tablet,
 
        if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
                /* Release all stylus buttons */
-               memset(tablet->button_state.stylus_buttons,
+               memset(tablet->button_state.bits,
                       0,
-                      sizeof(tablet->button_state.stylus_buttons));
+                      sizeof(tablet->button_state.bits));
                tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
                if (tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT))
                        tablet_set_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
index 1d6fc93..880d523 100644
--- a/src/evdev-tablet.h
+++ b/src/evdev-tablet.h
@@ -45,7 +45,7 @@ enum tablet_status {
 };
 
 struct button_state {
-       unsigned char stylus_buttons[NCHARS(KEY_CNT)];
+       unsigned char bits[NCHARS(KEY_CNT)];
 };
 
 struct tablet_dispatch {

commit 21fe11fb11a4d79aabb208f5839679a52a74678b
Author: Peter Hutterer <[email protected]>
Date:   Fri Feb 26 15:19:57 2016 +1000

    configure.ac: libinput 1.2.1
    
    Signed-off-by: Peter Hutterer <[email protected]>

diff --git a/configure.ac b/configure.ac
index d400f21..71255ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.64])
 
 m4_define([libinput_major_version], [1])

Reply via email to