- KurtJacobson / touchscreen_calibration.md
- Calibrating Touchscreen
- Using nVidia’s TwinView
- Get to know your system
- Your screen
- Your touch device
- Touch area
- Calculate the Coordinate Transformation Matrix
- Apply the Matrix
- Do it automatically via a udev rule
- Wayland
- Troubleshooting
- Using libinput
- See also
- Калибровка тачскрина
KurtJacobson / touchscreen_calibration.md
Unfortunately xinput-calibrator does not work at all for calibrating a touchscreen in Debian9. This is apparently because X server now uses libinput to handle input devices instead of evdev. I spent huge amount of trying to fiddling with xinput-calibrator and 99-calibration.conf files until I finely found this issue on GitHub that gave me some hints as how to proceed. This is mostly for my own reference, but I hope it might also help others in the same situation.
This not not seem to be installed by defaults on Debian9
$ sudo apt-get install xinput
Determine the screen size
You probably already know this, but if you have multiple screens they might be see as one big screen. So to determine the total size run
This will print out a good bit of information, but what you are interested in is the current vales in the first line, which will look something like this:
Screen 0: minimum 320 x 200, current 1440 x 900, maximum 8192 x 8192
Determine the name of the touch device
Next step it to find the touch device’s name
Look for the touch device in the Virtual core pointer section. In my case the device name is Elo TouchSystems 2700 IntelliTouch(r) .
⎡ Virtual core pointer [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer [slave pointer (2)] ⎜ ↳ Elo TouchSystems 2700 IntelliTouch(r) [slave pointer (2)] ⎜ ↳ 2.4G Mouse [slave pointer (2)] ⎣ Virtual core keyboard [master keyboard (2)] ↳ Virtual core XTEST keyboard [slave keyboard (3)] .
were is the name you determined in the last step.
Confirm that the list of properties includes near the top a property called Coordinate Transformation Matrix . If it does not, you probably have the wrong device name.
Set the Coordinate Transformation Matrix
The screen is calibrated using a Coordinate Transformation Matrix , which defaults to the identity matrix.
for convenient entry, the matrix is flatted into a single line like this
were the valuse seem to map like this
[hscale] [vskew] [hoffset] [hskew] [vscale] [voffset] 0 0 1
Here is a very nice interactive tool for visualizing the effect of the various values: https://codepen.io/GottZ/full/d73f2f844b52b91b7457febce2d1b18c/
Apply the calibration matrix by saying
xinput set-prop » ‘Coordinate Transformation Matrix’ 1.04 0 -0.02 0 1.04 -0.02 0 0 1
I just experimented with the values until I had the scree calibrated, it only took a few iterations to get so the pointer was exactly under were I touched.
Calibrating Touchscreen
To use multiple displays (some of which are touchscreens), you need to tell Xorg the mapping between the touch surface and the screen. This can be done using xinput to set the touchscreen’s coordinate transformation matrix.
This is a guide to do that, the old-fashioned way, in cases when xrandr does not know about your separate screens because they have been merged into one (e.g., when using TwinView). Everyone else, please go to Touchscreen to do it the easy way.
You will need to run the xinput command every time you attach the monitor or log in. Or course, you can add the command to your session-autostart. You can also use Udev to automate this.
Using nVidia’s TwinView
Get to know your system
Your screen
Using TwinView, X will see all your Screens as one big screen. You can get your total height and width by executing
$ xrandr | grep \* # xrandr uses "*" to identify the screen being used
You should see a line like this:
what means, your total width is 3600 and your total height is 1230.
Your touch device
Your next job is to get your device’s name. Execute
and find it by its name. Find the item containing [slave pointer (2)] , which is usually your own device name. E.g. if the line can look like this
⎜ ↳ Acer T230H id=24 [slave pointer (2)]
Tip: If your device contains both a stylus and a touch screen and more touch devices, then please pay attention to the name when determining the device.
$ xinput list-props "Device Name"
and make sure there is a property called
Coordinate Transformation Matrix
(If not, you may probably selected the wrong device, please try another one.)
Touch area
You need to shrink your touch area into a rectangle which is smaller than the total screen. This means, you have to know four values:
- Height of touch area
- Width of touch area
- horizontal offset (x offset) (amount of pixels between the left edge of your total screen and the left edge of your touch area)
- vertical offset (y offset) (amount of pixels between the top edge of your total screen and the top edge of your touch area)
Calculate the Coordinate Transformation Matrix
Now, calculate these as accurate as possible:
- c0 = touch_area_width / total_width
- c2 = touch_area_height / total_height
- c1 = touch_area_x_offset / total_width
- c3 = touch_area_y_offset / total_height
[ c0 0 c1 ] [ 0 c2 c3 ] [ 0 0 1 ]
which is represented as a row-by-row array:
Apply the Matrix
$ xinput set-prop "Device Name" --type=float "Coordinate Transformation Matrix" c0 0 c1 0 c2 c3 0 0 1
$ xinput set-prop "Acer T230H" --type=float "Coordinate Transformation Matrix" 0.533333333 0 0 0 0.87804878 0.12195122 0 0 1
to calibrate your touchscreen device. Now, it should work properly.
Do it automatically via a udev rule
Create a file something like /etc/udev/rules.d/99-acer-touch.rules with contents like this:
/etc/udev/rules.d/99-acer-touch.rules
ENV=="2149",ENV=="2703",ENV="DVI1",ENV="1 0 0 0 1 0"
Substitute your own touchscreen’s vendor ID, model ID, the xrandr output name, and the calibration matrix that you calculated above. This is based on the assumption that you are using the libinput driver for your touchscreen.
Wayland
Using libinput you can calibrate your touchscreen on Wayland compositors. See the libinput documentation.
If you have weston installed, you can use the weston-calibrator utility to get the transformation matrix. You can then apply it using a udev rule.
Troubleshooting
If, after following these instructions, multiple clicks occur in different places when you touch the screen, you will need to build the xorg-server package using the ABS, applying this patch before you build the package. (This patch fails on the current xorg source, but the bug is present on at least 1 system.)
Using libinput
The libinput package provides a few utilities to debug input events:
- The libinput debug-events command provides a list of events emitted by all devices, including the touchscreen driver. You can use the —verbose option to get more information.
- libinput debug-gui provides a graphical debug environment. This can be useful to verify visually that the transformation matrix has the correct values.
- libinput list-devices lists all input devices. This can be useful to identify the name and eventual attributes of an input device. Using this command you can also verify that the transformation matrix was applied correctly.
For more information see the troubleshooting section of the libinput page.
See also
Калибровка тачскрина
Тачскрин работает, но неправильно, нужно откалибровать. Установил и запустил xinput_calibrator , ткнул 4 точки. Ничего не изменилось (хотя на этом этапе уже должно правильно работать!) Попробовал по указанию программы сохранить настройки в файлик /usr/share/X11/xorg.conf.d/99-calibration.conf :
Section "InputClass" Identifier "calibration" MatchProduct "Silead GSLx680 Touchscreen" Option "MinX" "67097" Option "MaxX" "401" Option "MinY" "-8966" Option "MaxY" "62759" 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
В этой директории и другие похожие файлы есть, вроде 70-wacom.conf и пр. После ребута так же ничего не изменилось. Попробовал и в /etc/X11/xorg.conf.d/ закинуть (директорию пришлось создать) – так же ничего не поменялось.
Вот еще информация, которая может помочь: xinput -list
⎡ Virtual core pointer [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer [slave pointer (2)] ⎜ ↳ SteelSeries Rival Gaming Mouse [slave pointer (2)] ⎜ ↳ SteelSeries Rival Gaming Mouse [slave pointer (2)] ⎜ ↳ Silead GSLx680 Touchscreen [slave pointer (2)] ⎜ ↳ ImPS/2 Logitech Wheel Mouse [slave pointer (2)] ⎣ Virtual core keyboard [master keyboard (2)] ↳ Virtual core XTEST keyboard [slave keyboard (3)] ↳ Power Button [slave keyboard (3)] ↳ Video Bus [slave keyboard (3)] ↳ Power Button [slave keyboard (3)] ↳ SteelSeries Rival Gaming Mouse [slave keyboard (3)] ↳ PC Cam [slave keyboard (3)] ↳ AT Translated Set 2 keyboard [slave keyboard (3)] ↳ SteelSeries Rival Gaming Mouse [slave keyboard (3)]
(Мой девайс под номером 13)
Device 'Silead GSLx680 Touchscreen': Device Enabled (155): 1 Coordinate Transformation Matrix (157): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Calibration Matrix (314): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Calibration Matrix Default (315): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Send Events Modes Available (279): 1, 0 libinput Send Events Mode Enabled (280): 0, 0 libinput Send Events Mode Enabled Default (281): 0, 0 Device Node (282): "/dev/input/event9" Device Product ID (283): 0, 0
Попробовал поиграться с set-prop – тоже безрезультатно. Свойство вроде применяется (?), но эффекта нет. xinput set-prop 13 —type=atom —format=32 InvertX 1 , xinput list-props 13 :
Device 'Silead GSLx680 Touchscreen': Device Enabled (155): 1 Coordinate Transformation Matrix (157): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Calibration Matrix (314): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Calibration Matrix Default (315): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000 libinput Send Events Modes Available (279): 1, 0 libinput Send Events Mode Enabled (280): 0, 0 libinput Send Events Mode Enabled Default (281): 0, 0 Device Node (282): "/dev/input/event9" Device Product ID (283): 0, 0 InvertX (578): "PRIMARY" (1)
Этот тред я читал, но не понял, как тамошний гуру всё разрулил, да и у того человека калибровка уже работала, а у меня ничего.