[PATCH libinput 7/7] touchpad: sync the initial touch state

Benjamin Tissoires benjamin.tissoires at gmail.com
Wed May 20 13:32:27 PDT 2015


On Tue, May 19, 2015 at 6:52 PM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> Unlikely, but there's the odd chance of the first touch coming in with the
> same X or Y coordinate the kernel already has internally. This would
> generate a bogus delta on the second event when the touch coordinate jumps
> from 0/y or x/0 to the real coordinates.
>
> For touchpads with distance support this is a real issue since the default
> value for a touch distance is > 0.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---

The series is:
Tested-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>

Cheers,
Benjamin

>  src/evdev-mt-touchpad.c | 28 ++++++++++++++++++++++
>  test/touchpad.c         | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+)
>
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index 026f9ee..409d81e 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -1087,6 +1087,28 @@ tp_init_touch(struct tp_dispatch *tp,
>         t->has_ended = true;
>  }
>
> +static void
> +tp_sync_touch(struct tp_dispatch *tp,
> +             struct evdev_device *device,
> +             struct tp_touch *t,
> +             int slot)
> +{
> +       struct libevdev *evdev = device->evdev;
> +
> +       if (!libevdev_fetch_slot_value(evdev,
> +                                      slot,
> +                                      ABS_MT_POSITION_X,
> +                                      &t->point.x))
> +               t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
> +       if (!libevdev_fetch_slot_value(evdev,
> +                                      slot,
> +                                      ABS_MT_POSITION_Y,
> +                                      &t->point.y))
> +               t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
> +
> +       libevdev_fetch_slot_value(evdev, slot, ABS_MT_DISTANCE, &t->distance);
> +}
> +
>  static int
>  tp_init_slots(struct tp_dispatch *tp,
>               struct evdev_device *device)
> @@ -1134,6 +1156,12 @@ tp_init_slots(struct tp_dispatch *tp,
>         for (i = 0; i < tp->ntouches; i++)
>                 tp_init_touch(tp, &tp->touches[i]);
>
> +       /* Always sync the first touch so we get ABS_X/Y synced on
> +        * single-touch touchpads */
> +       tp_sync_touch(tp, device, &tp->touches[0], 0);
> +       for (i = 1; i < tp->num_slots; i++)
> +               tp_sync_touch(tp, device, &tp->touches[i], i);
> +
>         return 0;
>  }
>
> diff --git a/test/touchpad.c b/test/touchpad.c
> index f7f9dd5..3bdcc2b 100644
> --- a/test/touchpad.c
> +++ b/test/touchpad.c
> @@ -4530,9 +4530,69 @@ START_TEST(touchpad_trackpoint_no_trackpoint)
>  }
>  END_TEST
>
> +START_TEST(touchpad_initial_state)
> +{
> +       struct litest_device *dev;
> +       struct libinput *libinput1, *libinput2;
> +       struct libinput_event *ev1, *ev2;
> +       struct libinput_event_pointer *p1, *p2;
> +       int axis = _i; /* looped test */
> +       int x = 40, y = 60;
> +
> +       dev = litest_current_device();
> +       libinput1 = dev->libinput;
> +
> +       libinput_device_config_tap_set_enabled(dev->libinput_device,
> +                                              LIBINPUT_CONFIG_TAP_DISABLED);
> +
> +       litest_touch_down(dev, 0, x, y);
> +       litest_touch_up(dev, 0);
> +
> +       /* device is now on some x/y value */
> +       litest_drain_events(libinput1);
> +
> +       libinput2 = litest_create_context();
> +       libinput_path_add_device(libinput2,
> +                                libevdev_uinput_get_devnode(dev->uinput));
> +       litest_drain_events(libinput2);
> +
> +       if (axis == ABS_X)
> +               x = 30;
> +       else
> +               y = 30;
> +       litest_touch_down(dev, 0, x, y);
> +       litest_touch_move_to(dev, 0, x, y, 80, 80, 10, 1);
> +       litest_touch_up(dev, 0);
> +
> +       litest_wait_for_event(libinput1);
> +       litest_wait_for_event(libinput2);
> +
> +       while (libinput_next_event_type(libinput1)) {
> +               ev1 = libinput_get_event(libinput1);
> +               ev2 = libinput_get_event(libinput2);
> +
> +               p1 = litest_is_motion_event(ev1);
> +               p2 = litest_is_motion_event(ev2);
> +
> +               ck_assert_int_eq(libinput_event_get_type(ev1),
> +                                libinput_event_get_type(ev2));
> +
> +               ck_assert_int_eq(libinput_event_pointer_get_dx(p1),
> +                                libinput_event_pointer_get_dx(p2));
> +               ck_assert_int_eq(libinput_event_pointer_get_dy(p1),
> +                                libinput_event_pointer_get_dy(p2));
> +               libinput_event_destroy(ev1);
> +               libinput_event_destroy(ev2);
> +       }
> +
> +       libinput_unref(libinput2);
> +}
> +END_TEST
> +
>  int main(int argc, char **argv)
>  {
>         struct range multitap_range = {3, 8};
> +       struct range axis_range = {ABS_X, ABS_Y + 1};
>
>         litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY);
>         litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
> @@ -4675,5 +4735,7 @@ int main(int argc, char **argv)
>         litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_buttons_2fg_scroll, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
>         litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_no_trackpoint, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
>
> +       litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
> +
>         return litest_run(argc, argv);
>  }
> --
> 2.3.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list