如何更改scancode->keycode映射

如何更改scancode->keycode映射

我已將大寫鎖定重新映射為退格鍵。

/etc/預設/鍵盤

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

大寫鎖定已按下

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

當我按退格鍵和大寫鎖定鍵時,會記錄以下內容

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

所以基本上我的大寫鎖定被重新映射到退格鍵,但只有在工具和網站使用正確的檢查時它才有效。我不想為我曾經使用過的每個錯誤實現此功能的工具或網站提交錯誤報告。

是否可以以完全模擬退格鍵的方式映射大寫鎖定,而不是像重新映射的大寫鎖定一樣?

答案1

首先,讓我們看看如何處理按鍵(摘自這個答案):

/鍵盤/ → scancode→ /輸入驅動程式/ → keycode→ /X 伺服器 XKB/ →keysym

scancode是綁定到特定密鑰的設備特定代碼,並且在不同供應商/產品之間可能有所不同。keycodekeysym傳播到應用程式。它keycode充當抽象層,因為它與設備和區域設定無關。根據區域設定和修飾鍵的狀態,相同的內容keycode可以產生不同的s。keysym這就是為什麼某些應用程式只會尋找 的原因keycode,尤其是在處理鍵盤快速鍵時。

所以我們的目標是將scancodeCapsLock 鍵對應到keycodeBackSpace 鍵。然後,無論您按下 BackSpace 還是 CapsLock,應用程式都會看到相同的內容keycodekeysym

這個映射是由烏德夫使用H阿德wd阿塔ase 檔案 (hwdb.bin),它是從 .hwdb/lib/udev/hwdb.d/和.hwdb 檔案編譯而來的/etc/udev/hwdb.d/


如何更改scancode->keycode映射

收集所需信息

首先,您必須確定輸入裝置(鍵盤)的bustypevendor和,以及要重新映射的鍵的 和product要將其映射到的 。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

……scancode70039

現在執行以下命令,其中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 個字元(如果需要,可以用零填充)並且字母需要大寫
  • [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),因為這仍將應用於所有鍵盤。

相關內容