summaryrefslogtreecommitdiff
path: root/doc/tablet-support.dox
blob: 24d08d2091de8124c986f9338571f4ace0c1055d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
@page tablet-support Tablet support

This page provides details about the graphics tablet
support in libinput. Note that the term "tablet" in libinput refers to
graphics tablets only (e.g. Wacom Intuos), not to tablet devices like the
Apple iPad.

@image html tablet.svg "Illustration of a graphics tablet"

@section tablet-tools Tablet buttons vs. tablet tools

Most tablets provide two types of devices. The pysical tablet often provides
a number of buttons and a touch ring or strip. Interaction on the drawing
surface of the tablet requires a tool, usually in the shape of a stylus.
The libinput interface exposed by devices with the @ref
LIBINPUT_DEVICE_CAP_TABLET_TOOL applies only to events generated by tools.

Touch events on the tablet itself are exposed
through the @ref LIBINPUT_DEVICE_CAP_TOUCH capability and are often found on
a separate libinput device. See libinput_device_get_device_group() for
information on how to associate the touch part with other devices exposed by
the same physical hardware.

@section tablet-tip Tool tip events vs. button events

The primary use of a tablet tool is to draw on the surface of the tablet.
When the tool tip comes into contact with the surface, libinput sends an
event of type @ref LIBINPUT_EVENT_TABLET_TOOL_TIP, and again when the tip
ceases contact with the surface.

Tablet tools may send button events; these are exclusively for extra buttons
unrelated to the tip. A button event is independent of the tip and occur
at any time.

@section tablet-axes Special axes on tablet tools

A tablet tool usually provides additional information beyond x/y positional
information and the tip state. A tool may provide the distance to the tablet
surface and the pressure exerted on the tip when in contact. Some tablets
additionally provide tilt information along the x and y axis.

@image html tablet-axes.svg "Illustration of the distance, pressure and tilt axes"

The granularity and precision of these axes varies between tablet devices
and cannot usually be mapped into a physical unit.
libinput normalizes distance and pressure into a fixed positive 2-byte
integer range. The tilt axes are normalized into a signed 2-byte integer
range.

While the normalization range is identical for these axes, a caller should
not interpret identical values as identical across axes, i.e. a value V1 on
the distance axis has no relation to the same value V1 on the pressure axis.

@section tablet-fake-proximity Handling of proximity events

libinput's @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY events represent the
physical proximity limits of the device. In some cases the caller should
emulate proximity based on the distance events. For example, the Wacom mouse
and lens cursor tools are usually used in relative mode, lying flat on the
tablet. A user typically expects that lifting the tool off the tablet to a
different location has the same effect as with a normal mouse. The proximity
detection on Wacom tablets however extends further than the user may lift
the mouse, i.e. the tool may not be lifted out of physical proximity.

To enable normal use as a mouse it is recommended that the caller treats
proximity separate from libinput's proximity events. There is no simple way
to detect the proximity motion threshold, it is different on each tablet and
differs between tools. The recommended algorithm is to remember the minimum
distance value seen on the tool and assume a proximity out when the distance
exceeds a threshold above this minimum value. In pseudo-code:

@code
const double threshold = ...;
static double min;
static bool in_proximity;

double value;

value = libinput_event_tablet_tool_get_axis_value(device,
					      LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);

if (value < min) {
	min = value;
	return;
} else if (in_proximity &&
	   value > min + threshold) {
	   in_proximity = false;
} else if (!in_proximity &&
	   value < min + threshold) {
	   in_proximity = true;
}
@endcode

*/