Touch screen configuration using xinput

When you are trying to configure touch screen on Linux machine, internet offers examples Xorg.conf configuration but without explanation were numbers in it came from. If you have different touch screen you might be out of luck or guess what to do. In this post, I will try to explain how to examine your device using evtest and try out settings using xinput without restarting X server or installing any drivers other than built-in evdev.

microtouch.jpg

We have a couple of 3M MicroTouch M150 touch screens which are VGA monitors (1024*768 resolution) with USB touchscreen interface which is reported as:

dpavlin@t42:~$ lsusb -d 0596:0001
Bus 002 Device 002: ID 0596:0001 MicroTouch Systems, Inc. Touchscreen
A bit of googling later, I found out that there are two different drivers for microtouch devices, but both of them support serial devices only. Not giving up that easily I decided to see what xinput reports about it (without any additional drivers installed!):
dpavlin@t42:~$ xinput list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ 3M 3M USB Touchscreen - EX II             id=9    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     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)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=10   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                    id=13   [slave  keyboard (3)]
This seems like a good news, but when I tried to use it, it seemed that cursor would move only in middle of screen (with X axis swapped) so I wasn't very happy about it. Examining properties of device in more detail revealed that it has property to swap axes and calibrate them, but what to write into those values?
dpavlin@t42:~$ xinput list-props 9
Device '3M 3M USB Touchscreen - EX II':
        Device Enabled (139):   1
        Coordinate Transformation Matrix (141): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        Device Accel Profile (263):     0
        Device Accel Constant Deceleration (264):       1.000000
        Device Accel Adaptive Deceleration (265):       1.000000
        Device Accel Velocity Scaling (266):    10.000000
        Device Product ID (257):        1430, 1
        Device Node (258):      "/dev/input/event7"
        Evdev Axis Inversion (267):     0, 0
        Evdev Axis Calibration (268):   <no items>
        Evdev Axes Swap (269):  0
        Axis Labels (270):      "Abs X" (261), "Abs Y" (262)
        Button Labels (271):    "Button Unknown" (260), "Button Unknown" (260), "Button Unknown" (260), "Button Wheel Up" (145), "Button Wheel Down" (146)
        Evdev Middle Button Emulation (272):    0
        Evdev Middle Button Timeout (273):      50
        Evdev Third Button Emulation (274):     0
        Evdev Third Button Emulation Timeout (275):     1000
        Evdev Third Button Emulation Button (276):      3
        Evdev Third Button Emulation Threshold (277):   20
        Evdev Wheel Emulation (278):    0
        Evdev Wheel Emulation Axes (279):       0, 0, 4, 5
        Evdev Wheel Emulation Inertia (280):    10
        Evdev Wheel Emulation Timeout (281):    200
        Evdev Wheel Emulation Button (282):     4
        Evdev Drag Lock Buttons (283):  0
First task was was to flip x axes to make it move left-right instead of right-left. This can be acomplised using following command:
dpavlin@t42:~$ xinput set-prop 9 267 1 0
Parameters are device id, property id, X axis swap and Y axis swap. If you don't know how many parameters property takes, just put one, try it out and if it returns errors, keep adding parameters until it suceeds.

Next, I needed to calibrate screen to track my finger moving over surface. This is where evtest comes into play. It's low level utility which enables you to see input events before they are passwd to Xorg server. You will have to run it as root as follows:

dpavlin@t42:~$ sudo evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      AT Translated Set 2 keyboard
/dev/input/event1:      Lid Switch
/dev/input/event2:      Sleep Button
/dev/input/event3:      Power Button
/dev/input/event4:      ThinkPad Extra Buttons
/dev/input/event5:      Video Bus
/dev/input/event6:      PC Speaker
/dev/input/event7:      3M 3M USB Touchscreen - EX II
/dev/input/event8:      SynPS/2 Synaptics TouchPad
/dev/input/event9:      TPPS/2 IBM TrackPoint
Select the device event number [0-9]: 7
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x596 product 0x1 version 0x410
Input device name: "3M 3M USB Touchscreen - EX II"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value   7353
      Min        0
      Max    16384
    Event code 1 (ABS_Y)
      Value   4717
      Min        0
      Max    16384
Properties:
Testing ... (interrupt to exit)
Immidiatly we can see minimum and maximum values for both axes and putting figer on top-left corner of screen produced (a lot of) output like this:
Event: time 1386078786.506710, -------------- SYN_REPORT ------------
Event: time 1386078786.510712, type 3 (EV_ABS), code 0 (ABS_X), value 13919
Event: time 1386078786.510712, type 3 (EV_ABS), code 1 (ABS_Y), value 2782
After a few touches I had coordinates which where something like this:
14046,27222380,2986
7994,7819
13743,136162624,13545
Strangly it seems that origin is top-right corner, but we shouldn't care much about it beacuse we can specify them using following command (after rounding them a bit):
dpavlin@t42:~$ xinput set-prop 9 268 2380 14000 2800 13500
Trying it out on screen proved that it now works as expected. Let's call this success and remember that current Xorg knows a lot of tricks itself (recognising USB touch devices is one of them).

As a side note you don't really need to use evtest to get device position. Using xinput list id syntax displays you more-or-less same information, including last point which you touched on device as seen below:

dpavlin@t42:~$ xinput list 9
3M 3M USB Touchscreen - EX II                   id=9    [slave  pointer  (2)]
        Reporting 3 classes:
                Class originated from: 9. Type: XIButtonClass
                Buttons supported: 5
                Button labels: "Button Unknown" "Button Unknown" "Button Unknown" "Button Wheel Up" "Button Wheel Down"
                Button state:
                Class originated from: 9. Type: XIValuatorClass
                Detail for Valuator 0:
                  Label: Abs X
                  Range: 0.000000 - 16384.000000
                  Resolution: 0 units/m
                  Mode: absolute
                  Current value: 13889.000000
                Class originated from: 9. Type: XIValuatorClass
                Detail for Valuator 1:
                  Label: Abs Y
                  Range: 0.000000 - 16384.000000
                  Resolution: 0 units/m
                  Mode: absolute
                  Current value: 2832.000000
However evtest will run in loop until you stop it with Ctrl+C so I find it a little bit easier to use than re-running xinput list id.