前書き

ついに自作キーボードを作りました。 一生縁がないと思っていたが、、、来るところまで来てしまった。。。。 物理面のカスタマイズもそうですが、ファームウェアもカスタマイズし放題なのが最高ですね。いくらお値段高くても作る人がいるのが納得できます。

さて、今日はファームウェアのカスタマイズのうちの一つを紹介しようと思います。

※筆者は Windows ユーザーです。

困りごと – US/JIS

US キーボードと JIS キーボードでは、記号系のキーの文字コードが違います。 文字コードが違うせいで、“を押しても@が入力されるとか、印字通りに入力されない事象が発生します。

簡単にこのズレ直すには、PC の文字入力モードを US キーボードに切り替えてしまうのが良いです。 ただし、この方法だと変換/無変換などの JIS キーボード限定のキーが入力できなくなります。。。 変換で日本語入力 ON、無変換で日本語入力 OFF とするキーバインドを愛用していて、変換/無変換キーはどうしても欲しいんですよね。 というわけで JIS キーボード限定のキーも押したい。

今回は US キーボードの一部キーの文字コードを書き換えて、US 配列のまま JIS 配列のキーコードが送られるようにします。

QMK ユーザーじゃない Windows ユーザー向けの簡単な方法 – ULE4JIS

手っ取り早くキーコードを書き換えるなら、起動するだけでキーコードを JIS 仕様に書き換えてくれるソフトウェア、ULE4JIS を使うのがオススメです。 筆者もずっとこれ使ってました。

ただ、以下の困りごとがあって、キーボードファームウェアへの組み込みを考えました。

  • リモートデスクトップ時に接続先 PC への入力に反映されない。
  • Windows でしか使えない。

これくらいなら我慢しろよ感はありますが。笑 仕事の都合でよくリモートデスクトップしてたので、結構ストレスでした。

QMK への実装

キーコード書き換え部分実装

eswai さんが既に実装されていますので、これをありがたく拝借しました。 先人の知恵本当にありがたい。。。

/* Copyright 2018-2020 eswai <@eswai>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
  OSで日本語キーボード(logical bit pairing)と設定/認識されているキーボードで、
  USキーキャップの文字、記号(typewriter pairing)を正しく出力する。
  例: Shift + 2 で @ を入力する
  変換された文字はキーリピートが無効です。
*/

#include QMK_KEYBOARD_H
#include "keymap_jp.h"

const uint16_t us2jis[][2] = {
  {KC_LPRN, JP_LPRN},
  {KC_RPRN, JP_RPRN},
  {KC_AT,   JP_AT},
  {KC_LBRC, JP_LBRC},
  {KC_RBRC, JP_RBRC},
  {KC_LCBR, JP_LCBR},
  {KC_RCBR, JP_RCBR},
  {KC_MINS, JP_MINS},
  {KC_EQL,  JP_EQL},
  {KC_BSLS, JP_BSLS},
  {KC_SCLN, JP_SCLN},
  {KC_QUOT, JP_QUOT},
  {KC_GRV,  JP_GRV},
  {KC_PLUS, JP_PLUS},
  {KC_COLN, JP_COLN},
  {KC_UNDS, JP_UNDS},
  {KC_PIPE, JP_PIPE},
  {KC_DQT,  JP_DQUO},
  {KC_ASTR, JP_ASTR},
  {KC_TILD, JP_TILD},
  {KC_AMPR, JP_AMPR},
  {KC_CIRC, JP_CIRC},
};

bool twpair_on_jis(uint16_t keycode, keyrecord_t *record) {
  if (!record->event.pressed) return true;

  uint16_t skeycode; // シフトビットを反映したキーコード
  bool lshifted = keyboard_report->mods & MOD_BIT(KC_LSFT); // シフトキーの状態
  bool rshifted = keyboard_report->mods & MOD_BIT(KC_RSFT);
  bool shifted = lshifted | rshifted;

  if (shifted) {
    skeycode = QK_LSFT | keycode;
  } else {
    skeycode = keycode;
  }

  for (int i = 0; i < sizeof(us2jis) / sizeof(us2jis[0]); i++) {
    if (us2jis[i][0] == skeycode) {
      unregister_code(KC_LSFT);
      unregister_code(KC_RSFT);
      if ((us2jis[i][1] & QK_LSFT) == QK_LSFT || (us2jis[i][1] & QK_RSFT) == QK_RSFT) {
        register_code(KC_LSFT);
        tap_code(us2jis[i][1]);
        unregister_code(KC_LSFT);
      } else {
        tap_code(us2jis[i][1]);
      }
      if (lshifted) register_code(KC_LSFT);
      if (rshifted) register_code(KC_RSFT);
      return false;
    }
  }

  return true;
}

キーコード書き換え部分挙動

  • US -> JIS 変換表を設定する。
  • SHIFT が押されていれば、入力を SHIFT 込みのキーコードに書き換える。(=skeycode)
  • skeycode が変換表に
    • 合致すれば、変換したキーコードを送信する。(tap_code からの return false)
    • 合致しなければ、書き換えずにキーコードを送信する。 (return true)

process_record_user 実装

この twpair_on_jis を、keymap.c の process_record_user から呼び出すようにしました。 その実装が以下の箇所です。といっても入力を上記関数に丸投げしてるだけ。

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  ...中略
  switch (keycode) {
	...中略
    default:
	  ...中略
      if (user_config.jis){
          return twpair_on_jis(keycode, record);
      } else {
          return true;
      }
  }
}

レイヤーの処理とかも書くかと思うので、この処理は一番最後にするのが普通かなと思います。

US のキーコードをそのまま使いたい場合もあるので、user_config.jis で切り替えられるようにしています。 また、この設定は EEPROM に書き込んでいて、電源が切れても元の状態を復元できるようにしていますが、今回は省略します。

あとがき

これ設定してからリモートデスクトップ時や別 PC での使用時に、設定の違いに悩まなくて済むようになりました。快適も快適。

あまりこういった記事を見ないように思いますが、自作キーボードユーザーはこのへんに悩んでいないんですかね。。PC 側の設定でどうにかしてる、とかかなぁ。

既存の US キーボードでも同じようにやりたい、って方は Keyboard Quantizer がオススメです。私もこれ使ってました。
ULE4JIS -> Keyboard Quantizer -> 自作キーボード と辿ってきたので、いよいよ首まで沼に浸かってる気がする。

余談

US キーボード、キーの配置に無駄がなくてすごく好き。 ‘と"が押しやすい位置にいるとか、それだけでプログラマーは買って使うべきかなと思ってます。

そもそも、ソフトのショートカットキーとかも、US キーボード基準に設定されてたりするので、 押しやすかったり覚えやすかったりね。 とりあえず使ってみよう、US キーボード。