自作キーボードで複数キーの同時出力を行うQMK Firmwareを作成する

# はじめに
この記事は自作キーボードのMint60をWindowsとMacの両方に対応させるために行った設定の備忘録です。
Windowsの「変換」「無変換」キーの割り当て部分を、Macだと「かな」「英数」キーとして認識させるファームウェアを書きました。

スペースキー両隣のキーに、それぞれ「変換」と「かな」、「無変換」と「英数」のキーを同時に送信するようになっています。

# 環境
macOS Big Sur

# 手順
QMK Firmwareのcloneや、ファームウェアのビルドに必要なツールインストール、キーマップファイルのコピーを行います (詳細省略)。

キーマップの`keymap.c`にカスタムキーコード IMEON と IMEOFF を追加します。

```keymap.c

enum custom_keycodes {
  RGBRST = SAFE_RANGE,
  IMEON,
  IMEOFF
};
```

追加したカスタムキーをキーマップに追加します。私の場合は`KC_SPC, KC_BSPC`の両隣に置いています。

```keymap.c

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT( \
    KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,      KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,    KC_BSPC,  \
    KC_TAB,    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,      KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,  \
    KC_LCTL,     KC_A,    KC_S,    KC_D,    KC_F,    KC_G,      KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,        KC_ENT,   \
    KC_LSFT,       KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,      KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,   KC_UP,  MO(1),   \
    KC_ESC,    KC_LALT,    KC_LGUI,    IMEOFF,    KC_SPC,        KC_BSPC, IMEON,  KC_RGUI,               KC_LEFT,KC_DOWN,KC_RGHT \
  ),
  [1] = LAYOUT( \
    KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,     KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,    KC_DEL, \
    RGB_TOG,   RGBRST,  RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
    KC_CAPS,     RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,        XXXXXXX, \
    _______,       XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,   XXXXXXX, XXXXXXX, KC_MRWD, KC_MFFD, KC_MPLY, _______, KC_PGUP, _______, \
    XXXXXXX,   _______,    _______,    _______,    XXXXXXX,       XXXXXXX, KC_ZKHK, XXXXXXX,                   KC_HOME, KC_PGDN, KC_END \
  )
};
```

`process_record_user` に IMEON/IMEOFF が押されたときに複数のキーコードを送信する処理を追加します。`case IMEON:`、`case IMEON:`の部分で、IMEONに「変換」：`KC_HENK`と「かな」：`KC_LANG1`、IMEOFFに「無変換」：`KC_MHEN`と「英数」：`KC_LANG2`

他のキーにしたい場合は[Keycodes Overview](https://docs.qmk.fm/#/keycodes)よりキーコードを参照します。

```keymap.c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case RGBRST:
      #ifdef RGBLIGHT_ENABLE
        if (record->event.pressed) {
          eeconfig_update_rgblight_default();
          rgblight_enable();
          RGB_current_mode = rgblight_config.mode;
        }
      #endif
      break;
    case IMEON:
       if (record->event.pressed) {
         register_code(KC_HENK);
         register_code(KC_LANG1);
       } else {
         unregister_code(KC_HENK);
         unregister_code(KC_LANG1);
       }
       break;
    case IMEOFF:
       if (record->event.pressed) {
         register_code(KC_MHEN);
         register_code(KC_LANG2);
       } else {
         unregister_code(KC_MHEN);
         unregister_code(KC_LANG2);
       }
       break;
  }
  return true;
}
```

最後ファームウェアの書き込みを行います。キーボードを接続した状態で、

```sh
make mint60:<name>:avrdude
```

# 結果
同じキーボードをWindowsに接続した際は「変換」「無変換」キーとして認識され、Macに接続した際は「かな」「英数」として認識されるようになりました！Windows/Mac両対応キーボードの完成です。
ちなみに私はWindows側で「変換」にIMEオン、「無変換」にIMEオフの機能を割り当てています。


# 参考
[Mint60のキーマップをMacとWindowsで変更する](https://qiita.com/takeauk/items/58c56c7baf1b33afe549)
[QMK Firmware で英字配列のまま Windows と macOS 両対応の IME のオンオフキーを作る](https://qiita.com/ryohey/items/94e4102957d1d4bbb78f)