저는 종종 여러 개의 키보드가 설치된 페어링된 스테이션에서 작업합니다. setxkbmap
with를 사용하여 -device <ID>
특정 키보드의 레이아웃을 설정할 수 있습니다(사용신분증:xinput
), 그러나 일반적으로 내가 사용하는 키보드에서는 명확하지 않습니다. 두 키보드 사이를 오가며 시도하지 않는 것이 가장 좋습니다. 따라서 이를 위한 빠른 도구를 작성하고 싶었습니다 setxkbmap
. 일반적인 사용 사례는 다음과 같습니다.
$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID
Linux의 어떤 인터페이스가 이 정보를 제공합니까? 이상적으로는 X 없이 작동해야 하지만 이것이 필수 사항은 아닙니다(X 없이 이를 지원하는 도구는 많지 않은 것 같습니다).
현재까지의 조사 결과:
- 리눅스~ 해야 하다동시에 여러 키보드에 대한 다양한 레이아웃을 지원하기 위해 어떤 키보드를 입력하고 있는지 알아보세요.
xinput
→ list.c →list_xi2
→XIQueryDevice
사용 가능한 장치 ID를 제공합니다setxkbmap
.showkey
그리고xev
키보드 ID는 인쇄되지 않습니다.xinput list-props $ID
키보드 이벤트가 전송되는 위치를 표시합니다.. 그러나다른 답변의 코드장치가 키보드를 인식하기 위해 아무 것도 인쇄하지 않는 것 같습니다.가장 가능한 해결책 중 하나는 각 키보드 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)]
답변1
장치 비활성화
어떤 키보드가 어떤 키보드인지 식별하는 아이디어는 다음과 같습니다. 다음 명령을 사용할 수 있습니다.x 입력장치를 활성화 및 비활성화합니다.
예
$ 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 노트북의 다양한 장치를 보여줍니다. 키보드는 1개만 연결되어 있습니다. 이 키보드는 다음과 같습니다.
↳ 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
이 아이디어?
이 명령을 사용하면 키보드 중 하나를 활성화 또는 비활성화하여 어떤 키보드를 사용하고 있는지 확인할 수 있습니다.
인용하다
답변2
추가 발굴지 밝혀져또 다른 솔루션일반 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
답변3
이 질문은 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
1단계: 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...)를 누르도록 요청해야 할 수도 있습니다.어느열쇠.
2단계: xinput을 사용하여 장치 이름에서 X ID 가져오기
위의 C 소스 코드를 컴파일하고 다음과 같이 사용합니다.
xinput list --id-only "keyboard:$(sudo ./a.out /dev/input/event*)"