Tiny Core Linux
Off-Topic => Off-Topic - Tiny Core Lounge => Topic started by: GNUser on September 13, 2019, 01:05:26 PM
-
I've written a shell script that needs to know the xinput id of the keyboard being used. In the case of my TC 10.1 and Devuan boxes, the id happens to be 9. However, in my OpenBSD box the id is 6.
I want to make the script portable and don't want to bother myself or other users with having to run xinput --list and then manually editing the keyboard id in the script. Is there a way to determine the id automatically? If the script has to wait for user to press a key so that script can find the id, that would be fine.
grepping output of xinput --list for "keyboard" won't work because there's more than one line with that word in it. Also, I don't want to assume that the system language is English.
-
Hi GNUser
The contents of /proc/bus/input/devices might have some interesting content:
tc@box:~$ cat /proc/bus/input/devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=PNP0C0C/button/input0
S: Sysfs=/devices/LNXSYSTM:00/device:00/PNP0C0C:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0
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/input1
U: Uniq=
H: Handlers=kbd event1
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input2
U: Uniq=
H: Handlers=sysrq kbd event2
B: PROP=0
B: EV=120013
B: KEY=4 2000000 3803078 f800d001 feffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7
I: Bus=0011 Vendor=0002 Product=0006 Version=0006
N: Name="ImExPS/2 Logitech Explorer Mouse"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input3
U: Uniq=
H: Handlers=mouse0 event3
B: PROP=0
B: EV=7
B: KEY=1f0000 0 0 0 0 0 0 0 0
B: REL=143
I: Bus=0010 Vendor=001f Product=0001 Version=0100
N: Name="PC Speaker"
P: Phys=isa0061/input0
S: Sysfs=/devices/platform/pcspkr/input/input4
U: Uniq=
H: Handlers=kbd event4
B: PROP=0
B: EV=40001
B: SND=6
tc@box:~$
-
Thanks for that, Rich. Interesting. However, I don't see the xinput ids listed in there.
Meanwhile I found this https://unix.stackexchange.com/questions/89538/how-to-tell-which-keyboard-was-used-to-press-a-key
The above comes close, but having to ship a C program with my shell script is not an option. I need to figure out a way to find the id using native X tools, even if the script has to wait for a key to be pressed.
-
Hi GNUser
This should get you into the ballpark:
tc@E310:~$ cat /proc/bus/input/devices | grep -i keyboard
N: Name="DELL DELL USB Keyboard"
tc@E310:~$ xinput list --id-only "DELL DELL USB Keyboard"
9
tc@E310:~$
-
Beautiful! Thank you. That worked in every Linux box I tried.
I also found this solution, which works in the BSDs as well because it does not rely on info provided by the linux kernel:
xinput --list --long | grep XIKeyClass | head -n 1 | egrep -o '[0-9]+'
-
Hi GNUser
This one picks out the line for the actual keyboard:
tc@E310:~$ xinput --list | grep -i keyboard | grep -iv "Virtual core" | grep -iv Button
â³ DELL DELL USB Keyboard id=9 [slave keyboard (3)]
tc@E310:~$
And it's backward compatible with TC4:
tc@box:~$ xinput --list | grep -i keyboard | grep -iv "Virtual core" | grep -iv Button
â³ Keyboard0 id=6 [slave keyboard (3)]
tc@box:~$
-
Regarding the system language, you can run "LANG=C xinput ..." to get English output.
-
Thank you both. I think we're getting warmer. Does this work on all your test systems?
LANG=C xinput --list | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
-
Hi GNUser
... Does this work on all your test systems? ...
Yes it does. TC10:
tc@E310:~$ LANG=C xinput --list | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
9
tc@E310:~$
TC4:
tc@box:~$ LANG=C xinput --list | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
6
tc@box:~$
-
Darn, on my wife's Sony Vaio I get some stray hits:
eileen@vaio:~$ LANG=C xinput --list | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
7
10
12
14
eileen@vaio:~$ LANG=C xinput --list | grep -i keyboard | egrep -iv 'virtual|video|button|bus'
↳ Sony Vaio Keys id=7 [slave keyboard (3)]
↳ USB 2.0 Camera: USB 2.0 Camera id=10 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=12 [slave keyboard (3)]
↳ Sony Vaio Jogdial id=14 [slave keyboard (3)]
The correct id on her system is 12. There must be a universal solution, but we're not there yet.
-
Hi GNUser
Those master and slave messages in the square brackets at the end of each line are creating a lot of unnecessary noise:
tc@box:~$ xinput --list
â¡ Virtual core pointer id=2 [master pointer (3)]
â â³ Virtual core XTEST pointer id=4 [slave pointer (2)]
â â³ Mouse0 id=7 [slave pointer (2)]
⣠Virtual core keyboard id=3 [master keyboard (2)]
â³ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
â³ Keyboard0 id=6 [slave keyboard (3)]
tc@box:~$
Time to cut them out:
tc@box:~$ xinput --list | cut -d\[ -f1
â¡ Virtual core pointer id=2
â â³ Virtual core XTEST pointer id=4
â â³ Mouse0 id=7
⣠Virtual core keyboard id=3
â³ Virtual core XTEST keyboard id=5
â³ Keyboard0 id=6
tc@box:~$
The -d\[ sets the field delimiter to [ and the -f1 says to output field number 1 (everything before the left square bracket).
Try this:
tc@box:~$ LANG=C xinput --list | cut -d\[ -f1 | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
6
tc@box:~$
-
Hi GNUser
Here's a brief writeup that provides some insight to the various devices listed by xinput:
https://www.linux.org/threads/cool-tricks-with-xinput-device.10345/
-
Thank you very much, Rich. Your last suggestion worked on all systems I tested, even on wife's Vaio:
eileen@vaio:~$ LANG=C xinput --list | cut -d\[ -f1 | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
12
Cutting out the slave/master column at far right was key. Very nice. Thank you.
I will look over the link and educate myself.
-
Thank you very much, Rich. Your last suggestion worked on all systems I tested, even on wife's Vaio:
eileen@vaio:~$ LANG=C xinput --list | cut -d\[ -f1 | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
12
Cutting out the slave/master column at far right was key. Very nice. Thank you.
I will look over the link and educate myself.
Thanks to this feature; It is nice to have the KMAPS setting of languages other than English set automatically :)
will this be standard in the next TCL version in particular!?
-
Thank you very much, Rich. Your last suggestion worked on all systems I tested, even on wife's Vaio:
eileen@vaio:~$ LANG=C xinput --list | cut -d\[ -f1 | grep -i keyboard | egrep -iv 'virtual|video|button|bus' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+'
12
Cutting out the slave/master column at far right was key. Very nice. Thank you.
I will look over the link and educate myself.
for non-English keyboards,
(automatic keyboard recognition feature),
Will there be a new standard feature for TCL !?
I want this feature to be a standard feature.
In my country "Q" keyboard and "F" keyboard are used equally.
automatically localized keyboard settings,
Provides a universal convenience for all local regions! :)
-
Rich,
Apparently we can't rely on the word keyboard always appearing before the first left bracket. Here's from the OpenBSD partition I have laying around for these kinds of tests:
bruno@obsd:~353$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ /dev/wsmouse0 id=7 [slave pointer (2)]
⎜ ↳ /dev/wsmouse id=8 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ /dev/wskbd id=6 [slave keyboard (3)]
The correct id that needs to be automatically found in this case is 6.
I came up with this, which works in all my GNU/Linux partitions, wife's wonky Sony Vaio with GNU/Linux, and also the OpenBSD test machine above:
master_id=$(LANG=C xinput list | grep -i 'master keyboard' | egrep -o 'id=[0-9]+' | egrep -o '[0-9]+')
keyboard_id=$(LANG=C xinput list $master_id | grep 'XIKeyClass' | egrep -o '[0-9]+')
-
Hi GNUser
... Apparently we can't rely on the word keyboard always appearing before the first left bracket. ...
It seems you also can't rely on the word XIKeyClass always appearing in the output. From TC4:
tc@box:~$ xinput list 3
Virtual core keyboard id=3 [master keyboard (2)]
Reporting 1 classes:
Class originated from: 6
Keycodes supported: 248
tc@box:~$
TC4 dates back to 2012 so that may not be of interest. If you don't mind my being nosy, I have a couple of questions:
1. What are you working on that requires the keyboards XID?
2. What happens if a system has 2 keyboards?
-
No problem.
1. https://github.com/bdantas/iksilo
It is a little project for me and my Esperanto friends. The simplest way of typing in Esperanto is using the x-system, but a way of typing this way that works reliably on multiple UNIX-like operating systems is sorely lacking.
In order for the script to do its job, a crude keylogger (xinput test $keyboard_id) is built into the script, to keep track of the last two characters typed. I realize there are better ways to do this than with a shell script and X tools, but I'm trying to keep it as simple as possible.
2. If >1 keyboard then the autodetection won't work, but users savvy enough to have 2 keyboards can adjust the variable at the top of the script to match the id of the keyboard they want to use.
Sorry for all the trouble. This is way off-topic for Tiny Core, but I know TC users are smart so I wanted your input. We can close this thread now--what we have will work with non-ancient versions of xinput across multiple OSes :)
-
Hi GNUser
... In order for the script to do its job, a crude keylogger (xinput test $keyboard_id) is built into the script, ...
That's funny, I was going to ask if this was for a keylogger but opted to exercise some self control.
Sorry for all the trouble. This is way off-topic for Tiny Core,
It's no trouble at all. The topic involves scripting, text manipulation commands, internationalization, etc. As such, I consider it
relevant to this forum. Even if considered off topic, that's what this particular section of the forum is here for.
-
Hi GNUser
Just an FYI, Xorg supports Esperanto. I see from your link you already know ablout setxkbmap and probably already found
this documentation:
https://www.x.org/releases/X11R7.5/doc/input/XKB-Config.html
An example:
setxkbmap -option esperanto:qwerty
Found here:
https://esperanto.stackexchange.com/questions/378/how-do-i-type-the-esperanto-letters-with-accents-on-linux
A more advanced example:
setxkbmap -layout "us" -variant "alt-intl" -option "lv3:lwin_switch,esperanto:qwerty"
Found in the paragraph titled setxkbmap here:
https://www.esperanto.org.nz/learn-and-use-esperanto/how-to-type-esperanto-characters/linux/
If you install xkeyboard-config.tcz you'll find epo (short for Esperanto) listed in:
/usr/local/share/X11/xkb/rules/evdev
And I think this is used for mapping the keyboard:
/usr/local/share/X11/xkb/symbols/epo
-
Rich, you are over the top in your desire to help! I hope someday I can reciprocate.
Yes, I am aware of those setxkbmap options (take a look at my script's add_keyboard_options function). The point of the script is to allow the Esperantist to not have to conform to the X.org way (Level3_shift--whatever key is chosen--plus c to produce ĉ, for example) but rather to use the common-among-Esperantists x-system (cx to produce ĉ, for example). For Esperantists who are used to the x-system, it is very fast to type that way (vs. having to stop, think, and move one's hands on the keyboard to type any other way).
Note that x-system in this context has nothing to do with X.org, it's just a coincidence that both have X in the name.
-
Hi GNUser
Truth of the matter is I stumbled upon the Esperanto reference while perusing the /usr/local/share/X11/xkb directory looking
for something else. I just Googled a couple of items to try to tie it all together.
-
Just a quick followup. I found a way to detect keyboard input without needing the keyboard id at all:
LANG=C xinput --test-xi2 --root | awk '
/RawKeyPress/ { relevant=1 }
relevant==1 && /detail/ { print $2; relevant=0 }
'
This makes for a good enough keylogger for my purposes. Note that if you put a pipe after the awk command, you need to disable awk's buffer with either { fflush() } or { system("") }. An example of that is here: https://github.com/bdantas/iksilo