10

I'm looking for a reliable way to detect if a laptop has a touchscreen device from a script. I know I can parse the output of:

$ xinput --list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ ELAN Touchscreen                          id=10   [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                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)]
    ↳ TOSHIBA Web Camera - HD                   id=9    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ Toshiba input device                      id=13   [slave  keyboard (3)]

But ideally I'd prefer not having to rely on a product name. Actually I'm looking for a flag clearly stating that such device exist on my test system.

Sylvain Pineau
  • 61,564
  • 18
  • 149
  • 183

3 Answers3

11

udev already classifies the input devices (See https://wiki.kubuntu.org/X/InputConfiguration), the supported flags are:

  • ID_INPUT

    All input devices have this flag.

  • ID_INPUT_MOUSE

    Touchscreens and tables have this flag as well, since by the type of events they can produce they act as a mouse.

  • ID_INPUT_TABLET

  • ID_INPUT_TOUCHSCREEN

  • ID_INPUT_JOYSTICK

  • ID_INPUT_KEY

    Keyboards have this, but also things like lid switches which have just a few buttons

  • ID_INPUT_KEYBOARD

So an easy way to check in the system under test has a touchscreen device is to parse the output of udevadm info --export-db for the following section:

P: /devices/pci0000:00/0000:00:14.0/usb2/2-7/2-7:1.0/input/input14
E: ABS=273800000000003
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb2/2-7/2-7:1.0/input/input14
E: EV=10000b
E: ID_BUS=usb
E: ID_INPUT=1
E: ID_INPUT_TOUCHSCREEN=1
E: ID_MODEL=Touchscreen
E: ID_MODEL_ENC=Touchscreen
E: ID_MODEL_ID=0100
E: ID_PATH=pci-0000:00:14.0-usb-0:7:1.0
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_7_1_0
E: ID_REVISION=1110
E: ID_SERIAL=ELAN_Touchscreen
E: ID_TYPE=hid
E: ID_USB_DRIVER=usbhid
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=ELAN
E: ID_VENDOR_ENC=ELAN
E: ID_VENDOR_ID=04f3
E: KEY=400 0 0 0 0 0
E: MODALIAS=input:b0003v04F3p0100e0110-e0,1,3,14,k14A,ra0,1,2F,30,31,34,35,36,39,mlsfw
E: NAME="ELAN Touchscreen"
E: PHYS="usb-0000:00:14.0-7/input0"
E: PRODUCT=3/4f3/100/110
E: PROP=2
E: SUBSYSTEM=input
E: UDEV_LOG=3
E: UNIQ=""
E: USEC_INITIALIZED=815199186

The command to use is finally:

udevadm info --export-db | grep ID_INPUT_TOUCHSCREEN=1
Sylvain Pineau
  • 61,564
  • 18
  • 149
  • 183
0

Based on original answer, I wrote small parsing script, which extract name of the touchscreen.

#!/bin/bash
tmp_dir=$(mktemp -d)
pushd $tmp_dir > /dev/null
# Export whole database 
udevadm info --export-db > udevdb.txt
csplit -s udevdb.txt /^$/ {*}

FILES=./xx*
for f in $FILES
do
  if [[ ! -z $(grep ID_INPUT_TOUCHSCREEN=1 $f) ]] && [[ ! -z $(grep " NAME=*" $f) ]]; 
  then
        # Extract touchscreen name
        grep " NAME=*" $f | cut -d "=" -f 2
  fi
done
popd > /dev/null
rm -rf $tmp_dir
Pablo Bianchi
  • 14,308
  • 4
  • 74
  • 117
artsin
  • 121
  • 5
0

To build upon Sylvain Pineau's answer: Using awk instead of grep you can get all information of the block(s) the ID_INPUT_TOUCHSCREEN=1 was found in.

$ udevadm info --export-db | awk '/ID_INPUT_TOUCHSCREEN=1/' RS=

Further, if you want to get the device path(s) of the touch screen(s), you can do

$ udevadm info --export-db | awk '/ID_INPUT_TOUCHSCREEN=1/' RS= | grep "^E: DEVPATH="
E: DEVPATH=/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-WCOM486A:00/0018:056A:486A.0002/input/input19
E: DEVPATH=/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-WCOM486A:00/0018:056A:486A.0002/input/input19/event7
E: DEVPATH=/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-0/i2c-WCOM486A:00/0018:056A:486A.0002/input/input19/mouse2
E: DEVPATH=/devices/pci0000:00/0000:00:1d.0/0000:04:00.0/0000:05:04.0/0000:3b:00.0/0000:3c:04.0/0000:3e:00.0/0000:3f:04.0/0000:41:00.0/usb5/5-2/5-2.1/5-2.1:1.0/0003:222A:0001.000D/input/input29
E: DEVPATH=/devices/pci0000:00/0000:00:1d.0/0000:04:00.0/0000:05:04.0/0000:3b:00.0/0000:3c:04.0/0000:3e:00.0/0000:3f:04.0/0000:41:00.0/usb5/5-2/5-2.1/5-2.1:1.0/0003:222A:0001.000D/input/input29/event5
E: DEVPATH=/devices/pci0000:00/0000:00:1d.0/0000:04:00.0/0000:05:04.0/0000:3b:00.0/0000:3c:04.0/0000:3e:00.0/0000:3f:04.0/0000:41:00.0/usb5/5-2/5-2.1/5-2.1:1.0/0003:222A:0001.000D/input/input29/mouse0

Or to get the name(s) of the touch screen(s):

$ udevadm info --export-db | awk '/ID_INPUT_TOUCHSCREEN=1/' RS= | grep "^E: NAME=" | cut -d '"' -f2
Wacom HID 486A Finger
ILITEK ILITEK-TP

(I ran these commands on a system with two touch screens. One of them is an external USB-C one and the other one is a built-in PCI (or i²C?) one.)

Forivin
  • 358
  • 4
  • 14