변경방법 scancode-> keycode매핑

변경방법 scancode-> keycode매핑

Caps Lock을 백스페이스로 다시 매핑했습니다.

/etc/default/키보드

XKBLAYOUT="us"
XKBVARIANT="altgr-intl"
BACKSPACE="guess"
XKBOPTIONS="caps:backspace"

일부 특정 도구에서는 작동하지 않는다는 점을 제외하면 이것은 매우 훌륭하게 작동합니다. 나는 xev무슨 일이 일어나고 있는지 알아보곤 했습니다.

백스페이스 키를 눌렀습니다.

KeyPress event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 1028211, (335,635), root:(452,749),
    state 0x10, keycode 22 (keysym 0xff08, BackSpace), same_screen YES,
    XLookupString gives 1 bytes: (08) "
    XmbLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

KeyRelease event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 1028272, (335,635), root:(452,749),
    state 0x10, keycode 22 (keysym 0xff08, BackSpace), same_screen YES,
    XLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

Caps Lock을 눌렀습니다.

KeyPress event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 859789, (391,558), root:(508,672),
    state 0x10, keycode 66 (keysym 0xff08, BackSpace), same_screen YES,
    XKeysymToKeycode returns keycode: 22
    XLookupString gives 1 bytes: (08) "
    XmbLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

KeyRelease event, serial 38, synthetic NO, window 0x2400001,
    root 0x159, subw 0x0, time 859875, (391,558), root:(508,672),
    state 0x10, keycode 66 (keysym 0xff08, BackSpace), same_screen YES,
    XKeysymToKeycode returns keycode: 22
    XLookupString gives 1 bytes: (08) "
    XFilterEvent returns: False

나는 또한 다음을 사용하여 브라우저에서 시도했습니다.

addEventListener('keyup', event => {
  console.log(event.keyCode, event.key, event.code)
})

백스페이스와 Caps Lock을 누르면 다음이 기록됩니다.

8 "Backspace" "Backspace"
8 "Backspace" "CapsLock"

따라서 기본적으로 내 Caps Lock은 백스페이스로 다시 매핑되지만 도구와 웹 사이트가 적절한 검사를 사용하는 경우에만 작동합니다. 나는 이것을 잘못 구현하는 모든 도구나 웹사이트에 대해 버그 보고서를 제출하고 싶습니다.

다시 매핑된 Caps Lock처럼 작동하는 대신 백스페이스를 완전히 에뮬레이트하는 방식으로 Caps Lock을 매핑할 수 있습니까?

답변1

먼저 키 누름이 어떻게 처리되는지 살펴보겠습니다.이 답변):

/keyboard/ → scancode→ /input 드라이버/ → keycode→ /X 서버 XKB/ →keysym

이는 scancode특정 키에 바인딩된 장치별 코드이며 공급업체/제품마다 다를 수 있습니다. keycode그리고 keysym애플리케이션에 전파됩니다. 이는 keycode장치와 로케일에 구애받지 않으므로 추상화 계층 역할을 합니다. 로케일과 수정자 키의 상태에 따라 동일한 가 keycode생성될 수 있습니다 . 이것이 바로 일부 응용 프로그램이 특히 키보드 단축키를 다룰 때 keysym을 찾는 이유입니다 .keycode

따라서 우리의 목표는 scancodeCapsLock 키를 keycodeBackSpace 키에 매핑하는 것입니다. 그러면 응용 프로그램은 BackSpace를 누르든 CapsLock을 누르든 상관없이 동일하게 표시됩니다 keycode.keysym

이 매핑은 다음에 의해 수행됩니다.udev사용하여시간아르드~이다아타/lib/udev/hwdb.d/및 .hwdb 파일에서 컴파일된 ase 파일(hwdb.bin)입니다 /etc/udev/hwdb.d/.


변경방법 scancode-> keycode매핑

필수 정보 수집

먼저 입력 장치(키보드)의 , 및 및 bustypevendorproduct다시 매핑할 키와 매핑할 키를 결정해야 합니다 .versionscancodekey code identifier

실행 evtest(먼저 설치해야 할 수도 있음)하고 장치 목록에서 키보드를 식별합니다. 재생/일시 중지, WWW 등과 같은 추가 키가 있는 키보드에서는 이러한 키가 다른 입력 장치로 노출되는 경우가 많습니다. 키를 눌러도 출력이 나오지 않으면 Control+를 누르고 C다른 장치를 사용해 보십시오. 키보드를 식별한 후에는 첫 번째 열( /dev/input/eventX)을 기억하고 다시 매핑하려는 키를 누르십시오. 이후의 값 (MSC_SCAN)은 입니다 scancode. 내 키보드에서:

$ evtest
Available devices:
/dev/input/event0:  Power Button
/dev/input/event1:  Power Button
/dev/input/event2:  G19 Gaming Keyboard
/dev/input/event3:  G19 Gaming Keyboard
...
Select the device event number [0-18]:2
...
Event: time 1522111203.117945, -------------- SYN_REPORT ------------
Event: time 1522111220.778787, type 4 (EV_MSC), code 4 (MSC_SCAN),value 70039
Event: time 1522111220.778787, type 1 (EV_KEY), code 14 (KEY_BACKSPACE), value 1

... scancode이다70039.

이제 다음 명령을 실행합니다 eventX. 여기서 이전에 선택한 명령은 다음과 같습니다.

$ grep "" /sys/class/input/eventX/device/id/*

내 키보드의 출력은 다음과 같습니다.

/sys/class/input/event2/device/id/bustype:0003
/sys/class/input/event2/device/id/product:c228
/sys/class/input/event2/device/id/vendor:046d
/sys/class/input/event2/device/id/version:0110

을 얻으려면 key code identifier의 출력을 사용 evtest하거나키와 버튼/usr/include/linux/input-event-codes.h전체 목록을 보려면 섹션을 참조하세요 . 식별자는 KEY_소문자로 변환된 부분입니다 . 예 KEY_BACKSPACE:역행 키이.

udev 구성

보세요 /lib/udev/hwdb.d/. 우리는 텍스트 파일을 만들 것입니다/etc/udev/hwdb.d/장치 유형에 해당하는 파일보다 큰 숫자로 시작하는 파일 이름을 사용합니다. 키보드의 경우 60보다 큰 숫자일 수 있지만 포인팅 스틱의 경우 70보다 커야 합니다. 예를 들어 65-keyboard-custom.hwdb. 좋아하는 텍스트 편집기를 사용하세요. 단, 다음과 같이 시작해야 한다는 점을 명심하세요 root.

$ sudo gedit /etc/udev/hwdb.d/65-keyboard-custom.hwdb

다음 내용을 추가하세요

evdev:input:b[bustype]v[vendor]p[product]e[version]*
 KEYBOARD_KEY_[scancode]=[key code identifier]

...어디

  • [bustype], [vendor], [product] 및 [version]에는 정확히 4자가 있으며(필요한 경우 0으로 채움) 문자는 다음과 같아야 합니다.대문자
  • [scancode]에는 패딩이 필요하지 않지만 문자는 패딩이 필요합니다.소문자
  • evdev:...라인에는선행 공백 없음
  • KEYBOARD_KEY...라인에는정확히 하나의 선행 공백

내 예에서 파일은 다음과 같습니다.

evdev:input:b0003v046DpC228e0110*
 KEYBOARD_KEY_70039=backspace   # map CapsLock to BackSpace

첫 번째 줄은 장치와 일치합니다. 추가 줄을 지정할 수 evdev:있고 두 개 이상의 와일드카드( *)를 사용하여 추가 장치와 일치시킬 수 있지만 스캔 코드는 장치마다 다르다는 점을 명심하세요. 하나 이상의 스캔코드 매핑을 추가할 수도 있습니다. 영감을 얻으려면 살펴보십시오 /lib/udev/hwdb.d/60-keyboard.hwdb. 해당 파일의 더 자세한 최신 버전은 다음에서 찾을 수 있습니다.온라인 저장소.

새 구성 적용

새 구성을 하드웨어 데이터베이스로 컴파일합니다.

$ sudo systemd-hwdb update

변경 사항을 즉시 적용하려면 udev에 다음을 알립니다.

$ sudo udevadm trigger

구성 값은 시스템이 실행되는 동안에만 추가하거나 변경할 수 있습니다. 구성(예: 스캔코드 매핑)을 제거하는 경우 변경 사항을 적용하려면 재부팅해야 합니다.

이전에 수행한 재매핑( 을 사용하여 /etc/default/keyboard)을 되돌리는 것도 기억하세요. 왜냐하면 이 재매핑은 여전히 ​​모든 키보드에 적용되기 때문입니다.

관련 정보