How to set up touchscreen on Linux (on X-server or Wayland)
Step-by-step guide to detect, map, and calibrate touchscreens on Linux , covering xinput, xrandr, xinput_calibrator, and persistent Xorg configuration.
Table of Contents
- Table of Contents
- Step 0: Check if device is supported by the kernel
- [If kernel do not detect] Get X11 drivers
- [Optional] Touchscreen in a multi-screen setup: Adjust the Coordinate Transformation Matrix
- Calibrate: Adjust the Axis Calibration Matrix
- [Optional] Gestures and Two-fingers scrolling
- References
Step 0: Check if device is supported by the kernel
/proc/bus/input/devices file lists all input devices the Linux kernel currently knows about.
1
cat /proc/bus/input/devices
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[...]
I: Bus=0003 Vendor=1fd2 Product=8105 Version=0111
N: Name="Melfas LGDisplay Incell Touch" # Name of the device.
P: Phys=usb-0000:00:14.0-4.3.2.1/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.3/1-4.3.2/1-4.3.2.1/1-4.3.2.1:1.0/0003:1FD2:8105.0002/input/input16
U: Uniq=
H: Handlers=mouse0 event15 # Assigned handlers
B: PROP=2
B: EV=1b
B: KEY=400 0 0 0 0 0
B: ABS=260800000000003
B: MSC=20
[...]
Verify it’s the right device /dev/input/eventX and touching the screen. If you see characters streaming, that’s the one to use with xinput.
1
sudo cat /dev/input/event15
Output touching the screen:
[If kernel do not detect] Get X11 drivers
Depending on your touchscreen device choose an appropriate driver. You can use proprietary (if it’s available) or open source driver. The most common open-source drivers are:
- evdev: Generic input event interface in the Linux kernel and FreeBSD.
- libinput: For Wayland/Weston compositor.
libinput/libevdev sit between the kernel and the user-level input handler, translating kernel events into a device API used by X or Wayland.
- kernel → libevdev → xf86-input-evdev → X server → X client
For Wayland/Weston compositor, the stack would look like this:
- kernel → libevdev → libinput → Wayland compositor → Wayland client
Since xorg-server 1.16, X supports
libinputvia thexf86-input-libinputdriver:
- kernel → libevdev → libinput → xf86-input-libinput → X server → X client
[Extra] How to see the driver you are using
Method 1: xinput list-props
First get device name (in my case Melfas LGDisplay Incell Touch):
1
xinput
Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Melfas LGDisplay Incell Touch id=10 [slave pointer (2)]
⎜ ↳ Logitech Wireless Mouse PID:4022 id=11 [slave pointer (2)]
⎜ ↳ Logitech Wireless Keyboard PID:4023 id=12 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Power Button id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ Dell WMI hotkeys id=13 [slave keyboard (3)]
↳ Dell AIO WMI hotkeys id=14 [slave keyboard (3)]
↳ Logitech Wireless Keyboard PID:4023 id=15 [slave keyboard (3)]
And then get more detailed information:
1
xinput list-props "Melfas LGDisplay Incell Touch"
On the output you can see how the device use libinput driver:
1
2
3
4
5
6
7
8
9
10
Device 'Melfas LGDisplay Incell Touch':
Device Enabled (179): 1
Coordinate Transformation Matrix (181): 0.500000, 0.000000, 0.500000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
libinput Calibration Matrix (318): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
libinput Calibration Matrix Default (319): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
libinput Send Events Modes Available (301): 1, 0
libinput Send Events Mode Enabled (302): 0, 0
libinput Send Events Mode Enabled Default (303): 0, 0
Device Node (304): "/dev/input/event15"
Device Product ID (305): 8146, 33029
Method 2: System logs
Search for device name on system general logs (in my case Melfas LGDisplay Incell Touch):
1
sudo journalctl | grep "'Melfas LGDisplay Incell Touch'"
Note that I use
'simple quotes on thegrepcommand.
And on the output find a line similar to this one, that as you can see says that the input driver is libinput:
1
(II) Using input driver 'libinput' for 'Melfas LGDisplay Incell Touch'
[Optional] Touchscreen in a multi-screen setup: Adjust the Coordinate Transformation Matrix
You need to map the touchscreen to your actual touchscreen display. This is made by xinput’s map-to-output option.
1
2
# Generic command
xinput map-to-output <touch-input device (name or id)> <output name>
To get the touch-input device name execute xinput, and see the output (In this case is Melfas LGDisplay Incell Touch):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Melfas LGDisplay Incell Touch id=10 [slave pointer (2)]
⎜ ↳ Logitech Wireless Mouse PID:4022 id=11 [slave pointer (2)]
⎜ ↳ Logitech Wireless Keyboard PID:4023 id=12 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Power Button id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ Dell WMI hotkeys id=13 [slave keyboard (3)]
↳ Dell AIO WMI hotkeys id=14 [slave keyboard (3)]
↳ Logitech Wireless Keyboard PID:4023 id=15 [slave keyboard (3)]
Now to know device output interface name execute xrandr, and see the output ():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Screen 0: minimum 320 x 200, current 3840 x 1080, maximum 16384 x 16384
HDMI-1 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 527mm x 296mm
1920x1080 60.00*+ 50.00 59.94
1920x1080i 60.00 50.00 59.94
1600x900 60.00
1280x1024 75.02 60.02
[...]
DP-2-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
1920x1080 60.00*+ 50.00 59.94
1600x1200 60.00
1600x900 60.00
1280x1024 75.02 60.02
1152x864 75.00
[...]
In this case is HDMI-1, I know it because the touchscreen isn’t the primary monitor.
If unsure which touchscreen corresponds to which monitor, temporarily map it to an output, touch the screen, and verify the pointer moves only on that monitor.
So the final command to map the touch input to output monitor is:
1
xinput map-to-output "Melfas LGDisplay Incell Touch" HDMI-1
Calibrate: Adjust the Axis Calibration Matrix
The tool to calibrate a touchscreen is called xinput_calibrator.
xinput_calibrator works only for single-screen setups. It sets the device’s “Axis Calibration Matrix” and doesn’t account for a “Coordinate Transformation Matrix” used when mapping to a specific output. It also always opens stretched to the full available output area.
Calibration tool with all displays on
Calibration tool only with touchscreen displays on
- Turn off all the monitor except the one that you want to calibrate →
xrandr --output <non-touch-output> --off - Reset “Coordinate Transformation Matrix” if you map it before →
xinput map-to-output <touch input device> <touch-output> - Calibrate with →
xinput_calibrator. You should now have well-calibrated touch on the single screen. - Re-enable the other monitors →
xrandr --output <non-touch-output> --mode <resolution>. If you need position options use--right-of,--left-of,--above,--belowplace the monitor relative to another. - Map the touchscreen again to his monitor →
xinput map-to-output <touch input device> <touch-output>
Permanent calibration: xorg.conf.d
To make the new values permanent you need to create a configuration files for Xorg X server (normally on /usr/share/X11/xorg.conf.d/ on Debian based OS), named with a sufficiently low priority (90-calibration.conf). The file’s data will be:
1
2
3
4
5
6
7
8
9
Section "InputClass"
Identifier "calibration"
MatchProduct "<DEVICE_NAME_FROM_XINPUT_LIST>"
Option "TransformationMatrix" "<VALUES_FROM(Coordinate Transformation Matrix)>"
Option "Calibration" "<VALUES_FROM(Evdev Axis Calibration)>"
Option "SwapAxes" "<VALUE_FROM(Evdev Axes Swap)>"
Option "InvertX" "<X_VALUE_FROM(Evdev Axis Inversion)>"
Option "InvertY" "<Y_VALUE_FROM(Evdev Axis Inversion)>"
EndSection
[Optional] Gestures and Two-fingers scrolling
You can try installing Touchegg, an app that runs in the background and transform the gestures you make on your touchpad or touchscreen into visible actions in your desktop.

