touch screens and GNU/Linux

Since 2011 I've used Panasonic Toughbook computers (CF-74, CF-U1, CF-19 MK2 and MK3) with Debian, Kubuntu, Xubuntu and MX Linux. With every fresh install it is a question how to get the touchscreen calibrated.

Resistive touch screens can be calibrated for evdev and wacom drivers with utility 'xinput_calibrator'. The tool is often preinstalled or available in the official software repository as 'xinput-calibrator' (with dash instead of underscore). In the past I've sometimes compiled it from source.

If touch screen events are handled by libinput, one of the issues is that xinput_calibrator can't do the calibration. Depending on system configuration and available packages it may still be possible to use evdev. Troubleshooting described further down, here it starts with the simpler scenario where xinput_calibrator still works with default system configuration. That used to be the case with Debian and *buntu in the past, and is still the case in 2019 with MX linux.

xinput_calibrator

Even when xinput_calibrator is available in the settings menu as 'Calibrate Touchscreen', better run the tool from command line to first see which calibratable devices it finds:

$ xinput_calibrator --list

If more than one calibratable device found, start calibration with the relevant device id. If no device specified, xinput_calibrator will try to calibrate the first calibratable device.

$ xinput_calibrator --device <id>

The calibrator will present a simple full screen display with crosshairs that must be touched precisely. If all goes well the tool will give a configuration snippet and a recommendation of which file to put it in. Terminal output may look like this:

$ xinput_calibrator --device 10
Calibrating EVDEV driver for "Wacom ISDv4 93 Finger" id=10
    current calibration values (from XInput): min_x=153, max_x=4002 and
    min_y=23, max_y=3894

Doing dynamic recalibration:
    Setting calibration data: 170, 4006, 17, 3875 --> Making the calibration
    permanent <-- copy the snippet below into
    '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in
    some distro's)
Section "InputClass"
    Identifier  "calibration"
    MatchProduct    "Wacom ISDv4 93 Finger"
    Option  "Calibration"   "170 4006 17 3875"
    Option  "SwapAxes"  "0"
EndSection

Snippets like these were given for various touch panels using the evdev driver. Calibration was effectuated immediately, but only for the duration of the session. The snippet must be copied into a configuration file to make calibration persistent.

When touchscreen events are handled by the wacom driver the proposed snippet looked considerably different and couldn't be used as is. Also the calibration was not effectuated immediately. More about the wacom driver further down.

configure persistent calibration

As mentioned above the config snippet suggested by xinput_calibrator isn't by definition perfect but those for the evdev driver seem to be appropriate as is. What about the suggested file name and path? So far I've always used /etc/X11/xorg.conf.d/99-calibration.conf. On debian-based systems this path is meant to be respected in case of upgrades. When calibrating for the first time after fresh system install the file doesn't exist yet. Sometimes the directory doesn't even exist. To create the directory:

$ sudo mkdir /etc/X11/xorg.conf.d

The configuration file can be created or edited with a text editor like nano. A simple graphical text editor like leafpad can be used instead, but in any case make sure that it doesn't add invisible markup code.

$ sudo nano /etc/X11/xorg.conf.d/99-calibration.conf

Do not add extra characters, whitespaces or newlines to the snippet. An inappropriate config file can prevent X from loading, leaving you with just a command prompt at next boot or login.

wacom driver

On Xubuntu at least from 12.04 till 16.04 the wacom driver would handle touch events from a wacom device. Here the xinput_calibrator presented an output like this:

Calibrating standard Xorg driver "Wacom ISDv4 93 Finger touch"
current calibration values: min_x=168, max_x=4019 and min_y=26, max_y=3828
If these values are estimated wrong, either supply it manually with the
--precalib option, or run the 'get_precalib.sh' script to automatically get
it (through HAL). --> Making the calibration permanent <-- copy the snippet
below into '/etc/X11/xorg.conf.d/99-calibration.conf'
(/usr/share/X11/xorg.conf.d/ in some distro's)
Section "InputClass"
    Identifier  "calibration"
    MatchProduct    "!!Name_Of_TouchScreen!!"
    Option  "MinX"  "161"
    Option  "MaxX"  "3990"
    Option  "MinY"  "47"
    Option  "MaxY"  "3836"
    Option  "SwapXY"    "0" # unless it was already set to 1
    Option  "InvertX"   "0"  # unless it was already set
    Option  "InvertY"   "0"  # unless it was already set
EndSection

Change '!!Name_Of_TouchScreen!!' to your device's name in the config above.

In this case xinput_calibrator doesn't calibrate the touchscreen for the duration of the session. And isn't it weird that xinput_calibrator doesn't know the name of the device for which it suggests calibration coordinates? Use command 'xinput' with the same device id as before to get more info:

$ xinput --list-props <id>

The output will show device name, driver and current configuration settings. If the driver is wacom indeed, command 'xsetwacom' can be used to try calibration coordinates as proposed by xinput_calibrator (note the order):

$ xsetwacom set <id> area <min_x> <min_y> <max_x> <max_y>

If these coordinates appear to be correct they can be stored in the configuration file as described in the previous section. But, the snippet formulation from xinput_calibrator didn't work for me. After much trial and error this is what worked in my case:

Section "InputClass"
    Identifier    "finger touch calibration"
    MatchDriver   "wacom"
    MatchProduct  "Finger"
    Option        "TopX"    "173"
    Option        "TopY"    "19"
    Option        "BottomX"    "4013"
    Option        "BottomY"    "3851"
EndSection

I can't tell if different formulations work as well, but in any case don't take the snippet from xinput_calibrator for granted. Documentation of the wacom properties was found in /usr/include/xorg/wacom-properties.h. It is interesting but doesn't provide the exact formulation for a config file either.

driver selection

In my experience with Panasonic Toughbook on GNU/Linux the evdev driver has always worked the most effortless for touchscreen. Most distro's have recently switched to libinput however, which doesn't work for me due to various issues. More about these issues with libinput in a later section. For the moment I try to enable evdev for handling touchscreen events. I assume this can only work on systems which (are able to) use X.org as their display server.

To start with, package xorg-xserver-input-evdev must be installed. If this package isn't available in the repository I'd give up and find another distro. Some distro's still have it preinstalled (in 2019). Another thing to find out is which driver is preconfigured to handle touchscreen events. A first but not decisive check is the order of config files for X11. Example from MX18.2:

$ ls /usr/share/X11/xorg.conf.d
10-amdgpu.conf  10-radeon.conf    50-joystick.conf
10-evdev.conf   20-thinkpad.conf  70-synaptics.conf
10-quirks.conf  40-libinput.conf  70-wacom.conf

Libinput config file has precedence over evdev because of its higher number. Let's see the content (irrelevant sections snipped):

$ cat /usr/share/X11/xorg.conf.d/40-libinput.conf
# Match on all types of devices but tablet devices and joysticks
...
Section "InputClass"
        Identifier "libinput touchscreen catchall"
        MatchIsTouchscreen "on"
        MatchDevicePath "/dev/input/event*"
        Driver "libinput"
EndSection
...

Libinput is preinstalled on MX18.2 and it seems to be designated to handle touchscreen events. The evdev config file has a similar section and it could take over control when given a higher number. Like with:

$ cd /usr/share/X11/xorg.conf.d
$ sudo mv 10-evdev.conf 45-evdev.conf

To my surprise, on MX18.2 this wasn't even needed to make evdev work. Further inspection revealed why:

$ ls /etc/X11/xorg.conf.d
10-evdev.conf synaptics.conf

The evdev conf file in /etc/X11/xorg.conf.d has precedence over all files in /usr/share/X11/xorg.conf.d, regardless of the order therein. It seems to me that this is a better approach than tweaking order in /usr/share/X11/xorg.conf.d. The calibrator tool is available in MX18 repository and touchscreen calibration was easier than ever before. I only wonder why MX has those config files in /etc/X11/xorg.conf.d by default.

libinput

Linbinput is a input-handling library for Wayland compositors and also the short name for an Xorg driver based on the same library. Much like evdev the libinput driver handles many device types including touchscreens, however its ambition is to do it with more consistency.

For touchscreen calibration libinput expects a transformation matrix instead of x and y coordinates. Maintenance of xinput_calibrator stopped before the libinput project started and the calibrator can't produce output in this format. Workarounds and alternative tools are available, one of which discussed further down. Also see links at page bottom.

libinput: misclick

In some cases the libinput driver for Xorg can't be used for touchscreen at all. The first sign is when the calibrator reports 'misclick detected'. A calibration tool I was trying to make in Pure Data revealed that the click is detected somewhere on the path from previous to new cursor position.

The misclick is related to the anti-jitter filter in libinput. The filter reduces sensor noise but it also produces interpolated coordinates inbetween discrete touch points. If the button press event is registered before the filter has stabilized, the actual click position is not properly reflected. "Fujitsu Component USB Touch Panel" is one such device that works all right with evdev but suffers the misclick issue with the libinput driver. The following output from utility 'libinput-debug-events' shows a recording of two non-dragging touch clicks (irrelevant lines snipped):

$ sudo libinput-debug-events
WARNING: This compatibility wrapper will be removed in the future. Please run
'libinput debug-events' instead
[...]
-event9   DEVICE_ADDED     Fujitsu Component USB Touch Panel seat0 default
group7  cap:T  size 256x256mm
[...]
-event9   TABLET_TOOL_PROXIMITY +18.37s     40.12*/68.88*   pen (0, id 0)
proximity-in  axes:   btn:S
 event9   TABLET_TOOL_TIP  +18.38s  down
 event9   TABLET_TOOL_AXIS +18.39s      40.12/68.81*
 event9   TABLET_TOOL_AXIS +18.39s      40.12/68.81*
 event9   TABLET_TOOL_AXIS +18.40s      40.12/68.88*
 event9   TABLET_TOOL_AXIS +18.41s      40.12*/68.94*
 event9   TABLET_TOOL_AXIS +18.42s      40.12*/69.06*
 event9   TABLET_TOOL_AXIS +18.43s      40.19*/69.19*
 event9   TABLET_TOOL_AXIS +18.43s      40.25/69.38*
 event9   TABLET_TOOL_TIP  +18.47s  up
 event9   TABLET_TOOL_AXIS +20.28s      84.94*/101.06*
 event9   TABLET_TOOL_TIP  +20.29s  down
 event9   TABLET_TOOL_AXIS +20.29s      174.19*/164.25*
 event9   TABLET_TOOL_AXIS +20.30s      218.88/195.75*
 event9   TABLET_TOOL_AXIS +20.31s      218.94*/195.69
 event9   TABLET_TOOL_AXIS +20.32s      218.94*/195.69
 event9   TABLET_TOOL_AXIS +20.32s      219.00*/195.62*
 event9   TABLET_TOOL_AXIS +20.33s      219.12*/195.62*
 event9   TABLET_TOOL_AXIS +20.34s      219.25*/195.56
 event9   TABLET_TOOL_AXIS +20.35s      219.44*/195.56
 event9   TABLET_TOOL_AXIS +20.36s      219.62*/195.56*
 event9   TABLET_TOOL_AXIS +20.36s      219.75*/195.56*
 event9   TABLET_TOOL_AXIS +20.37s      219.81*/195.62*
 event9   TABLET_TOOL_AXIS +20.38s      219.88*/195.69*
 event9   TABLET_TOOL_AXIS +20.39s      219.94*/195.81*
 event9   TABLET_TOOL_TIP  +20.41s  up

By the way this is on Xubuntu 18.04 with libinput version 1.10. One question is, why is the touch screen interpreted as tablet tool? And another, why is panel size reported incorrectly as 256x256mm while its real size is 210x156mm? Device data for "Fujitsu Component USB Touch Panel" is registered in /lib/udev/hwdb.d/60-evdev.hwdb. The incorrect size appears there.

libinput: systemd dependency

On Xubuntu 18.04 package libinput doesn't mention systemd as dependency. However libinput relies on the hardware database that is part of systemd.

xinput_calibrator for libinput

Branch 'devel' of this xinput_calibrator fork created by github user kreijack is libinput-compatible. I built this from source and it worked well for me on a Wacom touchscreen. It has the following (build) dependencies:

These packages bring their own dependencies, a few dozen altogether. The build system needs autoconf, automake, libtool. Assuming project root folder '~/xinput_calibrator', a local build with X11 gui can be configured like so:

$ ./configure --prefix="~/xinput_calibrator" --with-gui=x11

After building and installing the tool can be run from the bin directory that is created in the project root dir:

$ cd ~/xinput_calibrator/bin
$ ./xinput_calibrator

xinput_calibrator, original wiki

archlinux talk about touchscreen calibration

xcal calibration tool, libinput-compatible (by reinderien)

xinput_calibrator fork, libinput-compatibility in branch 'devel' (by kreijack)

libinput library documentation

libinput driver documentation