エスリル ニューキーボード − 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 キーのワンショットモディファイヤ化に挑戦するよ。
参考資料
- "USB HID Usage Tables" http://www.usb.org/developers/hidpage/Hut1_12v2.pdf 53〜60ページ
- "Scan Codes Demystified" http://www.quadibloc.com/comp/scan.htm
- "Windows Platform Design Notes - Keyboard Scan Code Specification" http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc