linuxにおけるキーマップ入れ替え

### 環境
Linux Mint 22.1 Cinnamon 

### 参考
https://symfoware.blog.fc2.com/blog-entry-2677.html

※xremapの箇所はそのままでは実行しない（サービスを"--user"なしでenabaleにしたら全キー入力不可、disableしてもShiftキー入力不可になった事がある）

### 概要
1. 単一キーはudevで入れ替え
2. 複数キーの組み合わせはxremapで入れ替え

### スキャンコードの調査
#### 以下のコマンド(evtest)を投入＆調査したいキーを押下
```shell
sudo evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:	Lid Switch
/dev/input/event1:	Microsoft Surface Type Cover Keyboard
/dev/input/event10:	Video Bus
/dev/input/event11:	HDA Intel PCH Mic
/dev/input/event12:	HDA Intel PCH Headphone
/dev/input/event13:	HDA Intel PCH HDMI/DP,pcm=3
/dev/input/event14:	HDA Intel PCH HDMI/DP,pcm=7
/dev/input/event15:	HDA Intel PCH HDMI/DP,pcm=8
/dev/input/event16:	Logitech MX Anywhere 3
/dev/input/event2:	Microsoft Surface Type Cover Mouse
/dev/input/event3:	Microsoft Surface Type Cover UNKNOWN
/dev/input/event4:	Microsoft Surface Type Cover Touchpad
/dev/input/event5:	Microsoft Surface Type Cover UNKNOWN
/dev/input/event6:	Microsoft Surface Type Cover UNKNOWN
/dev/input/event7:	Microsoft Surface Type Cover UNKNOWN
/dev/input/event8:	gpio-keys
/dev/input/event9:	gpio-keys
Select the device event number [0-16]: 1
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x45e product 0x9c1 version 0x111
Input device name: "Microsoft Surface Type Cover Keyboard"
Supported events:
```
```shell:F23（無変換キーにマッピングしたい）を押下
Event: time 1748318775.171345, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70072
Event: time 1748318775.171345, type 1 (EV_KEY), code 193 (KEY_F23), value 1
Event: time 1748318775.171345, -------------- SYN_REPORT ------------
Event: time 1748318775.172132, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70072
Event: time 1748318775.172132, type 1 (EV_KEY), code 193 (KEY_F23), value 0
Event: time 1748318775.172132, -------------- SYN_REPORT ------------
```

```shell:F24（変換キーにマッピングしたい）を押下
Event: time 1748318818.248189, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70073
Event: time 1748318818.248189, type 1 (EV_KEY), code 194 (KEY_F24), value 1
Event: time 1748318818.248189, -------------- SYN_REPORT ------------
Event: time 1748318818.248992, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70073
Event: time 1748318818.248992, type 1 (EV_KEY), code 194 (KEY_F24), value 0
Event: time 1748318818.248992, -------------- SYN_REPORT ------------
```

#### デバイスの指定方法
evdev:input:b\<bus_id>v\<vendor_id>p\<product_id>e\<version_id>-\<modalias>
usbの場合、bus_idは0003
vendor_id、product_idはlsusbで表示されるIDを(ID \<vendor_id>:\<product_id>)大文字4桁で指定
```shell
ueki5@surfacePro5:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 1286:204c Marvell Semiconductor, Inc. Bluetooth and Wireless LAN Composite
Bus 001 Device 004: ID 045e:09c1 Microsoft Corp. Surface Type Cover
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
```

#### キー名の調べ方（KC_XXXX形式、KC_は省略可。大文字小文字は認識しない）
※全てOK: KC_MUHENKAN,MUHENKANmuhenkan,Muhenkan
https://github.com/emberian/evdev/blob/1d020f11b283b0648427a2844b6b980f1a268221/src/scancodes.rs#L26-L572

### 設定ファイル(ファイル名は任意だが、拡張子をhwdbにする事)を作成
```shell:/etc/udev/hwdb.d/10-surface-pro-typecover.hwdb
evdev:input:b0003v045Ep09C1e*
 KEYBOARD_KEY_70032=enter
 KEYBOARD_KEY_70087=rightshift
 KEYBOARD_KEY_70089=backslash
```

### 設定を反映
```shell
sudo systemd-hwdb update
```
```shell
sudo udevadm trigger
```

### fcitx5の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232903/672926a3-c230-45fc-ac8b-7eda45db6c63.png)

#### xremapのインストール
https://github.com/xremap/xremap

##### Rustのインストール
https://rustup.rs
```shell:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
```shell:選択は1を選択
   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation
>1
```

```shell:PATHを反映
. "$HOME/.cargo/env"
```

##### xremapのインストール
・環境に合わせてオプションを変更
```shell:
cargo install xremap --features x11     # X11
cargo install xremap --features gnome   # GNOME Wayland
cargo install xremap --features kde     # KDE-Plasma Wayland
cargo install xremap --features wlroots # Sway, Wayfire, etc.
cargo install xremap --features hypr    # Hyprland
cargo install xremap                    # Others
```

##### config.ymlの作成
```shell:~/.config/xremap/config.yml
modmap:
  - remap:
     muhenkan:
       held: fn
       alone: muhenkan
       alene_timeout_millis: 1000
virtual_modifiers:
  - fn
keymap:
  - remap:
     fn-y: home
     fn-u: pagedown 
     fn-i: pageup
     fn-o: end
     fn-p: backspace
     fn-h: left
     fn-j: down
     fn-k: up
     fn-l: right
     fn-semicolon: delete
     fn-space: enter
```

##### xremap.serviceの編集
```shell:~/.config/systemd/user/xremap.service
[Unit]
Description=Xremap
After=default.target

[Service]
ExecStart=/home/ueki5/.cargo/bin/xremap --watch=device /home/ueki5/.config/xremap/config.yml
Restart=always
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target
```

##### xremapをsudoなしで実行できるようにする
```shell:
sudo gpasswd -a "$USER" input
echo 'KERNEL=="uinput", GROUP="input", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/input.rules
```

##### xremapを開始する
```shell:
systemctl --user start xremap.service
```

##### xremapを終了する
```shell:
systemctl --user stop xremap.service
```

##### xremapを有効にする
```shell:
systemctl --user enable xremap.service
```