スキャンコードをキーコードにマップ

提供: ArchWiki
2022年11月18日 (金) 15:09時点におけるKusanaginoturugi (トーク | 投稿記録)による版 (→‎udev を使う: リンクに変更)
ナビゲーションに移動 検索に移動
ノート: このページは既に特別なキーボードキーを読んでいることを前提としています。特別なキーボードキーでは広い範囲で問題を扱っています。

スキャンコードからキーコードへのマッピングは Linux コンソールもしくは Xorg に限定されない普遍的なことであり、コンソールと Xorg 両方に影響を与えます。

スキャンコードキーコードにマップする方法は2つあります:

  • udev を使う
  • setkeycodes を使う

udev を使用する方法が推奨されます。udev は (情報源として信頼できる) ハードウェア情報を使ってデータベースからキーボードモデルを選択しているからです。あなたの使用しているキーボードモデルがデータベースから見つからなかった場合、あなたのキーは out of the box として認識されます。

スキャンコードの確認

リマップするキーのスキャンコードを知っておく必要があります。詳しくは特別なキーボードキー#スキャンコードを見て下さい。

udev を使う

udev には /etc/udev/hwdb.bin のハードウェアデータベースインデックスを管理するための hwdb という組み込み関数が存在します。/usr/lib/udev/hwdb.d/, /run/udev/hwdb.d/, /etc/udev/hwdb.d/ ディレクトリに存在する拡張子が .hwdb のファイルからデータベースが作成されます。スキャンコードをキーコードにマッピングするデフォルトのマッピングファイルは /usr/lib/udev/hwdb.d/60-keyboard.hwdb です。詳しくは hwdb(7) を見て下さい。

.hwdb ファイルには様々なキーボードに対応する複数のマッピングブロックを記述でき、ひとつのブロックを複数のキーボードに適用することもできます。ハードウェアに対するブロックのマッチには evdev: プレフィックスが使われます。以下のハードウェアマッチがサポートされています:

  • 一般的な入力デバイス (USB キーボードなど) は usb カーネル modalias によって識別されます:
    evdev:input:b<bus_id>v<vendor_id>p<product_id>e<version_id>-<modalias>
    <vendor_id>, <product_id>, <version_id> は4桁の大文字の16進数で、それぞれベンダー ID、プロダクト ID、バージョン ID を表します (ID は lsusb コマンドを実行することで確認できます)。<modalias> は任意の長さの modalias でデバイスの機能を表します。<bus_id> は4桁の16進数のバス ID で、USB デバイスの場合は 0003 になります。<bus_id> に指定できる値は /usr/include/linux/input.h に定義されています (次のコマンドを使うことでリストとして表示できます: awk '/BUS_/ {print $2, $3}' /usr/include/linux/input.h)。
  • AT キーボードの DMI データは以下の形式でマッチします:
    evdev:atkbd:dmi:bvn*:bvr*:bd*:svn<vendor>:pn<product>:pvr*
    <vendor><product> はファームウェアによって供給される文字列でカーネルの DMI modalias を経由して確認できます。
  • 入力ドライバーのデバイス名と DMI データは以下の形式でマッチします:
    evdev:name:<input device name>:dmi:bvn*:bvr*:bd*:svn<vendor>:pn*
    <input_device_name> はドライバーによって指定されたドライバーの名前、<vendor> はカーネルの DMI modalias 経由で確認できるファームウェアの文字列です。

ブロックの本体部は各行とも KEYBOARD_KEY_<scancode>=<keycode> という形式になっています。<scancode> の値は16進数ですが先頭に 0x は付けません (0xa0 ではなく a0 と指定します)。<keycode>/usr/include/linux/input-event-codes.h に記載されている小文字のキーコード名になります (KEY_<KEYCODE> 変数を見てください)。ソートされたリストが [1] から確認できます。<keycode> で10進数の値を指定することはできません。

hwdb のカスタム例

以下の hwdb ファイルは全ての AT キーボードにマッチします:

/etc/udev/hwdb.d/90-custom-keyboard.hwdb
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr*
 KEYBOARD_KEY_10=suspend
 KEYBOARD_KEY_a0=search

ノートパソコンと USB キーボードの修飾キーのバインドを変更する例:

/etc/udev/hwdb.d/10-my-modifiers.hwdb
evdev:input:b0003v05AFp8277* # was tested on Kensington Slim Type USB (with old ABI)
 KEYBOARD_KEY_70039=leftalt  # bind capslock to leftalt
 KEYBOARD_KEY_700e2=leftctrl # bind leftalt to leftctrl

evdev:atkbd:dmi:*            # built-in keyboard: match all AT keyboards for now
 KEYBOARD_KEY_3a=leftalt     # bind capslock to leftalt
 KEYBOARD_KEY_38=leftctrl    # bind leftalt to leftctrl

Hardware Database Index のアップデート

設定ファイルを変更した後は、ハードウェアデータベースインデックス hwdb.bin を再構築する必要があります。

  • 次を実行して hwdb.bin を手動でアップデート:
# udevadm hwdb --update
  • systemd-hwdb-update.serviceConditionNeedsUpdate をコメントアウトすると再起動するたびに自動的に更新されます:
/usr/lib/systemd/system/systemd-hwdb-update.service
#  This file is part of systemd.
.
.
#ConditionNeedsUpdate=/etc
.
.

systemd-hwdb-update.service のロードが完了すると systemd-trigger.servicehwdb.bin の変更をリロードします。

  • Systemd のアップグレード時には自動的に更新が行われます。

Systemd のアップグレード時、インストールスクリプトが # udevadm hwdb --update を実行して hwdb.bin を再構築するため手動の操作は必要ありません。

Hardware Database Index のリロード

カーネルは起動時に hwdb.bin を読み込むため、システムを再起動することで最新の hwdb.bin をロードできます。

udevadm を以下のようなコマンドで使うことで最新の hwdb.bin から新しいキーマッピングをロードできます:

# udevadm trigger

udevadm は追加・変更したキーマッピングしかロードしないため注意してください。コンフィグファイルからマッピングを削除した場合、hwdb.bin を再ビルドして # udevadm trigger を実行して、さらに再起動を行わないと削除されたマッピングがカーネルに残り続けます。

データベースに問い合わせる

キーを押したり udevadm info を実行することで設定がロードされているかどうか確認できます。上記の例の USB キーボードの場合、以下のように設定したマッピングが出力されます:

# udevadm info /dev/input/by-path/*-usb-*-kbd | grep KEYBOARD_KEY
E: KEYBOARD_KEY_70039=leftalt
E: KEYBOARD_KEY_700e2=leftctrl

setkeycodes を使う

setkeycodesscancodes-to-keycodes マッピングテーブルを Linux カーネルにロードさせるツールです。使用方法は:

# setkeycodes scancode keycode ...

一度に複数のペアを指定することが可能です。スキャンコードは16進数で、キーコードは10進数で記述します。

ノート: setkeycodes は USB キーボードでは機能しません (Linux 3.14.44-1-lts):
# setkeycodes 45 30     # bind NumLock (0x45) to KEY_A (30) on AT keyboard
(successful)
# setkeycodes 70053 30  # bind NumLock (0x70053) to KEY_A (30) on USB keyboard
KDSETKEYCODE: Invalid argument
failed to set scancode 620d3 to keycode 31