Touch screen calibration

Posted by rajmohan on Mon, 09 Sep 2019 09:26:52 +0200

Some devices have inaccurate touch screens and need to be corrected before they can be used properly. Correction is actually to configure the properties of the device in Xorg. The specific attribute names are related to the driver, which will be described later.

Note: All the operations in this paper are done on deepin. Please look up the package names by yourself.

The following is the introduction of the correction method:

Get ready

Install the tools needed:

  • xinput-calibrator: touch screen correction tool
  • xinput: Screen Mapping Tool, Used in Multi-Screen

Correcting

  1. Execute xinput_calibrator --list to view the list of touch devices

  2. Xinput_calibrator-v--device <device name or id>

    device name or id is obtained from the list above

At this time, there will be a correction interface, click on the prompt, after success, the program will output the corrected data.

Then, according to the different settings of drivers, the driver used by the viewing device can be obtained through the / var/log/Xorg.0.log file.

  • evdev

    The output data of xinput_calibrator can be used directly when using evedev driver without any other settings.

    The Evdev Axis Calibration property is set using xinput during the test.

  • libinput

    When using libinput driver, the output data of xinput_calibrator need to be calculated before it can be used. Libinput breaks xinput_calibrator

    Here the calculation method is written into a script, which reads as follows:

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    import sys
    
    def usage():
        info = "Usage: " + sys.argv[0]
        info += " <screen_width> <screen_height>"
        info += " <click_0_x> <click_0_y>"
        info += " <click_3_x> <click_3_y>"
        print(info)
        print("\tScreen width/hight by the command 'xrandr|grep screen' got")
        print("\tClick x/y by the command 'xinput_calibrator -v' got")
        sys.exit(0)
    
    def convert(screen_x, screen_y, c0_x, c0_y, c3_x, c3_y):
        a = (screen_x * 6 / 8) / (c3_x - c0_x)
        c = ((screen_x / 8) - (a * c0_x)) / screen_x
        e = (screen_y * 6 / 8) / (c3_y - c0_y)
        f = ((screen_y / 8) - (e * c0_y)) / screen_y
    
        print("Try set 'libinput Calibration Matrix' to '%.1f, 0.0, %.1f, 0.0, %.1f, %.1f, 0.0, 0.0, 1.0'" % (a,c,e, f))
    
    if __name__ == "__main__":
        if len(sys.argv) != 7:
            usage()
    
        convert(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]),
        int(sys.argv[4]),int(sys.argv[5]),int(sys.argv[6]))
    

    The libinput Calibration Matrix property is set using xinput during the test.

    If there is still a problem after setting the values calculated above, try Calculate the Coordinate Transformation Matrix This method of calculation.

    If you can't switch to evdev driver, install xserver-xorg-input-evdev and add 99-touch screen-evdev.conf to the / etc/X11/xorg.conf.d directory, as follows:

    Section "InputClass"
          Identifier	"calibration"
          Driver	"evdev"
          MatchProduct	"<touchscreen product>"
    EndSection
    

    The touchscreen product can be obtained from / var/log/Xorg.0.log.

Example

For example, the output of the correction operation performed on Huawei is as follows:

deepin@deepin-PC:~$ xinput_calibrator -v
DEBUG: XInputExtension version is 2.3
DEBUG: Skipping virtual master devices and devices without axis valuators.
DEBUG: Skipping device 'Virtual core XTEST pointer' id=4, does not report Absolute events.
DEBUG: Skipping device 'SYNA1D31:00 06CB:CD48 Touchpad' id=12, does not report Absolute events.
DEBUG: Selected device: SYNA2393:00 06CB:19AC
DEBUG: Not usbtouchscreen calibrator: Not a usbtouchscreen device
DEBUG: Evdev Axis Calibration not set, setting to axis valuators to be sure.
        Setting calibration data: 0, 3000, 0, 2000
DEBUG: Successfully applied axis calibration.
DEBUG: Read axes swap value of 0.
DEBUG: Read InvertX=0, InvertY=0.
Calibrating EVDEV driver for "SYNA2393:00 06CB:19AC" id=11
        current calibration values (from XInput): min_x=0, max_x=3000 and min_y=0, max_y=2000
DEBUG: Found that 'SYNA2393:00 06CB:19AC' is a sysfs name.
DEBUG: Adding click 0 (X=382, Y=246)
DEBUG: Adding click 1 (X=2647, Y=246)
DEBUG: Adding click 2 (X=376, Y=1761)
DEBUG: Adding click 3 (X=2640, Y=1764)

Doing dynamic recalibration:
        Setting calibration data: 2, 3021, -7, 2015
DEBUG: Successfully applied axis calibration.
        --> Making the calibration permanent <--
DEBUG: Found that 'SYNA2393:00 06CB:19AC' is a sysfs name.
  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	"SYNA2393:00 06CB:19AC"
        Option	"Calibration"	"2 3021 -7 2015"
        Option	"SwapAxes"	"0"
EndSection

The device driver related logs in Xorg.0.log are as follows:

[  7221.421] (II) config/udev: Adding input device SYNA2393:00 06CB:19AC (/dev/input/event7)
[  7221.421] (**) SYNA2393:00 06CB:19AC: Applying InputClass "evdev touchscreen catchall"
[  7221.421] (**) SYNA2393:00 06CB:19AC: Applying InputClass "libinput touchscreen catchall"
[  7221.421] (**) SYNA2393:00 06CB:19AC: Applying InputClass "calibration"
[  7221.421] (II) LoadModule: "evdev"
[  7221.421] (II) Loading /usr/lib/xorg/modules/input/evdev_drv.so
[  7221.421] (II) Module evdev: vendor="X.Org Foundation"
[  7221.421]    compiled for 1.19.1, module version = 2.10.5
[  7221.421]    Module class: X.Org XInput Driver
[  7221.421]    ABI class: X.Org XInput driver, version 24.1
[  7221.421] (II) Using input driver 'evdev' for 'SYNA2393:00 06CB:19AC'
  • evdev

Execute the command XInput set-prop 11 Evdev Axis Calibration 2 3021-7 to test the effect in 2015

  • libinput

Using the values of click 0 and click 3 above and screen width/height calculated by xrandr, the values are as follows:

$ python3 ./touchscreen_calibration_convert.py 344 193 382 246 376 1761
Try set 'libinput Calibration Matrix' to '-43.0, 0.0, 47.9, 0.0, 0.1, 0.0, 0.0, 0.0, 1.0'

Execute the command XInput set-prop 11 libinput Calibration Matrix-43.0 0 0.47.9 0.0 0 0.1 0.0 0 0.0 0 0.0 1.0 to test the effect.

Additional questions

Some devices still have some problems after they have been set up according to the above steps. Here are some of the problems encountered. Once these situations occur, please switch to evdev first and then set them up.

On the contrary

If you click on the top left corner and feed back to the bottom left corner, add Option InvertY "true" in 90-touch screen-calibrator.conf.

Left and right opposite

If you click on the top left corner and feed back to the bottom right corner, add Option InvertX "true" in 90-touch screen-calibrator.conf.

Edge migration

If you click on the right-most area but feed back to the next area, you can adjust the value of Option Calibration, which contains "min-x max-x min-y max-y". Try on all four edges and adjust the corresponding values.

XY Conversely

If you click on the top left corner and feed back to the top right corner, add Option SwapAxes "true" in 90-touch screen-calibrator.conf.

Persistence

After the above tests are correct, they are integrated into the system and executed automatically every time they start up.

Auto-execution is performed by xorg.conf.d hook, adding 90-touch screen-calibrator.conf to / etc/X11/xorg.conf.d/directory.

evdev

The examples are as follows:

Section "InputClass"
        Identifier	"calibration"
        MatchProduct	"SYNA2393:00 06CB:19AC"
        Option	"Calibration"	"2 3021 -7 2015"
        Option	"SwapAxes"	"0"
EndSection

libinput

The examples are as follows:

Section "InputClass"
        Identifier	"calibration"
        MatchProduct	"SYNA2393:00 06CB:19AC"
        Option	"CalibrationMatrix"	"-43.0 0.0 47.9 0.0 0.1 0.0 0.0 0.0 1.0"
EndSection

Device mapping

If there are multiple screens, then you need to specify the device corresponding to the touch screen, using XInput -- map-output-to <device id> <output name>.

device name is the id obtained above, and output name can be obtained through the xrandr command.

Persistence

You can add 90-touch screen-map to the / etc/X11/xinit/xinitrc.d directory, which is the command above.

Reference Documents

  • Man4 evdev: xserver-xorg-input-evdev needs to be installed
  • Man4 libinput: You need to install xserver-xorg-input-libinput

Topics: Attribute