path: root/doc/tablet-support.dox
diff options
Diffstat (limited to 'doc/tablet-support.dox')
1 files changed, 95 insertions, 0 deletions
diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
new file mode 100644
index 00000000..24d08d20
--- /dev/null
+++ b/doc/tablet-support.dox
@@ -0,0 +1,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
+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:
+const double threshold = ...;
+static double min;
+static bool in_proximity;
+double value;
+value = libinput_event_tablet_tool_get_axis_value(device,
+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;