エスリル NISSE ファームウェア改造ガイド (3)

エスリル ニューキーボード − NISSEファームウェアを自分用に改造するメモ。

5. Fn 面のマッピングを変える

Fn キーを押しているときのキー割り当てを定義しているのは KeyboardCommon.c にある3次元配列 matrixFn だ。

static uint8_t const matrixFn[8][12][3] =
{
    {{KEY_INSERT}, {KEY_F2}, {KEY_F3}, {KEY_F4}, {KEY_F5}, {KEY_F6}, {KEY_F7}, {KEY_F8}, {KEY_F9}, {KEY_MUTE}, {KEY_VOLUME_DOWN}, {KEY_PAUSE}},
    {{KEY_LEFTCONTROL, KEY_DELETE}, {KEY_F1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {KEY_VOLUME_UP}, {KEY_SCROLL_LOCK}},
    {{KEY_LEFTCONTROL, KEY_LEFTSHIFT, KEY_Z}, {KEY_LEFTCONTROL, KEY_1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {KEY_LEFTCONTROL, KEY_0}, {KEY_PRINTSCREEN}},
    {{KEY_DELETE}, {KEY_LEFTCONTROL, KEY_2}, {KEY_LEFTCONTROL, KEY_3}, {KEY_LEFTCONTROL, KEY_4}, {KEY_LEFTCONTROL, KEY_5}, {0}, {0}, {KEY_LEFTCONTROL, KEY_6}, {KEY_LEFTCONTROL, KEY_LEFTSHIFT, KEY_LEFTARROW}, {KEY_LEFTSHIFT, KEY_UPARROW}, {KEY_LEFTCONTROL, KEY_LEFTSHIFT, KEY_RIGHTARROW}, {KEYPAD_NUM_LOCK}},
    {{KEY_LEFTCONTROL, KEY_Q}, {KEY_LEFTCONTROL, KEY_W}, {KEY_PAGEUP}, {KEY_LEFTCONTROL, KEY_R}, {KEY_LEFTCONTROL, KEY_T}, {0}, {0}, {KEY_LEFTCONTROL, KEY_HOME}, {KEY_LEFTCONTROL, KEY_LEFTARROW}, {KEY_UPARROW}, {KEY_LEFTCONTROL, KEY_RIGHTARROW}, {KEY_LEFTCONTROL, KEY_END}},
    {{KEY_LEFTCONTROL, KEY_A}, {KEY_LEFTCONTROL, KEY_S}, {KEY_PAGEDOWN}, {KEY_LEFTCONTROL, KEY_F}, {KEY_LEFTCONTROL, KEY_G}, {KEY_ESCAPE}, {KEY_CAPS_LOCK}, {KEY_HOME}, {KEY_LEFTARROW}, {KEY_DOWNARROW}, {KEY_RIGHTARROW}, {KEY_END}},
    {{KEY_LEFTCONTROL, KEY_Z}, {KEY_LEFTCONTROL, KEY_X}, {KEY_LEFTCONTROL, KEY_C}, {KEY_LEFTCONTROL, KEY_V}, {KEY_LANG2}, {KEY_TAB}, {KEY_ENTER}, {KEY_LANG1}, {KEY_LEFTSHIFT, KEY_LEFTARROW}, {KEY_LEFTSHIFT, KEY_DOWNARROW}, {KEY_LEFTSHIFT, KEY_RIGHTARROW}, {KEY_LEFTSHIFT, KEY_END}},
    {{0}, {0}, {0}, {0}, {KEY_LEFTCONTROL, KEY_BACKSPACE}, {0}, {0}, {KEY_LEFTCONTROL, KEY_SPACEBAR}, {0}, {0}, {0}, {0}}
};

この並び順も前出のキーマトリクスに対応している。各要素が配列になっていて3キーまでの同時押しが可能。キーの名前は Keyboard.h に定義されている。"KEY" まで打って Ctrl+Space で補完すれば間違えない。
この matrixFn を好きなように書き換えれば Fn 押下時のキーマップを変更できるが、いくつか罠がある。
罠その1。Fn+F2 (OS) の設定が 109a または 109b の場合、Fn+[M], Fn+[<], Fn+[>], Fn+[/] がそれぞれ [無変換], [変換], [ひらがな], [全角] になるようにハードコーディングされている。これを止めるには KeyboardCommon.c の getKeyFn 関数の次のコードを削除する。

    if (is109()) {
        if (12 * 6 + 8 <= code && code <= 12 * 6 + 11)
            return matrixFn109[code - (12 * 6 + 8)];
    }

罠その2。3キーまでの同時押しが可能と書いたが、モディファイヤとしては Ctrl と Shift しか使えない。Alt と Win も使えるようにするには KeyboardCommon.c の processKeys 関数の case 文に次の分岐を追加する。

case KEY_LEFTALT:
    modifiers |= MOD_LEFTALT;
    break;
case KEY_RIGHTALT:
    modifiers |= MOD_RIGHTALT;
    break;
case KEY_LEFT_GUI:
    modifiers |= MOD_LEFTGUI;
    break;
case KEY_RIGHT_GUI:
    modifiers |= MOD_RIGHTGUI;
    break;

罠その3。[変換] (KEY_INTERNATIONAL4) と [無変換] (KEY_INTERNATIONAL5) がスペースキーに化ける。[変換] と [無変換] がそのまま入力されるようにするには KeyboardCommon.c の processOSMode 関数の次のコード(4か所ある)をすべて削除する。

case KEY_INTERNATIONAL4:
case KEY_INTERNATIONAL5:
    report[i] = KEY_SPACEBAR;
    break;

罠その4。Fn+F3 (LAYOUT) の設定が jp または jp-n の場合、Shift+[0] でアンダースコア(Shift+[\])が入力されるが、この処理もハードコーディングされている。Fn 面に [\] を割り当てたときバッティングするので、KeyboardJP.c にある次のコードを削除する。

case KEY_0:
    if ((mod & MOD_SHIFT) && isJP())
        key = KEY_INTERNATIONAL1;
    break;

KeyboardJP.c にはこの他にも怪しげなハードコーディングがたくさんある。日本語レイアウトを使う人は一通り検証したほうがいい。

筆者のカスタマイズ例

最終的な割り当ては OS 側で(のどかを使って)別途カスタマイズする。ファームウェア上のマッピングは、そのままの状態での実用性を求めるのではなく、カスタマイズの自由度を最大化することを目指す。つまり、単独で存在しないキーを(実際の使用頻度にかかわらず)できるだけたくさん Fn 面に割り当てる。とはいえ、109 キーボードドライバで拾えるキーはそんなに多くないので、全部を単独キーと異なるキーにすることはできない。

  • 下段の16進数はのどかで調べたスキャンコード(Keyboard.h で定義されている値とは異なる)。
  • 小指外側のキー([全角], [英数], [:], []])は、のどかでモディファイヤ化する可能性を考えて、元のキーと同じにしてある。
  • OS のキーボードドライバは、日本語 109 キーボード用の標準ドライバを使う。
  • NISSE は次の設定で使う。(ファームウェア書き込み直後のデフォルト設定。[\] と [¥] が存在しない)
f2 pc
f3 us
f4 roma
f5 d0
f6 c
f7 ms
f8 c-c
f9 off

ソースコード:

static uint8_t const matrixFn[8][12][3] =
{
    {{KEY_PRINTSCREEN}, {KEY_F2}, {KEY_F3}, {KEY_F4}, {KEY_F5}, {KEY_F6}, {KEY_F7}, {KEY_F8}, {KEY_F9}, {KEY_MUTE}, {KEY_VOLUME_DOWN}, {KEY_PAUSE}},
    {{KEY_GRAVE_ACCENT}, {KEY_F1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {KEY_VOLUME_UP}, {KEY_BACKSLASH}},
    {{KEY_SCROLL_LOCK}, {KEY_LEFTALT, KEY_1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {KEY_LEFTALT, KEY_0}, {KEYPAD_NUM_LOCK}},
    {{KEY_CAPS_LOCK}, {KEY_LEFTALT, KEY_2}, {KEY_LEFTALT, KEY_3}, {KEY_LEFTALT, KEY_4}, {KEY_LEFTALT, KEY_5}, {0}, {0}, {KEY_LEFTALT, KEY_6}, {KEY_LEFTALT, KEY_7}, {KEY_LEFTALT, KEY_8}, {KEY_LEFTALT, KEY_9}, {KEY_QUOTE}},
    {{KEY_INTERNATIONAL2}, {KEY_INTERNATIONAL4}, {KEY_PAGEUP}, {KEY_INTERNATIONAL5}, {KEY_INTERNATIONAL6}, {0}, {0}, {KEY_LANG3}, {KEY_NON_US_BACKSLASH}, {KEY_UPARROW}, {KEYPAD_EQUAL}, {KEYPAD_COMMA}},
    {{KEY_INTERNATIONAL1}, {KEY_INSERT}, {KEY_PAGEDOWN}, {KEY_DELETE}, {KEY_INTERNATIONAL3}, {KEY_ESCAPE}, {KEY_APPLICATION}, {KEY_HOME}, {KEY_LEFTARROW}, {KEY_DOWNARROW}, {KEY_RIGHTARROW}, {KEY_END}},
    {{KEY_F15}, {KEY_F16}, {KEY_F17}, {KEY_F18}, {KEY_F19}, {KEY_TAB}, {KEY_ENTER}, {KEY_F20}, {KEY_F21}, {KEY_F22}, {KEY_F23}, {KEY_F24}},
    {{0}, {0}, {0}, {0}, {KEY_BACKSPACE}, {0}, {0}, {KEY_SPACEBAR}, {0}, {0}, {0}, {0}}
};

次回は Fn キーのワンショットモディファイヤ化に挑戦するよ。

参考資料