3

Background info:
I've got a buggy touchscreen on a laptop, and I used to have a special Bash script on startup for dealing with it, but I recently installed PureOS in an effort to be a little more in-line to GNU's recommendations. I've given up on finding anything remotely close to xinput in the Wayland ecosystem, however I don't like running legacy software unless absolutely forced to. Methods such as tampering with drivers and whatever information libinput gives is of no use. The only command that was able to halt the nearly pseudo-random behavior of my touchscreen is the sacred evtest --grab. I'd like to stress that without disabling my touchscreen, my work laptop is absolutely useless (apart from TTY).


Important part:
I've been trying to create a script that will

  1. Retrieve a list of input devices: cat /proc/bus/input/devices
  2. Parse the output to find the paragraph with "ELAN0732:00 04F3:264C" (I've tried approaching this with awk but I do not know it well enough)
  3. Differentiate between the above and "ELAN0732:00 04F3:264C Pen" (which are two different devices, the Pen isn't causing any issues but I don't need it, so if it is also disabled as a consequence I don't mind)
  4. Within that paragraph, find a statement that includes eventN where N is random at each reboot (using grep/awk)
  5. Run sudo evtest --grab /dev/input/event$N > /dev/null

Thereafter, I would place this script in a place in which it will run at boot with root privileges (I've seen something about /etc/rc.local, but haven't tried it yet)

evtest already prints the input devices in single lines, and I put together variants of this:

sudo timeout 2 evtest --grab | grep "ELAN073 | grep "ELAN0732:00 04F3:264C"

however grep doesn't parse correctly (probably due to the way stdout gets piped with timeout), but even then it probably would be better to parse /proc/bus/input/devices with awk (as per the above steps) rather than running a command, piping the output, killing the command, parsing it, running it again.


Additional info:
PureOS 9.0 (based on Debian testing), Linux 4.19.0-5-amd64
cat /proc/bus/input/devices prints:

N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input0
U: Uniq=
H: Handlers=sysrq kbd leds event0 
B: PROP=0
B: EV=120013
B: KEY=20000 20 0 0 1500f02100000 3803078f900d401 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7

I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=PNP0C0C/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input2
U: Uniq=
H: Handlers=kbd event1 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

I: Bus=0019 Vendor=0000 Product=0005 Version=0000
N: Name="Lid Switch"
P: Phys=PNP0C0D/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input3
U: Uniq=
H: Handlers=event2 
B: PROP=0
B: EV=21
B: SW=1

I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input4
U: Uniq=
H: Handlers=kbd event3 
B: PROP=0
B: EV=3
B: KEY=10000000000000 0

I: Bus=0019 Vendor=0000 Product=0006 Version=0000
N: Name="Video Bus"
P: Phys=LNXVIDEO/video/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:14/LNXVIDEO:02/input/input6
U: Uniq=
H: Handlers=kbd event4 
B: PROP=0
B: EV=3
B: KEY=3e000b00000000 0 0 0

I: Bus=0011 Vendor=0002 Product=0007 Version=01a1
N: Name="SynPS/2 Synaptics TouchPad"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input5
U: Uniq=
H: Handlers=mouse2 event9 
B: PROP=5
B: EV=b
B: KEY=e520 10000 0 0 0 0
B: ABS=660800011000003

I: Bus=0019 Vendor=0000 Product=0000 Version=0000
N: Name="HP Wireless hotkeys"
P: Phys=hpq6001/input0
S: Sysfs=/devices/virtual/input/input13
U: Uniq=
H: Handlers=kbd event10 rfkill 
B: PROP=0
B: EV=3
B: KEY=80000000000000 0 0 0

I: Bus=0010 Vendor=001f Product=0001 Version=0100
N: Name="PC Speaker"
P: Phys=isa0061/input0
S: Sysfs=/devices/platform/pcspkr/input/input14
U: Uniq=
H: Handlers=kbd event11 
B: PROP=0
B: EV=40001
B: SND=6

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HD-Audio Generic HDMI/DP,pcm=3"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:08.1/0000:03:00.1/sound/card0/input15
U: Uniq=
H: Handlers=event12 
B: PROP=0
B: EV=21
B: SW=140

I: Bus=0003 Vendor=04f2 Product=b634 Version=0012
N: Name="HP Wide Vision FHD Camera: HP W"
P: Phys=usb-0000:03:00.4-1/button
S: Sysfs=/devices/pci0000:00/0000:00:08.1/0000:03:00.4/usb3/3-1/3-1:1.0/input/input16
U: Uniq=
H: Handlers=kbd event13 
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HD-Audio Generic Mic"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:08.1/0000:03:00.6/sound/card1/input17
U: Uniq=
H: Handlers=event5 
B: PROP=0
B: EV=21
B: SW=10

I: Bus=0019 Vendor=0000 Product=0000 Version=0000
N: Name="HP WMI hotkeys"
P: Phys=wmi/input0
S: Sysfs=/devices/virtual/input/input19
U: Uniq=
H: Handlers=kbd event6 
B: PROP=0
B: EV=33
B: KEY=4000000000 0 1000700000000 2102400 0 0
B: MSC=10
B: SW=0

I: Bus=0003 Vendor=04f2 Product=b634 Version=0012
N: Name="HP Wide Vision FHD Camera: HP I"
P: Phys=usb-0000:03:00.4-1/button
S: Sysfs=/devices/pci0000:00/0000:00:08.1/0000:03:00.4/usb3/3-1/3-1:1.2/input/input20
U: Uniq=
H: Handlers=kbd event14 
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="HD-Audio Generic Headphone"
P: Phys=ALSA
S: Sysfs=/devices/pci0000:00/0000:00:08.1/0000:03:00.6/sound/card1/input18
U: Uniq=
H: Handlers=event7 
B: PROP=0
B: EV=21
B: SW=4

# THIS IS THE PARAGRAPH I NEED
I: Bus=0018 Vendor=04f3 Product=264c Version=0100
N: Name="ELAN0732:00 04F3:264C"
P: Phys=i2c-ELAN0732:00
S: Sysfs=/devices/platform/AMDI0010:00/i2c-0/i2c-ELAN0732:00/0018:04F3:264C.0001/input/input21
U: Uniq=
H: Handlers=mouse0 event8 #THIS IS THE EVENT NUMBER I NEED
B: PROP=2
B: EV=1b
B: KEY=400 0 0 0 0 0
B: ABS=3273800000000003
B: MSC=20

# THIS PARAGRAPH SHOULD BE IGNORED, OR BOTH CAN BE USED, BUT NOT EXCLUSIVELY THIS ONE
I: Bus=0018 Vendor=04f3 Product=264c Version=0100
N: Name="ELAN0732:00 04F3:264C Pen"
P: Phys=i2c-ELAN0732:00
S: Sysfs=/devices/platform/AMDI0010:00/i2c-0/i2c-ELAN0732:00/0018:04F3:264C.0001/input/input24
U: Uniq=
H: Handlers=mouse1 event15 
B: PROP=0
B: EV=1b
B: KEY=c03 0 0 0 0 0
B: ABS=1000003
B: MSC=10

I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="BRLTTY 5.6 Linux Screen Driver Keyboard"
P: Phys=pid-692/brltty/14
S: Sysfs=/devices/virtual/input/input27
U: Uniq=
H: Handlers=sysrq kbd event16 
B: PROP=0
B: EV=100003
B: KEY=402000007 ffc03078f800d2a9 f2beffdfffefffff fffffffffffffffe

I: Bus=0005 Vendor=045e Product=082f Version=0206
N: Name="Microsoft Bluetooth Mouse Mouse"
P: Phys=80:2B:F9:52:CA:DC
S: Sysfs=/devices/virtual/misc/uhid/0005:045E:082F.0002/input/input28
U: Uniq=DD:47:30:64:95:63
H: Handlers=mouse3 event17 
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0
B: REL=143
B: MSC=10

I: Bus=0005 Vendor=045e Product=082f Version=0206
N: Name="Microsoft Bluetooth Mouse Keyboard"
P: Phys=80:2B:F9:52:CA:DC
S: Sysfs=/devices/virtual/misc/uhid/0005:045E:082F.0002/input/input29
U: Uniq=DD:47:30:64:95:63
H: Handlers=sysrq kbd event18 
B: PROP=0
B: EV=100013
B: KEY=1000000000007 ff800000000007ff febeffdff3cfffff fffffffffffffffe
B: MSC=10

I: Bus=0005 Vendor=045e Product=082f Version=0206
N: Name="Microsoft Bluetooth Mouse"
P: Phys=80:2B:F9:52:CA:DC
S: Sysfs=/devices/virtual/misc/uhid/0005:045E:082F.0002/input/input30
U: Uniq=DD:47:30:64:95:63
H: Handlers=event19 
B: PROP=0
B: EV=9
B: ABS=10000000000

I: Bus=0005 Vendor=0000 Product=0000 Version=0000
N: Name="00:0A:45:0A:FB:49"
P: Phys=
S: Sysfs=/devices/virtual/input/input33
U: Uniq=
H: Handlers=kbd event20 
B: PROP=0
B: EV=100007
B: KEY=2fc800 145200000000 0 10300 49e800000c00 e16800000000f f810000010000ffc
B: REL=0

3 Answers 3

3

This should be a suitable awk script:

device=$( cat /proc/bus/input/devices |
  awk '
  /"ELAN0732:00 04F3:264C"/{ inside = 1 }
  /Handlers=/  { if(match($0,"event([0-9]+)",group))event = group[1] }
  /^$/         { if(inside && event!="")print "/dev/input/event" event
                 inside = 0; event = ""
  }')
if [ -n "$device" ]
then sudo evtest --grab "$device" > /dev/null &
fi

The first line matches the wanted string and sets variable inside to note we are in the right stanza. The next line finds the Handlers and uses match(string, regexp, returnarray) to look for the regexp event[0-9]+ and captures the digits () into the array group, and then sets variable event.

Finally, we match the empty line at the end of every stanza (including the last), and if we are inside and have an event number, print the device path concatenated with the event number.

If your awk is POSIX rather than GNU replace the Handlers line with

/Handlers=/{ if(split($0,part,"event"))event = part[2]+0 }

which splits the line at the word "event", then converts the following characters into a number.

If the above script is written directly onto /etc/rc.local, make sure that you run sudo chmod +x /etc/rc.local or it will not execute.

The & in the end of the command in necessary for Systemd to not hang at boot (as it expects an exit before continuing, and we need it instead to run throughout the entire uptime). The /dev/null attempts to ignore the standard output that evtest uses to report touchscreen use, in an effort to save memory. Adding /dev/null may be trivial, however can't hurt.

4
  • Thanks for your effort! I'll have to learn awk someday However when running i'm receiving awk: line 3: syntax error at or near , im guessing the error is in the match function, the only place with commas May 18, 2020 at 18:53
  • I was assuming that since PureOS says it's FOSS etc the awk would be gnu awk, as the 3rd arg to match() is a gnu extension. Perhaps you just need to use gawk instead of awk. If not I'll add a posix version above.
    – meuh
    May 18, 2020 at 19:11
  • made some final edits after optimizing the implementation a bit (reduced the memory usage from 228 KiB to 72 KiB). Thanks a lot for the help!! May 18, 2020 at 22:40
  • 3
    Nice solution! I've adapted it for a toggle script I map to an Fx key in my desktop environment, allowing me to easily enable/disable the touchscreen on both Xorg and XWayland.
    – JinnKo
    Jun 22, 2020 at 15:26
1

Oh. Thanks so much for this question which is actually giving me the answer on how to disable touchscreen. Mine kinda works, until suddenly it goes all ballistic and clicks everything on the screen a lot.

The accepted solution is nice and cool and all, but I just wanted something super basic that I can actually understand. So with regular shell it could be like this:

sudo evtest --grab /dev/input/$(grep "SYNA2393" -A 5 /proc/bus/input/devices | grep "Handlers=" | cut -d" " -f 3)

This is more brittle than the accepted solution, so I'd suggest the reader use that, unless they are fine with hardcoding like this.

1
  • 1
    it might be nicer, cuz the previous requires awk and looks ugly, but you'll also wanna add > /dev/null in the end, so it doesnt use resources to log all the junk. throw it into /etc/rc.local and enable rclocal in systemctl - wayland is nice and never crashes, but theres still legacy features of xorg that unfortunately arent clear in wayland, such as disabling specific input devices like this without modifying what the kernel loads, and sharing screen in a web browser application on xorg i think you just do xinput --disable [device] something super simple like that Nov 25, 2021 at 21:34
0

I'm on a fresh install of ubuntu 22.04. I couldn't figure out how to get awk's match function to work, so I just used code from @meuh and @JinnKo to create a non-awk version that disables/toggles multiple devices given a keyword.

First, make sure evtest is installed:

sudo apt install evtest

I have two files, one that toggles the touchscreen on and off, and one that always disables it when booting up.

Toggle Touchscreen:

#!/bin/bash
# This toggles my touchscreen
#search for "Touchscreen" or something like that in /proc/bus/input/devices to make sure you're disabling what you want to disable.

path_for_temp_files="/ANY_PATH_YOU_WANT_TO_STORE_SOME_PID_FILES/"
regex='event([0-9]+)'
DEVICE="Touchscreen"

if [ -r "${path_for_temp_files}touchscreen-evtest0.pid" ]; then
    kill_these_files=("${path_for_temp_files}"touchscreen-evtest*)

    for i in "${kill_these_files[@]}"; do
        echo "kill" $(cat "${i}")
        sudo kill $(cat "${i}")
        sudo rm "${i}"
    done  

else
    filename='/proc/bus/input/devices'
    inside=0
    events=()
    while read line; do
        if [[ $line =~ $DEVICE ]]; then 
            inside=1
        fi

        if [[ $line =~ $regex ]]; then
            if [[ "$inside" -eq 1 ]]; then
                events+=("${BASH_REMATCH[1]}")
            fi
            inside=0
        fi
    done < $filename
    
    numevents=${#events[@]}
    
    for (( i=0; i<${numevents}; i++ )); do
        sudo evtest --grab "/dev/input/event${events[$i]}" > /dev/null &
        pid=$!
        echo $pid > "${path_for_temp_files}touchscreen-evtest${i}.pid"
        echo "/dev/input/event${events[$i]} running on pid ${pid}"
    done
fi

Disable Touchscreen to run at boot:

#!/bin/bash
# This disables my touchscreen
#search for "Touchscreen" or something like that in /proc/bus/input/devices to make sure you're disabling what you want to disable.

path_for_temp_files="/ANY_PATH_YOU_WANT_TO_STORE_SOME_PID_FILES/"
regex='event([0-9]+)'
DEVICE="Touchscreen"

if [ -r "${path_for_temp_files}touchscreen-evtest0.pid" ]; then
    kill_these_files=("${path_for_temp_files}"touchscreen-evtest*)

    for i in "${kill_these_files[@]}"; do
        echo "kill" $(cat "${i}")
        sudo kill $(cat "${i}")
        sudo rm "${i}"
    done  

fi

filename='/proc/bus/input/devices'
inside=0
events=()
while read line; do
    if [[ $line =~ $DEVICE ]]; then 
        inside=1
    fi

    if [[ $line =~ $regex ]]; then
        if [[ "$inside" -eq 1 ]]; then
            events+=("${BASH_REMATCH[1]}")
        fi
        inside=0
    fi
done < $filename

numevents=${#events[@]}

for (( i=0; i<${numevents}; i++ )); do
    sudo evtest --grab "/dev/input/event${events[$i]}" > /dev/null &
    pid=$!
    echo $pid > "${path_for_temp_files}touchscreen-evtest${i}.pid"
    echo "/dev/input/event${events[$i]} running on pid ${pid}"
done

Then I followed this answer to run as root at startup

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .