test: add tablet test for out-of-bounds motion coordinates

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@who-t.net>
This commit is contained in:
Peter Hutterer 2016-02-11 14:32:33 +10:00
parent 197bad1676
commit 3d1b17e1fd
4 changed files with 363 additions and 0 deletions

View file

@ -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>

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -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.
@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.
@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.
*/

View file

@ -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

View file

@ -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);