여러 키보드가 설치된 페어링 스테이션에서 자주 작업합니다. setxkbmap
와 함께 사용 -device <ID>
하여 특정 키보드의 레이아웃을 설정할 수 있지만 (의 IDxinput
사용 ) 종종 어떤 키보드를 사용하고 있는지 명확하지 않습니다. 두 키보드를 모두 시도하는 것을 피하는 것이 좋습니다. 따라서이 정보를 얻을 수있는 빠른 도구를 작성하고 싶습니다 setxkbmap
. 다음과 같은 일반적인 유스 케이스를 기대합니다.
$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID
Linux에서이 정보를 제공하는 인터페이스는 무엇입니까? 이상적으로는 X없이 작동해야하지만 요구 사항은 아닙니다 (X없이 이것을 지원하는 많은 도구는 보이지 않습니다).
지금까지의 결과 :
- Linux 는 여러 키보드에 대해 서로 다른 레이아웃을 동시에 지원하기 위해 입력하는 키보드 를 알고 있어야합니다 .
xinput
→ list.c →list_xi2
→에서XIQueryDevice
사용할 수있는 장치 ID를 제공합니다setxkbmap
.showkey
및xev
키보드 ID를 인쇄되지 않습니다.xinput list-props $ID
키보드 이벤트가 전송되는 위치를 보여줍니다 . 그러나 다른 답변의 코드를 사용 하면이 장치가 키보드를 식별하기 위해 아무것도 인쇄하지 않는 것 같습니다.-
거의 가능한 해결책 중 하나는
xinput --test <ID> &
각 키보드 ID마다 실행 하고 어떤 것이 먼저 무언가를 반환하는지 확인하는 것입니다. 이것의 문제점은 어떤 “키보드”가 실제로 키보드 인지 알아내는 것입니다 .$ xinput | grep keyboard ⎣ 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)] ↳ Sleep Button id=9 [slave keyboard (3)] ↳ WebCam SC-13HDL10931N id=10 [slave keyboard (3)] ↳ AT Translated Set 2 keyboard id=11 [slave keyboard (3)]
답변
장치 비활성화
다음은 어떤 키보드가 어떤 키보드인지 식별하는 아이디어입니다. xinput 명령을 사용할 수 있습니다 을 사용하여 장치를 활성화 및 비활성화 할 수 있습니다.
예
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=12 [slave pointer (2)]
⎜ ↳ TPPS/2 IBM TrackPoint id=13 [slave pointer (2)]
⎜ ↳ Logitech USB Receiver id=9 [slave pointer (2)]
⎜ ↳ Logitech USB Receiver id=10 [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=11 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=14 [slave keyboard (3)]
위 출력은 Thinkpad 랩탑에있는 다양한 장치를 보여줍니다. 하나의 키보드 만 연결되어 있습니다.
↳ AT Translated Set 2 keyboard id=11 [slave keyboard (3)]
이제이 장치를 통해 사용할 수있는 속성을 살펴보십시오.
$ xinput list-props "AT Translated Set 2 keyboard"
Device 'AT Translated Set 2 keyboard':
Device Enabled (124): 1
Coordinate Transformation Matrix (126): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.
위로부터 활성화되어 있음을 알 수 있으므로 비활성화하십시오.
$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 0
사용하려면 다음을 수행하십시오.
$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 1
아이디어?
이 명령을 사용하여 키보드 중 하나를 비활성화하여 사용중인 키보드를 확인할 수 있습니다.
참고 문헌
답변
X 툴을 인용하고 있지만 “이상적으로 X없이 작동해야한다”는 솔루션을 요구하기 때문에이 질문은 약간 모순된다.
네 번째 발견에 관하여 :
xinput
당신에게 서신을 줄 것입니다
$ xinput list-props 11
Device 'AT Translated Set 2 keyboard':
Device Enabled (145): 1
Coordinate Transformation Matrix (147): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
Device Product ID (266): 1, 1
Device Node (267): "/dev/input/event0"
적어도 다음 버전에서는
$ xinput --version
xinput version 1.6.1
XI version on server: 2.3
첫 번째 단계 : C에서 키보드 이벤트 장치 감지
#include <stdio.h>
//#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>
// typical use : sudo ./a.out /dev/input/event*
int main (int argc, char *argv[])
{
struct input_event ev[64];
int fd[argc],rd,idev,value, size = sizeof (struct input_event);
char name[256] = "Unknown";
if(argc==1) return -1;
int ndev=1;
while(ndev<argc && (fd[ndev] = open (argv[ndev], O_RDONLY|O_NONBLOCK)) != -1){
ndev++;
}
fprintf (stderr,"Found %i devices.\n", ndev);
if(ndev==1) return -1;
while (1){
for(idev=1; idev<argc; idev++){
if( (rd=read (fd[idev], ev, size * 64)) >= size){
value = ev[0].value;
if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){
ioctl (fd[idev], EVIOCGNAME (sizeof (name)), name);
printf ("%s\n", name);
return idev;
}
}
}
// sleep(1);
}
return -1;
}
이 페이지 덕분에 많은 감사 . 필자는 여기서 빌린 코드에서 대부분의 안전 점검을 명확하게하기 위해 실제 코드에서 아마도 원하는 것을 제거했습니다.
키 누름은 에코되므로 실제로 사용자에게 수정 자 키 (Shift, Control …)를 누르지 말라고 친절하게 요청할 수 있습니다. 키를 누릅니다.
두 번째 단계 : xinput을 사용하여 장치 이름에서 X ID를 가져옵니다.
위의 C 소스를 컴파일하고 다음과 같이 사용하십시오.
xinput list --id-only "keyboard:$(sudo ./a.out /dev/input/event*)"
답변
더 많은 파기 작업은 일반 Bash와 일반 사용자 계정을 사용하는 다른 솔루션 을 공개했습니다 . 스크립트 :
#!/usr/bin/env bash
set -o errexit -o nounset -o noclobber -o pipefail
# Remove leftover files and processes on exit
trap 'rm --recursive -- "$dir"; kill -- -$$' EXIT
dir="$(mktemp --directory)"
cd "$dir"
# Log key presses to file
xinput --list --id-only | while read id
do
# Only check devices linked to an event source
if xinput --list-props "$id" | grep --quiet --extended-regexp '^\s+Device Node.*/dev/input/event'
then
xinput test "$id" > "$id" &
fi
done
# Check for key presses
while sleep 0.1
do
for file in *
do
if [[ -s "$file" ]]
then
echo "$file"
exit
fi
done
done