[PATCH libinput] test: add tablet test for out-of-bounds motion coordinates

Carlos Garnacho carlosg at gnome.org
Thu Feb 11 10:44:55 UTC 2016


Hey :),

On Thu, Feb 11, 2016 at 8:31 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> The newer Cintiqs have a minimum value of 400/400 advertised by the kernel but
> the actual sensor goes past the 0/0 origin. Test this, make sure that a value
> outside the boundaries generates negative mm values.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Mostly just documenting this and adding a test. The behaviour is that any
> out-of-bounds motion may provide negative coordinates, when transformed may
> provide something outside the [0, max-range].
>
> Now, this is documenting the API behaviour. For the Cintiq I think it might
> be better to put a device-specific quirk in to simply supress those events
> since we don't have anything outside of these boundaries. Jason, Carlos, any
> comments?

I agree, reporting those would mean that such tablets could move
"outside" the crtc they're mapped to, even if not too far around the
borders. Although that same thought comes from any other tablet that
happens to behave the same. Not that we can preemptively add quirks
for these, but we probably should too when we know of these.

Cheers,
  Carlos

>
>  doc/svg/tablet-out-of-bounds.svg | 271 +++++++++++++++++++++++++++++++++++++++
>  doc/tablet-support.dox           |  22 ++++
>  src/libinput.h                   |  12 ++
>  test/tablet.c                    |  58 +++++++++
>  4 files changed, 363 insertions(+)
>  create mode 100644 doc/svg/tablet-out-of-bounds.svg
>
> diff --git a/doc/svg/tablet-out-of-bounds.svg b/doc/svg/tablet-out-of-bounds.svg
> new file mode 100644
> index 0000000..83e5021
> --- /dev/null
> +++ b/doc/svg/tablet-out-of-bounds.svg
> @@ -0,0 +1,271 @@
> +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
> +<!-- Created with Inkscape (http://www.inkscape.org/) -->
> +
> +<svg
> +   xmlns:dc="http://purl.org/dc/elements/1.1/"
> +   xmlns:cc="http://creativecommons.org/ns#"
> +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
> +   xmlns:svg="http://www.w3.org/2000/svg"
> +   xmlns="http://www.w3.org/2000/svg"
> +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
> +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
> +   width="134.12477mm"
> +   height="73.121971mm"
> +   viewBox="0 0 475.24525 259.0936"
> +   id="svg2"
> +   version="1.1"
> +   inkscape:version="0.91 r13725"
> +   sodipodi:docname="tablet-out-of-bounds.svg">
> +  <defs
> +     id="defs4" />
> +  <sodipodi:namedview
> +     id="base"
> +     pagecolor="#ffffff"
> +     bordercolor="#666666"
> +     borderopacity="1.0"
> +     inkscape:pageopacity="0.0"
> +     inkscape:pageshadow="2"
> +     inkscape:zoom="5.6"
> +     inkscape:cx="105.43109"
> +     inkscape:cy="265.46934"
> +     inkscape:document-units="px"
> +     inkscape:current-layer="layer1"
> +     showgrid="false"
> +     showguides="true"
> +     inkscape:guide-bbox="true"
> +     inkscape:window-width="1920"
> +     inkscape:window-height="1136"
> +     inkscape:window-x="0"
> +     inkscape:window-y="27"
> +     inkscape:window-maximized="1"
> +     fit-margin-top="0"
> +     fit-margin-left="0"
> +     fit-margin-right="0"
> +     fit-margin-bottom="0">
> +    <sodipodi:guide
> +       position="63.6133,240.91614"
> +       orientation="0,1"
> +       id="guide4164" />
> +    <sodipodi:guide
> +       position="61.08792,13.126743"
> +       orientation="0,1"
> +       id="guide4166" />
> +  </sodipodi:namedview>
> +  <metadata
> +     id="metadata7">
> +    <rdf:RDF>
> +      <cc:Work
> +         rdf:about="">
> +        <dc:format>image/svg+xml</dc:format>
> +        <dc:type
> +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
> +        <dc:title></dc:title>
> +      </cc:Work>
> +    </rdf:RDF>
> +  </metadata>
> +  <g
> +     inkscape:label="tablet"
> +     inkscape:groupmode="layer"
> +     id="layer1"
> +     style="display:inline"
> +     transform="translate(-139.42736,-156.36219)">
> +    <rect
> +       style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.9201867;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.68074643, 0.92018661;stroke-dashoffset:0;stroke-opacity:1"
> +       id="rect4136"
> +       width="474.32504"
> +       height="258.1734"
> +       x="139.88745"
> +       y="156.82228"
> +       rx="5" />
> +    <rect
> +       y="175.42407"
> +       x="199.33878"
> +       height="226.52563"
> +       width="357.34042"
> +       id="rect4140"
> +       style="opacity:0.92000002;fill:#a44d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.74800003;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
> +    <g
> +       id="g7041"
> +       transform="translate(12,0)">
> +      <g
> +         transform="matrix(0.53265351,0,0,0.53265351,92.308091,96.440418)"
> +         id="g7023">
> +        <circle
> +           style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.98900002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
> +           id="path4158"
> +           cx="135.61298"
> +           cy="287.06125"
> +           r="22.98097" />
> +        <ellipse
> +           cy="287.06125"
> +           cx="135.61298"
> +           id="circle4160"
> +           style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.52043104;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172421, 0.52043105;stroke-dashoffset:0;stroke-opacity:1"
> +           rx="11.5985"
> +           ry="12.608653" />
> +      </g>
> +      <rect
> +         rx="0.5"
> +         y="268.93671"
> +         x="163.8243"
> +         height="8.9902887"
> +         width="13.786156"
> +         id="rect4162"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1" />
> +      <rect
> +         rx="0.5"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7027"
> +         width="13.786156"
> +         height="8.9902887"
> +         x="163.8243"
> +         y="280.97675" />
> +      <rect
> +         rx="0.5"
> +         y="293.01678"
> +         x="163.8243"
> +         height="8.9902887"
> +         width="13.786156"
> +         id="rect7029"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1" />
> +      <rect
> +         rx="0.5"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.44849709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.79398834, 0.44849708;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7031"
> +         width="9.1119308"
> +         height="32.483532"
> +         x="149.90343"
> +         y="269.44443" />
> +      <rect
> +         rx="0.5"
> +         y="269.44443"
> +         x="137.90343"
> +         height="32.483532"
> +         width="9.1119308"
> +         id="rect7033"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.44849709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.79398834, 0.44849708;stroke-dashoffset:0;stroke-opacity:1" />
> +      <rect
> +         rx="0.5"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7035"
> +         width="9.3657951"
> +         height="5.9516821"
> +         x="137.77649"
> +         y="256.10321" />
> +      <rect
> +         rx="0.5"
> +         y="246.10321"
> +         x="137.77649"
> +         height="5.9516821"
> +         width="9.3657951"
> +         id="rect7037"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1" />
> +      <rect
> +         rx="0.5"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7039"
> +         width="9.3657951"
> +         height="5.9516821"
> +         x="137.77649"
> +         y="236.10321" />
> +    </g>
> +    <g
> +       transform="matrix(-1,0,0,1,743.43474,0)"
> +       id="g7054">
> +      <g
> +         id="g7056"
> +         transform="matrix(0.53265351,0,0,0.53265351,92.308091,96.440418)">
> +        <circle
> +           r="22.98097"
> +           cy="287.06125"
> +           cx="135.61298"
> +           id="circle7058"
> +           style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.98900002;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
> +        <ellipse
> +           ry="12.608653"
> +           rx="11.5985"
> +           style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.52043104;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172421, 0.52043105;stroke-dashoffset:0;stroke-opacity:1"
> +           id="ellipse7060"
> +           cx="135.61298"
> +           cy="287.06125" />
> +      </g>
> +      <rect
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7062"
> +         width="13.786156"
> +         height="8.9902887"
> +         x="163.8243"
> +         y="268.93671"
> +         rx="0.5" />
> +      <rect
> +         y="280.97675"
> +         x="163.8243"
> +         height="8.9902887"
> +         width="13.786156"
> +         id="rect7064"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1"
> +         rx="0.5" />
> +      <rect
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.29022256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.16089031, 0.29022258;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7066"
> +         width="13.786156"
> +         height="8.9902887"
> +         x="163.8243"
> +         y="293.01678"
> +         rx="0.5" />
> +      <rect
> +         y="269.44443"
> +         x="149.90343"
> +         height="32.483532"
> +         width="9.1119308"
> +         id="rect7068"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.44849709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.79398834, 0.44849708;stroke-dashoffset:0;stroke-opacity:1"
> +         rx="0.5" />
> +      <rect
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.44849709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:1.79398834, 0.44849708;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7070"
> +         width="9.1119308"
> +         height="32.483532"
> +         x="137.90343"
> +         y="269.44443"
> +         rx="0.5" />
> +      <rect
> +         y="256.10321"
> +         x="137.77649"
> +         height="5.9516821"
> +         width="9.3657951"
> +         id="rect7072"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1"
> +         rx="0.5" />
> +      <rect
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1"
> +         id="rect7074"
> +         width="9.3657951"
> +         height="5.9516821"
> +         x="137.77649"
> +         y="246.10321"
> +         rx="0.5" />
> +      <rect
> +         y="236.10321"
> +         x="137.77649"
> +         height="5.9516821"
> +         width="9.3657951"
> +         id="rect7076"
> +         style="opacity:0.92000002;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.19463234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0.77852936, 0.19463234;stroke-dashoffset:0;stroke-opacity:1"
> +         rx="0.5" />
> +    </g>
> +    <rect
> +       style="opacity:0.92000002;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.6687212;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.6748846, 0.66872115;stroke-dashoffset:0;stroke-opacity:1"
> +       id="rect7078"
> +       width="326.1051"
> +       height="198.32079"
> +       x="214.95644"
> +       y="189.5265" />
> +  </g>
> +  <g
> +     inkscape:groupmode="layer"
> +     id="layer3"
> +     inkscape:label="stylus"
> +     style="display:inline"
> +     transform="translate(-139.42736,-156.36219)" />
> +</svg>
> diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
> index ff4e460..0e719b7 100644
> --- a/doc/tablet-support.dox
> +++ b/doc/tablet-support.dox
> @@ -186,4 +186,26 @@ Intuos 3, 4, 5, Wacon Cintiq and Wacom Intuos Pro series. The tool ID can
>  be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen.
>  It is  the caller's responsibility to interpret the tool ID.
>
> + at section tablet-bounds Out-of-bounds motion events
> +
> +Some tablets integrated into a screen (e.g. Wacom Cintiq 24HD, 27QHD and
> +13HD series, etc.) have a sensor larger than the display area. libinput uses
> +the range advertised by the kernel as the valid range unless device-specific
> +quirks are present. Events outside this range will produce coordinates that
> +may be negative or larger than the tablet's width and/or height. It is up to
> +the caller to ignore these events.
> +
> + at image html tablet-out-of-bounds.svg "Illustration of the out-of-bounds area on a tablet"
> +
> +In the image above, the display area is shown in black. The red area around
> +the display illustrates the sensor area that generates input events. Events
> +within this area will have negative coordinate or coordinates larger than
> +the width/height of the tablet.
> +
> +If events outside the logical bounds of the input area are scaled into a
> +custom range with libinput_event_tablet_tool_get_x_transformed() and
> +libinput_event_tablet_tool_get_y_transformed() the resulting value may be
> +less than 0 or larger than the upper range provided. It is up to the caller
> +to test for this and handle or ignore these events accordingly.
> +
>  */
> diff --git a/src/libinput.h b/src/libinput.h
> index b14c281..cf33492 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -1562,6 +1562,9 @@ libinput_event_tablet_tool_wheel_has_changed(
>   * libinput_event_tablet_tool_get_x_transformed() for transforming the axis
>   * value into a different coordinate space.
>   *
> + * @note On some devices, returned value may be negative or larger than the
> + * width of the device. See @ref tablet-bounds for more details.
> + *
>   * @param event The libinput tablet tool event
>   * @return The current value of the the axis
>   */
> @@ -1576,6 +1579,9 @@ libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool *event);
>   * libinput_event_tablet_tool_get_y_transformed() for transforming the axis
>   * value into a different coordinate space.
>   *
> + * @note On some devices, returned value may be negative or larger than the
> + * width of the device. See @ref tablet-bounds for more details.
> + *
>   * @param event The libinput tablet tool event
>   * @return The current value of the the axis
>   */
> @@ -1754,6 +1760,9 @@ libinput_event_tablet_tool_get_wheel_delta_discrete(
>   * libinput_event_tablet_tool_*_has_changed() returns 0 for that axis.
>   * libinput always includes all device axes in the event.
>   *
> + * @note On some devices, returned value may be negative or larger than the
> + * width of the device. See @ref tablet-bounds for more details.
> + *
>   * @param event The libinput tablet tool event
>   * @param width The current output screen width
>   * @return the current absolute x coordinate transformed to a screen coordinate
> @@ -1772,6 +1781,9 @@ libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool *
>   * libinput_event_tablet_tool_*_has_changed() returns 0 for that axis.
>   * libinput always includes all device axes in the event.
>   *
> + * @note On some devices, returned value may be negative or larger than the
> + * width of the device. See @ref tablet-bounds for more details.
> + *
>   * @param event The libinput tablet tool event
>   * @param height The current output screen height
>   * @return the current absolute y coordinate transformed to a screen coordinate
> diff --git a/test/tablet.c b/test/tablet.c
> index 6909f95..c5dc892 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -1655,6 +1655,63 @@ START_TEST(motion_event_state)
>  }
>  END_TEST
>
> +START_TEST(motion_outside_bounds)
> +{
> +       struct litest_device *dev = litest_current_device();
> +       struct libinput *li = dev->libinput;
> +       struct libinput_event *event;
> +       struct libinput_event_tablet_tool *tablet_event;
> +       double val;
> +
> +       struct axis_replacement axes[] = {
> +               { ABS_DISTANCE, 10 },
> +               { ABS_PRESSURE, 0 },
> +               { -1, -1 }
> +       };
> +
> +       litest_tablet_proximity_in(dev, 50, 50, axes);
> +       litest_drain_events(li);
> +
> +       /* On the 24HD x/y of 0 is outside the limit */
> +       litest_event(dev, EV_ABS, ABS_X, 0);
> +       litest_event(dev, EV_ABS, ABS_Y, 1000);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tablet_event = litest_is_tablet_event(event,
> +                                             LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       val = libinput_event_tablet_tool_get_x(tablet_event);
> +       ck_assert_double_lt(val, 0.0);
> +       val = libinput_event_tablet_tool_get_y(tablet_event);
> +       ck_assert_double_gt(val, 0.0);
> +
> +       val = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
> +       ck_assert_double_lt(val, 0.0);
> +
> +       libinput_event_destroy(event);
> +
> +       /* On the 24HD x/y of 0 is outside the limit */
> +       litest_event(dev, EV_ABS, ABS_X, 1000);
> +       litest_event(dev, EV_ABS, ABS_Y, 0);
> +       litest_event(dev, EV_SYN, SYN_REPORT, 0);
> +       libinput_dispatch(li);
> +
> +       event = libinput_get_event(li);
> +       tablet_event = litest_is_tablet_event(event,
> +                                             LIBINPUT_EVENT_TABLET_TOOL_AXIS);
> +       val = libinput_event_tablet_tool_get_x(tablet_event);
> +       ck_assert_double_gt(val, 0.0);
> +       val = libinput_event_tablet_tool_get_y(tablet_event);
> +       ck_assert_double_lt(val, 0.0);
> +
> +       val = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
> +       ck_assert_double_lt(val, 0.0);
> +
> +       libinput_event_destroy(event);
> +}
> +END_TEST
> +
>  START_TEST(bad_distance_events)
>  {
>         struct litest_device *dev = litest_current_device();
> @@ -3577,6 +3634,7 @@ litest_setup_tests(void)
>         litest_add("tablet:tip", tip_state_button, LITEST_TABLET, LITEST_ANY);
>         litest_add("tablet:motion", motion, LITEST_TABLET, LITEST_ANY);
>         litest_add("tablet:motion", motion_event_state, LITEST_TABLET, LITEST_ANY);
> +       litest_add_for_device("tablet:motion", motion_outside_bounds, LITEST_WACOM_CINTIQ_24HD);
>         litest_add("tablet:tilt", tilt_available, LITEST_TABLET|LITEST_TILT, LITEST_ANY);
>         litest_add("tablet:tilt", tilt_not_available, LITEST_TABLET, LITEST_TILT);
>         litest_add("tablet:tilt", tilt_x, LITEST_TABLET|LITEST_TILT, LITEST_ANY);
> --
> 2.5.0
>


More information about the wayland-devel mailing list