The officially official Devuan Forum!

You are not logged in.

#1 2019-09-13 17:46:24

GNUser
Member
Registered: 2017-03-16
Posts: 561  

how to automatically get xinput id of keyboard? [SOLVED]

I've written a shell script that needs to know the xinput id of the keyboard being used. In the case of my Devuan box 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.

I've checked what xdotooland xev but neither one seems able to help. 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.

Any ideas?

Last edited by GNUser (2019-09-14 17:46:15)

Offline

#2 2019-09-13 21:02:23

fsmithred
Administrator
Registered: 2016-11-25
Posts: 2,409  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Maybe more creative grepping will do it. Hm... not so easy. I think I can do it, but I'd need to see what your xinput shows and which line you want.

Assuming I want the one that says "keyboard" but not "Virtual core" on the left side, and says "slave  keyboard" on the right side, this works on two of my machines. (One is "Microsoft Wired Keyboard 600" and the other is "AT Translated set 2 keyboard" on a Thinkpad.)

keyboard_id=$(xinput --list | grep 'slave  keyboard' | sed -e 's/\[.*//g' | grep -i keyboard | grep -v core | cut -d"=" -f2)

Offline

#3 2019-09-13 21:26:51

fsmithred
Administrator
Registered: 2016-11-25
Posts: 2,409  

Re: how to automatically get xinput id of keyboard? [SOLVED]

sad   not quite. That way leaves white space at the end. Maybe add another sed that removes the white space. (not sure if it's a tab or several spaces.)

$ echo "$keyboard_id"
10

$echo "$keyboard_id"x
10     x

Offline

#4 2019-09-13 23:26:21

ralph.ronnquist
Administrator
From: Clifton Hill, Victoria, AUS
Registered: 2016-11-30
Posts: 1,106  

Re: how to automatically get xinput id of keyboard? [SOLVED]

To avoid the language problem, I would go for using xinput --list --long, and the id of the "originating class" from the first line with type XIKeyClass. Perhaps something like the following:

xinput --list --long | grep -Fwm1 XIKeyClass | egrep -oE '[0-9]*'

which would allow almost any i18n of the sought line, merely expecting XIKeyClass to be present, and the id being the only number on the line.

That method should find at least one of the currently available keyboards; I think it'll pick "the last one" if you connect additional USB or Bluetooth keyboards. Or possibly it's "the last one used".

Offline

#5 2019-09-14 00:58:38

bgstack15
Member
Registered: 2018-02-04
Posts: 205  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Can you not just do

LANG=C xinput --list --long

Or similar?


This space intentionally left blank.

Offline

#6 2019-09-14 02:04:07

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Wow, thanks guys!

ralph.ronnquist's suggestion works in Devuan, in Tiny Core Linux (which uses BusyBox instead of coreutils), and even in OpenBSD. I modified it slightly to something that does same thing but makes more sense to me:

xinput --list --long | grep XIKeyClass | head -n 1 | egrep -o '[0-9]+'

There's no way I would have figured this out on my own. Thanks again, ralph. You're a wizard!

The only thing I don't understand is why the entry of interest always happens to be the first match.

Offline

#7 2019-09-14 03:58:49

ralph.ronnquist
Administrator
From: Clifton Hill, Victoria, AUS
Registered: 2016-11-30
Posts: 1,106  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Perhaps it's merely incidental, or perhaps it's because it's the detail associated with the 'master keyboard' where something in the xinput code makes it a reliable feature. I did do a quick test with a couple of different hardware set ups, including a laptop with a USB keyboard, and it seemed to offer the right result for those.

It's also a guess that the label XIKeyClass is a code label without i18n, and that no i18n of that detail line will morph the id number, or add any other digits into the mix.

It works while it works smile

Eventually someone with direct insight into the source might pass by, to confirm or refute.

Offline

#8 2019-09-14 10:22:45

fsmithred
Administrator
Registered: 2016-11-25
Posts: 2,409  

Re: how to automatically get xinput id of keyboard? [SOLVED]

The first line with XIKeyClass on my desktop is my mouse. On the laptop, it's Virtual Core Keyboard.

⎜   ↳ Logitech USB Receiver                     id=11   [slave  pointer  (2)]
        Reporting 6 classes:
                Class originated from: 11. Type: XIButtonClass
                Buttons supported: 7
                Button labels: "Button 0" "Button Unknown" "Button Unknown" "Button Wheel Up" "Button Wheel Do
wn" "Button Horiz Wheel Left" "Button Horiz Wheel Right"
                Button state:
                Class originated from: 11. Type: XIKeyClass

Offline

#9 2019-09-14 10:58:56

ralph.ronnquist
Administrator
From: Clifton Hill, Victoria, AUS
Registered: 2016-11-30
Posts: 1,106  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Few things kill a perfectly good theory as effectivly as does reality....

Offline

#10 2019-09-14 11:16:51

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

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]+'

Last edited by GNUser (2019-09-14 11:19:02)

Offline

#11 2019-09-14 11:59:35

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Doesn't work on my wife's Sony 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)]

This is tough.

Offline

#12 2019-09-14 12:55:35

fsmithred
Administrator
Registered: 2016-11-25
Posts: 2,409  

Re: how to automatically get xinput id of keyboard? [SOLVED]

That one gives me two numbers, 13 and 12, which corrspond to:

↳ Microsoft Wired Keyboard 600            	id=13	[slave  pointer  (2)]
↳ Microsoft Wired Keyboard 600            	id=12	[slave  keyboard (3)]

Offline

#13 2019-09-14 13:45:17

ralph.ronnquist
Administrator
From: Clifton Hill, Victoria, AUS
Registered: 2016-11-30
Posts: 1,106  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Perhaps it's important that the id of the entry is different from the id of the origin class. E.g. in post#8 above, the origin class id, 11, is the same as the id of the entry it concerns, and it should therefore be ignored. This logic could be done as:

xinput list --id-only | \
    xargs -n 1 -I+ sh -c "xinput list + | grep -wv + | grep XIKeyClass" | \
    grep -oE "[0-9]+"

I.e., in words: for each of the available ids, check the details for the id, but ignoring lines containing the id, for a XIKeyClass line, and then reduce resulting lines to the number they contains. Ideally there should be only one resulting line, but if there are more... well.

Then you might want to check out https://unix.stackexchange.com/question … ress-a-key on how to "really" do this smile

Offline

#14 2019-09-14 16:16:30

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Yes, that works even on my wife's wonky hardware where multiple "slave keyboards" are listed. big_smile

eileen@vaio:~$ xinput list --id-only | xargs -n 1 -I+ sh -c "xinput list + | grep -wv + | grep XIKeyClass" | egrep -o '[0-9]+'
12

Wow, ralph.ronnquist. Very impressive. Thank you!

I understand the logic of the command, but don't understand how you figured out that it was the necessary logic. Will chew on it.

BTW, I had also found that nugget on stackexchange, but do not want to give users anything in addition to the shell script I've created. The script is here if you are curious:
https://github.com/bdantas/iksilo

Last edited by GNUser (2019-09-14 16:36:42)

Offline

#15 2019-09-14 17:02:05

chris2be8
Member
Registered: 2018-08-11
Posts: 264  

Re: how to automatically get xinput id of keyboard? [SOLVED]

That would not work on my devuan system:
chris@rigel:~/bin$ xinput --list
bash: xinput: command not found

So how can it be done without asking the user to install xinput?

Chris

Offline

#16 2019-09-14 17:45:01

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

Why would you need the xinput id if you don't have xinput installed?

Last edited by GNUser (2019-09-14 18:08:30)

Offline

#17 2019-09-15 00:46:57

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

I tinkered with ralph.ronnquist's solution in post #13 and figured out that this is what's actually going on when you decompress the logic:

$ 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]+')

This version is easier for my pea brain to grasp.

Last edited by GNUser (2019-09-15 00:47:35)

Offline

#18 2019-10-07 18:28:37

GNUser
Member
Registered: 2017-03-16
Posts: 561  

Re: how to automatically get xinput id of keyboard? [SOLVED]

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 }
'

The most obvious application of this is a keylogger (https://github.com/bdantas/keylogger), but the keylogger itself may just be a stepping stone to something more useful (e.g., https://github.com/bdantas/iksilo).

Last edited by GNUser (2019-10-07 18:29:00)

Offline

Board footer