어떤 키보드가 특정 키를 눌렀는지 어떻게 알 수 있나요?

어떤 키보드가 특정 키를 눌렀는지 어떻게 알 수 있나요?

저는 종종 여러 개의 키보드가 설치된 페어링된 스테이션에서 작업합니다. setxkbmapwith를 사용하여 -device <ID>특정 키보드의 레이아웃을 설정할 수 있습니다(사용신분증:xinput), 그러나 일반적으로 내가 사용하는 키보드에서는 명확하지 않습니다. 두 키보드 사이를 오가며 시도하지 않는 것이 가장 좋습니다. 따라서 이를 위한 빠른 도구를 작성하고 싶었습니다 setxkbmap. 일반적인 사용 사례는 다음과 같습니다.

$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID

Linux의 어떤 인터페이스가 이 정보를 제공합니까? 이상적으로는 X 없이 작동해야 하지만 이것이 필수 사항은 아닙니다(X 없이 이를 지원하는 도구는 많지 않은 것 같습니다).


현재까지의 조사 결과:

  • 리눅스~ 해야 하다동시에 여러 키보드에 대한 다양한 레이아웃을 지원하기 위해 어떤 키보드를 입력하고 있는지 알아보세요.
  • xinput→ list.c → list_xi2XIQueryDevice사용 가능한 장치 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*)"

관련 정보