Add tablet area configuration

This adds the configuration option to define a rectangle that serves as
an input area on external tablets such as an Intuos.

The intention behind this is to make this input area behave as if it was
the only physical input area on this tablet with libinput emulating
proximity events as required for where the tools moves in and out
of this area.

This could also be achieved with the existing calibration setting but
area configuration is not calibration and we don't want to expose other
side-effects of the matrix (e.g. scaling and rotation) for these
devices.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1013>
This commit is contained in:
Peter Hutterer 2024-06-13 09:00:21 +10:00
parent 9735229dee
commit cf5b7bee01
12 changed files with 502 additions and 1 deletions

View file

@ -49,6 +49,7 @@ __all_seats()
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
'--disable-sendevents=[Disable send-events option for the devices matching the pattern]:pattern' \
'--set-area=[Set the desired area as "x1/y1 x2/y2" (within [0.0, 1.0]) ]' \
'--set-click-method=[Set the desired click method]:click-method:(none clickfinger buttonareas)' \
'--set-clickfinger-map=[Set button mapping for clickfinger]:tap-map:(( \
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \

View file

@ -191,3 +191,16 @@ the given threshold is met, and will reach the maximum logical pressure
before the maximum hardware-supported pressure is reached.
See :ref:`tablet-pressure-range` for more info.
------------------------------------------------------------------------------
Area configuration
------------------------------------------------------------------------------
Area configuration is available for some indirect input devices such as
graphics tablets. This configuration allows reducing the active area of
such a device to a subset of the physically possible area.
An example use-case for this is to match the aspect ratio of the device to that
of the screen.
See :ref:`tablet-area` for more info.

View file

@ -120,6 +120,7 @@ src_rst = files(
'svg/software-buttons-thumbpress.svg',
'svg/software-buttons-visualized.svg',
'svg/swipe-gestures.svg',
'svg/tablet-area.svg',
'svg/tablet-axes.svg',
'svg/tablet-cintiq24hd-modes.svg',
'svg/tablet-interfaces.svg',

View file

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="229.5488mm"
height="86.66362mm"
viewBox="0 0 813.36188 307.07582"
id="svg2"
version="1.1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
sodipodi:docname="tablet-area.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4294"
id="linearGradient4300"
x1="465.81339"
y1="666.13727"
x2="454.82117"
y2="658.65521"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient4294">
<stop
style="stop-color:#1a1a1a;stop-opacity:1;"
offset="0"
id="stop4296" />
<stop
style="stop-color:#808080;stop-opacity:1"
offset="1"
id="stop4298" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="410.53571"
inkscape:cy="188.39286"
inkscape:document-units="px"
inkscape:current-layer="layer3"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="3072"
inkscape:window-height="1659"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<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" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="tablet"
inkscape:groupmode="layer"
id="layer1"
style="display:inline"
transform="translate(67.109152,-133.63374)">
<g
id="g4309"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="translate(0,1.0715222)">
<rect
y="134.15933"
x="75.787216"
height="306.02466"
width="522.19733"
id="rect4136"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:1.05118;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:4.20473, 1.05118;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.748138;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.99255, 0.748138;stroke-dashoffset:0;stroke-opacity:1"
id="rect4140"
width="357.34042"
height="226.52563"
x="199.33878"
y="175.42407" />
<rect
y="175.72914"
x="103.10225"
height="22.142857"
width="65"
id="rect4142"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
id="rect4148"
width="65"
height="22.142857"
x="103.10225"
y="203.72914" />
<rect
y="231.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4150"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
y="323.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4154"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
id="rect4156"
width="65"
height="22.142857"
x="103.10225"
y="351.72913" />
<circle
r="22.98097"
cy="287.06125"
cx="135.61298"
id="path4158"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;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.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.520431;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172, 0.520431;stroke-dashoffset:0;stroke-opacity:1"
id="circle4160"
cx="135.61298"
cy="287.06125" />
<rect
y="379.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4162"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="area">
<rect
style="display:inline;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.675728"
id="rect1"
width="131.51813"
height="126.57689"
x="326.15009"
y="97.775696" />
<text
xml:space="preserve"
style="display:inline;font-size:11.25px;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.9375"
x="261.92404"
y="244.01244"
id="text1"
transform="translate(67.109152,-133.63374)"><tspan
sodipodi:role="line"
id="tspan1"
style="fill:#000000;stroke-width:0.9375"
x="261.92404"
y="244.01244">0/0</tspan></text>
<path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
d="m 259.17629,227.63135 v 7.63349"
id="path1"
transform="translate(67.109152,-133.63374)" />
<path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
d="m 262.99304,231.44809 h -7.63349"
id="path2"
transform="translate(67.109152,-133.63374)" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="stylus"
style="display:inline"
transform="translate(67.109152,-133.63374)">
<g
id="g4304"
transform="matrix(0.37129971,0.09948946,-0.09618892,0.35898192,319.19555,24.123239)"
style="display:inline">
<path
sodipodi:nodetypes="czcc"
inkscape:connector-curvature="0"
id="path4286"
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ssssccssscsssssssssssssssssss"
inkscape:connector-curvature="0"
id="path4283"
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
style="display:inline;fill:#000000" />
<path
sodipodi:nodetypes="scccs"
inkscape:connector-curvature="0"
id="path4292"
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

@ -467,3 +467,31 @@ devices arbitration has to be done in userspace.
libinput uses the **libinput_device_group** to decide on touch arbitration
and automatically discards touch events whenever a tool is in proximity.
The exact behavior is device-dependent.
.. _tablet-area:
------------------------------------------------------------------------------
Tablet area
------------------------------------------------------------------------------
External tablet devices such as e.g. the Wacom Intuos series can be configured
to reduce the available logical input area. Typically the logical input area
is equivalent to the physical input area but it can be reduced with the
**libinput_device_config_area_set_rectangle()** call. Once reduced, input
events outside the logical input area are ignored and the logical input area
acts as if it represented the extents of the physical tablet.
.. figure:: tablet-area.svg
:align: center
Tablet area configuration example
In the image above, the area is set to the rectangle 0.25/0.25 to 0.5/0.75.
Even though the tool is roughly at the physical position ``0.5 * width`` and
``0.75 * height``, the return values of
**libinput_event_tablet_tool_get_x_transformed()** and
**libinput_event_tablet_tool_get_y_transformed()** would be close to the
maximum provided in this call.
The size of the tablet reported by **libinput_device_get_size()** always reflects
the physical area, not the logical area.

View file

@ -228,6 +228,14 @@ struct libinput_device_config_calibration {
float matrix[6]);
};
struct libinput_device_config_area {
int (*has_rectangle)(struct libinput_device *device);
enum libinput_config_status (*set_rectangle)(struct libinput_device *device,
const struct libinput_config_area_rectangle *rectangle);
struct libinput_config_area_rectangle (*get_rectangle)(struct libinput_device *device);
struct libinput_config_area_rectangle (*get_default_rectangle)(struct libinput_device *device);
};
struct libinput_device_config_send_events {
uint32_t (*get_modes)(struct libinput_device *device);
enum libinput_config_status (*set_mode)(struct libinput_device *device,
@ -391,6 +399,7 @@ struct libinput_device_config_gesture {
struct libinput_device_config {
struct libinput_device_config_tap *tap;
struct libinput_device_config_calibration *calibration;
struct libinput_device_config_area *area;
struct libinput_device_config_send_events *sendevents;
struct libinput_device_config_accel *accel;
struct libinput_device_config_natural_scroll *natural_scroll;

View file

@ -4134,6 +4134,45 @@ libinput_device_config_calibration_get_default_matrix(struct libinput_device *de
return device->config.calibration->get_default_matrix(device, matrix);
}
LIBINPUT_EXPORT int
libinput_device_config_area_has_rectangle(struct libinput_device *device)
{
return device->config.area ?
device->config.area->has_rectangle(device) : 0;
}
LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_area_set_rectangle(struct libinput_device *device,
const struct libinput_config_area_rectangle *rectangle)
{
if (!libinput_device_config_area_has_rectangle(device))
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
return device->config.area->set_rectangle(device, rectangle);
}
LIBINPUT_EXPORT struct libinput_config_area_rectangle
libinput_device_config_area_get_rectangle(struct libinput_device *device)
{
struct libinput_config_area_rectangle rect = { 0.0, 0.0, 1.0, 1.0 };
if (!libinput_device_config_area_has_rectangle(device))
return rect;
return device->config.area->get_rectangle(device);
}
LIBINPUT_EXPORT struct libinput_config_area_rectangle
libinput_device_config_area_get_default_rectangle(struct libinput_device *device)
{
struct libinput_config_area_rectangle rect = { 0.0, 0.0, 1.0, 1.0 };
if (!libinput_device_config_area_has_rectangle(device))
return rect;
return device->config.area->get_default_rectangle(device);
}
LIBINPUT_EXPORT uint32_t
libinput_device_config_send_events_get_modes(struct libinput_device *device)
{

View file

@ -2401,6 +2401,10 @@ libinput_event_tablet_tool_wheel_has_changed(
* libinput_event_tablet_tool_get_x_transformed() for transforming the axis
* value into a different coordinate space.
*
* If an area is defined for this device, the coordinate is in mm from
* the top left corner of the area. See
* libinput_device_config_area_set_rectangle() for details.
*
* @note On some devices, returned value may be negative or larger than the
* width of the device. See the libinput documentation for more details.
*
@ -2420,6 +2424,10 @@ 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.
*
* If an area is defined for this device, the coordinate is in mm from
* the top left corner of the area. See
* libinput_device_config_area_set_rectangle() for details.
*
* @note On some devices, returned value may be negative or larger than the
* width of the device. See the libinput documentation for more details.
*
@ -5128,6 +5136,143 @@ int
libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,
float matrix[6]);
/**
* @ingroup config
*
* Describes a rectangle to configure a device's area, see
* libinput_device_config_area_set_rectangle().
*
* This struct describes a rectangle via the upper left points (x1, y1)
* and the lower right point (x2, y2).
*
* All arguments are normalized to the range [0.0, 1.0] to represent the
* corresponding proportion of the device's width and height, respectively.
* A rectangle covering the whole device thus comprises of the points
* (0.0, 0.0) and (1.0, 1.0).
*
* The conditions x1 < x2 and y1 < y2 must be true.
*/
struct libinput_config_area_rectangle {
double x1;
double y1;
double x2;
double y2;
};
/**
* @ingroup config
*
* Check if the device can change its logical input area via a rectangle.
*
* @param device The device to check
* @return Non-zero if the device can be calibrated, zero otherwise.
*
* @see libinput_device_config_area_set_rectangle
* @see libinput_device_config_area_get_rectangle
* @see libinput_device_config_area_get_default_rectangle
*/
int
libinput_device_config_area_has_rectangle(struct libinput_device *device);
/**
* @ingroup config
*
* Set the given rectangle as the logical input area of this device.
* Future interactions by a tablet tool on this devices are scaled
* to only consider events within this logical input area - as if the
* logical input area were the available physical area.
*
* The coordinates of the rectangle represent the proportion of the
* available maximum physical area, normalized to the range [0.0, 1.0].
* For example, a rectangle with the two points 0.25, 0.5, 0.75, 1.0
* adds a 25% dead zone to the left and right and a 50% dead zone on
* the top:
*
* @code
* +----------------------------------+
* | |
* | 50% |
* | |
* | +-----------------+ |
* | | | |
* | 25% | | 25% |
* | | | |
* +--------+-----------------+-------+
* @endcode
*
* The area applies in the tablet's current logical rotation, i.e. the above
* example is always at the bottom of the tablet.
*
* Once applied, the logical area's top-left coordinate (in the current logical
* rotation) becomes the new offset (0/0) and the return values of
* libinput_event_tablet_tool_get_x() and libinput_event_tablet_tool_get_y()
* are in relation to this new offset.
*
* Likewise, libinput_event_tablet_tool_get_x_transformed() and
* libinput_event_tablet_tool_get_y_transformed() represent the value scaled
* into the configured logical area.
*
* The return value of libinput_device_get_size() is not affected by the
* configured area.
*
* Changing the area may not take effect immediately, the device may wait until
* it is in a neutral state before applying any changes.
*
* @param device The device to check
* @param rect The intended rectangle
* @return A config status code. Setting the area on a device that does not
* support area rectangles always fails with @ref LIBINPUT_CONFIG_STATUS_UNSUPPORTED.
*
* @see libinput_device_config_area_has_rectangle
* @see libinput_device_config_area_get_rectangle
* @see libinput_device_config_area_get_default_rectangle
*/
enum libinput_config_status
libinput_device_config_area_set_rectangle(struct libinput_device *device,
const struct libinput_config_area_rectangle *rect);
/**
* @ingroup config
*
* Return the current area rectangle for this device.
*
* The return value for a device that does not support area rectangles is a
* rectangle with the points 0/0 and 1/1.
*
* @note It is an application bug to call this function for devices where
* libinput_device_config_area_has_rectangle() returns 0.
*
* @param device The device to check
* @return The current area rectangle
*
* @see libinput_device_config_area_has_rectangle
* @see libinput_device_config_area_set_rectangle
* @see libinput_device_config_area_get_default_rectangle
*/
struct libinput_config_area_rectangle
libinput_device_config_area_get_rectangle(struct libinput_device *device);
/**
* @ingroup config
*
* Return the default area rectangle for this device.
*
* The return value for a device that does not support area rectangles is a
* rectangle with the points 0/0 and 1/1.
*
* @note It is an application bug to call this function for devices where
* libinput_device_config_area_has_rectangle() returns 0.
*
* @param device The device to check
* @return The default area rectangle
*
* @see libinput_device_config_area_has_rectangle
* @see libinput_device_config_area_set_rectangle
* @see libinput_device_config_area_get_rectangle
*/
struct libinput_config_area_rectangle
libinput_device_config_area_get_default_rectangle(struct libinput_device *device);
/**
* @ingroup config
*

View file

@ -350,3 +350,10 @@ LIBINPUT_1.26 {
libinput_tablet_tool_config_pressure_range_get_default_minimum;
libinput_tablet_tool_config_pressure_range_get_default_maximum;
} LIBINPUT_1.23;
LIBINPUT_1.27 {
libinput_device_config_area_has_rectangle;
libinput_device_config_area_set_rectangle;
libinput_device_config_area_get_rectangle;
libinput_device_config_area_get_default_rectangle;
} LIBINPUT_1.26;

View file

@ -87,6 +87,10 @@ Enable or disable the scroll button lock
.B \-\-enable\-tap|\-\-disable\-tap
Enable or disable tap-to-click
.TP 8
.B \-\-set\-area="x1/y1 x2/y2"
Set the tablet area to the rectangle described by the two points x1/y1 and x2/y2. All
coordinates must be in the range [0.0, 1.0].
.TP 8
.B \-\-set\-calibration="1.0 0.0 0.0 0.0 1.0 0.0"
Set the first 6 elements of a 3x3 matrix to use for calibration. The third row of the
matrix is always "0.0 0.0 0.1".

View file

@ -133,6 +133,10 @@ tools_init_options(struct tools_options *options)
options->pressure_range[1] = 1.0;
options->calibration[0] = 1.0;
options->calibration[4] = 1.0;
options->area.x1 = 0.0;
options->area.y1 = 0.0;
options->area.x2 = 1.0;
options->area.y2 = 1.0;
}
int
@ -390,6 +394,22 @@ tools_parse_option(int option,
options->calibration[i] = matrix[i];
free(matrix);
break;
}
case OPT_AREA: {
if (!optarg)
return 1;
double x1, x2, y1, y2;
if (sscanf(optarg, "%lf/%lf %lf/%lf", &x1, &y1, &x2, &y2) != 4) {
fprintf(stderr, "Invalid --set-area values\n");
return 1;
}
options->area.x1 = x1;
options->area.y1 = y1;
options->area.x2 = x2;
options->area.y2 = y2;
break;
}
}
return 0;
@ -606,6 +626,9 @@ tools_device_apply_config(struct libinput_device *device,
if (libinput_device_config_calibration_has_matrix(device))
libinput_device_config_calibration_set_matrix(device, options->calibration);
if (libinput_device_config_area_has_rectangle(device))
libinput_device_config_area_set_rectangle(device, &options->area);
}
void

View file

@ -68,6 +68,7 @@ enum configuration_options {
OPT_ROTATION_ANGLE,
OPT_PRESSURE_RANGE,
OPT_CALIBRATION,
OPT_AREA,
};
#define CONFIGURATION_OPTIONS \
@ -103,7 +104,8 @@ enum configuration_options {
{ "set-custom-type", required_argument, 0, OPT_CUSTOM_TYPE },\
{ "set-rotation-angle", required_argument, 0, OPT_ROTATION_ANGLE }, \
{ "set-pressure-range", required_argument, 0, OPT_PRESSURE_RANGE }, \
{ "set-calibration", required_argument, 0, OPT_CALIBRATION }
{ "set-calibration", required_argument, 0, OPT_CALIBRATION }, \
{ "set-area", required_argument, 0, OPT_AREA }
enum tools_backend {
BACKEND_NONE,
@ -138,6 +140,7 @@ struct tools_options {
unsigned int angle;
double pressure_range[2];
float calibration[6];
struct libinput_config_area_rectangle area;
};
void tools_init_options(struct tools_options *options);