[PATCH libinput] tablet: always enable the no-proximity-out quirk on HUION tablets

Benjamin Tissoires benjamin.tissoires at gmail.com
Wed Sep 20 16:38:25 UTC 2017


On Wed, Sep 20, 2017 at 3:40 AM, Peter Hutterer <peter.hutterer at who-t.net>
wrote:

> And instead disable it when we do get a proximity out.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>

This looks good to me:
Reviewed-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>

Cheers,
Benjamin


> Follow-up to
> https://lists.freedesktop.org/archives/wayland-devel/2017-
> September/035006.html
> While writing some more documentation for it, I realised it's easier to
> just
> enable this on all HUION tablets and auto-disable it on those that support
> real proximity out. Much better than having the user drop a hwdb file and
> hope it works.
>
>  doc/device-configuration-via-udev.dox  | 19 --------
>  src/evdev-tablet.c                     | 15 +++++-
>  src/evdev-tablet.h                     |  3 ++
>  test/test-tablet.c                     | 87 ++++++++++++++++++++++++++++++
> ++++
>  udev/90-libinput-model-quirks.hwdb     | 13 ++---
>  udev/90-libinput-model-quirks.rules.in |  4 ++
>  udev/parse_hwdb.py                     |  2 +-
>  7 files changed, 112 insertions(+), 31 deletions(-)
>
> diff --git a/doc/device-configuration-via-udev.dox
> b/doc/device-configuration-via-udev.dox
> index 3050cd80..2ebfa321 100644
> --- a/doc/device-configuration-via-udev.dox
> +++ b/doc/device-configuration-via-udev.dox
> @@ -162,23 +162,4 @@ model quirks hwdb for instructions.
>  This property must not be used for any other purpose, no specific behavior
>  is guaranteed.
>
> - at subsection model_specific_configuration_huion_tablets Graphics tablets
> without BTN_TOOL_PEN proximity events
> -
> -On graphics tablets, the <b>BTN_TOOL_PEN</b> bit signals that the pen is
> in
> -detectable range and will send events. When the pen leaves the sensor
> range,
> -the bit must be unset to signal that the tablet is out of proximity again.
> -Some HUION PenTablet devices are buggy and do not send this event. To a
> -caller, it thus looks like the pen is constantly in proximity. This causes
> -unexpected behavior in applications that rely on tablet device proximity.
> -
> -The property <b>LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT</b> may be set
> -by a user in a local hwdb file. This property designates the tablet
> -to be buggy and that libinput should work around this bug.
> -
> -Many of the affected tablets cannot be detected automatically by libinput
> -because HUION tablets reuse USB IDs.  Local configuration is required to
> set
> -this property. Refer to the libinput model quirks hwdb for instructions.
> -
> -This property must not be used for any other purpose, no specific behavior
> -is guaranteed.
>  */
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index 7e9281d1..21501c2b 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -1667,12 +1667,14 @@ tablet_proximity_out_quirk_timer_func(uint64_t
> now, void *data)
>                 return;
>         }
>
> +       tablet->quirks.proximity_out_in_progress = true;
>         ARRAY_FOR_EACH(events, e) {
>                 tablet->base.interface->process(&tablet->base,
>                                                  tablet->device,
>                                                  e,
>                                                  now);
>         }
> +       tablet->quirks.proximity_out_in_progress = false;
>
>         tablet->quirks.proximity_out_forced = true;
>  }
> @@ -1721,10 +1723,19 @@ tablet_proximity_out_quirk_update(struct
> tablet_dispatch *tablet,
>                 }
>                 tablet->quirks.last_event_time = time;
>         } else if (e->type == EV_KEY && e->code == BTN_TOOL_PEN) {
> -               if (e->value)
> +               if (e->value) {
>                         tablet_proximity_out_quirk_set_timer(tablet,
> time);
> -               else
> +               } else {
> +                       /* If we get a BTN_TOOL_PEN 0 when *not* injecting
> +                        * events it means the tablet will give us the
> right
> +                        * events after all and we can disable our
> +                        * timer-based proximity out.
> +                        */
> +                       if (!tablet->quirks.proximity_out_in_progress)
> +                               tablet->quirks.need_to_force_prox_out =
> false;
> +
>                         libinput_timer_cancel(&tablet-
> >quirks.prox_out_timer);
> +               }
>         }
>  }
>
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index ba05e88c..bf5a3dc1 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -89,6 +89,9 @@ struct tablet_dispatch {
>                 struct libinput_timer prox_out_timer;
>                 bool proximity_out_forced;
>                 uint64_t last_event_time;
> +
> +               /* true while injecting BTN_TOOL_PEN events */
> +               bool proximity_out_in_progress;
>         } quirks;
>  };
>
> diff --git a/test/test-tablet.c b/test/test-tablet.c
> index 66b4f79c..92fd45b9 100644
> --- a/test/test-tablet.c
> +++ b/test/test-tablet.c
> @@ -4445,9 +4445,95 @@ START_TEST(huion_static_btn_
> tool_pen_no_timeout_during_usage)
>  }
>  END_TEST
>
> +START_TEST(huion_static_btn_tool_pen_disable_quirk_on_prox_out)
> +{
> +       struct litest_device *dev = litest_current_device();
> +       struct libinput *li = dev->libinput;
> +       bool with_timeout = _i; /* ranged test */
> +       int i;
> +
> +       /* test is run twice, once where the real BTN_TOOL_PEN is triggered
> +        * during proximity out, one where the real BTN_TOOL_PEN is
> +        * triggered after we already triggered the quirk timeout
> +        */
> +
> +       litest_drain_events(li);
> +
> +       litest_event(dev, EV_ABS, ABS_X, 20000);
> +       litest_event(dev, EV_ABS, ABS_Y, 20000);
> +       litest_event(dev, EV_ABS, ABS_PRESSURE, 100);
> +       litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       litest_drain_events(li);
> +
> +       for (i = 0; i < 10; i++) {
> +               litest_event(dev, EV_ABS, ABS_X, 20000 + 10 * i);
> +               litest_event(dev, EV_ABS, ABS_Y, 20000 - 10 * i);
> +               litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +               libinput_dispatch(li);
> +       }
> +       litest_assert_only_typed_events(li,
> +                                       LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +
> +       /* Wait past the timeout to expect a proximity out */
> +       if (with_timeout) {
> +               litest_timeout_tablet_proxout();
> +               libinput_dispatch(li);
> +               litest_assert_tablet_proximity_event(li,
> +                                                    LIBINPUT_TABLET_TOOL_
> PROXIMITY_STATE_OUT);
> +       }
> +
> +       /* Send a real prox out, expect quirk to be disabled */
> +       litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       libinput_dispatch(li);
> +
> +       if (with_timeout) {
> +               /* we got the proximity event above already */
> +               litest_assert_empty_queue(li);
> +       } else {
> +               litest_assert_tablet_proximity_event(li,
> +                                                    LIBINPUT_TABLET_TOOL_
> PROXIMITY_STATE_OUT);
> +       }
> +
> +       litest_push_event_frame(dev);
> +       litest_tablet_proximity_out(dev);
> +       litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       litest_pop_event_frame(dev);
> +
> +       litest_tablet_proximity_in(dev, 50, 50, NULL);
> +       libinput_dispatch(li);
> +       litest_assert_tablet_proximity_event(li,
> +                            LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
> +       libinput_dispatch(li);
> +
> +       for (i = 0; i < 10; i++) {
> +               litest_tablet_motion(dev, 50 + i, 50 + i, NULL);
> +               libinput_dispatch(li);
> +       }
> +
> +       litest_assert_only_typed_events(li,
> +                                       LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +
> +       litest_push_event_frame(dev);
> +       litest_tablet_proximity_out(dev);
> +       litest_event(dev, EV_KEY, BTN_TOOL_PEN, 0);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       litest_pop_event_frame(dev);
> +       libinput_dispatch(li);
> +
> +       litest_assert_tablet_proximity_event(li,
> +                            LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT);
> +       litest_assert_empty_queue(li);
> +}
> +END_TEST
> +
>  void
>  litest_setup_tests_tablet(void)
>  {
> +       struct range with_timeout = { 0, 2 };
> +
>         litest_add("tablet:tool", tool_ref, LITEST_TABLET |
> LITEST_TOOL_SERIAL, LITEST_ANY);
>         litest_add("tablet:tool", tool_user_data, LITEST_TABLET |
> LITEST_TOOL_SERIAL, LITEST_ANY);
>         litest_add("tablet:tool", tool_capability, LITEST_TABLET,
> LITEST_ANY);
> @@ -4543,4 +4629,5 @@ litest_setup_tests_tablet(void)
>
>         litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen,
> LITEST_HUION_TABLET);
>         litest_add_for_device("tablet:quirks",
> huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);
> +       litest_add_ranged_for_device("tablet:quirks",
> huion_static_btn_tool_pen_disable_quirk_on_prox_out, LITEST_HUION_TABLET,
> &with_timeout);
>  }
> diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-
> quirks.hwdb
> index 867ffa53..6525b800 100644
> --- a/udev/90-libinput-model-quirks.hwdb
> +++ b/udev/90-libinput-model-quirks.hwdb
> @@ -171,15 +171,10 @@ libinput:name:AlpsPS/2 ALPS GlidePoint:dmi:*svnHP:
> pnHPZBookStudioG3:*
>  # matching BTN_TOOL_PEN value 0 event. The device appears as if it was
>  # permanently in proximity.
>  #
> -# If the tablet is affected by this bug, copy the two lines below into a
> new
> -# file
> -# /etc/udev/hwdb.d/90-libinput-huion-pentablet-proximity-quirk.hwdb,
> then run
> -# sudo udevadm hwdb --update and reboot.
> -#
> -# Note that HUION re-uses USB IDs for its devices, not ever HUION tablet
> is
> -# affected by this bug.
> -#libinput:name:PenTablet Pen:dmi:*
> -# LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT=1
> +# HUION re-uses USB IDs for its devices, not every HUION tablet is
> +# affected by this bug, libinput will auto-disable this feature
> +libinput:tablet:input:b0003v256Cp*
> + LIBINPUT_MODEL_TABLET_NO_PROXIMITY_OUT=1
>
>  ##########################################
>  # LENOVO
> diff --git a/udev/90-libinput-model-quirks.rules.in b/udev/
> 90-libinput-model-quirks.rules.in
> index 08137812..5c2ff42e 100644
> --- a/udev/90-libinput-model-quirks.rules.in
> +++ b/udev/90-libinput-model-quirks.rules.in
> @@ -29,6 +29,10 @@ KERNELS=="*input*", \
>  ENV{ID_INPUT_TOUCHPAD}=="1", \
>    IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:
> touchpad:"
>
> +# libinput:tablet:<modalias>
> +ENV{ID_INPUT_TABLET}=="1", \
> +  IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:
> TABLET:"
> +
>  # libinput:mouse:<modalias>
>  ENV{ID_INPUT_MOUSE}=="1", \
>    IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:
> mouse:"
> diff --git a/udev/parse_hwdb.py b/udev/parse_hwdb.py
> index f6b9ec0a..69eb65b0 100755
> --- a/udev/parse_hwdb.py
> +++ b/udev/parse_hwdb.py
> @@ -59,7 +59,7 @@ REAL = Combine((INTEGER + Optional('.' +
> Optional(INTEGER))) ^ ('.' + INTEGER))
>  UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
>
>  TYPES = {
> -    'libinput': ('name', 'touchpad', 'mouse', 'keyboard'),
> +    'libinput': ('name', 'touchpad', 'mouse', 'keyboard', 'tablet'),
>  }
>
>
> --
> 2.13.5
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20170920/908e7254/attachment-0001.html>


More information about the wayland-devel mailing list