2. どのようにしてキー入力が動作 (Action) になるのか

キーボード上のあるキーが押されると、いくつものハードやソフトの部品が 協力して、その実際のキーで意図された意味 (文字を表示するとか) を実行する。 とりあえずここでは (ハードウェアの部分はいじれないので) ソフトの側、 それもコンソール出力に関連したイベントに注目してみよう。

  1. キーを叩くと生のキーボードスキャンコードが生成され、 これがキー番号に変換される。i386 上のシステムでは、 普通 BackSpace キーのキー番号は 14 番 になり、Delete キーは 111 番になる。

  2. キー番号は、キーボードライブラリによってキーシンボル (keysym) に変換される。これにはユーザがロードした キー定義ファイルが使われる。キーボードデータベース (例えば RedHat なら /usr/lib/kbd/ 以下) を覗くと、たぶん何種類もの 違ったコンピュータやレイアウト、そして違った解釈 (2 つの Alt キーに別々の働きをさせたい人もいる) のキー定義ファイルがあるのが わかるだろう。Linux コンソールのレイアウトでは、keysym の Delete はキー番号の 14 番に割り当てられており、 Remove が 111 番になっている。ヘンだと思うかもしれないが、 Linux コンソールは VT100 端末をエミュレートするためこうなっているのだ。

  3. まだ先がある。コンソール上のアプリケーションは ASCII 文字列を読む。keysym ではない。だからコンソールは keysym を読んで、 その内容をきちんとエンコードした ASCII 文字列に 変換してやらなくてはならない。たとえば Linux コンソールでは Delete の keysym が ASCII コードの 127 番 (DEL) にマップされている。一方 Remove keysym はエスケープシーケンスになる。BackSpace keysym は ASCII コードの 8 番 (BS) になる。

  4. 最終段階は、ある意味ちょっと遡ることになる - それぞれのキーによって 生成された ASCII 文字列をキー特性 (key capability) に戻すのだ。ここでは端末データベース が用いられる。このデータベースには、それぞれの端末に応じた、文字列からキー特性 (要するに keysym の一部) への対応表が入っている。

    注意: まずいのは、"標準" とされている端末データベースには 2 つの種類があるということだ - termcapterminfo だ。 ディストリビューションにもよるが、どちらか片方だけを使っている かもしれないし、アプリケーションにもよるかもしれない。解説は主に新しい terminfo 向けだが、文中の対応策では 両方を考慮している。

    たとえば Linux コンソールでは、F1 キーは エスケープ文字 + [[A という文字列を生成する。 端末データベースにあるコンソールの項目を参照すると、 これは key_f1 というキー特性に変換されることがわかる (この項目を実際に見てみたければ、infocmp linux と打ってみるといい)。GNUtermcap マニュアルには、端末データベースに関する 非常に徹底した優れた説明が載っている。普通、Linux のアプリケーションは、 より新しい形式である terminfo データベースを使う。 これは ncurses パッケージに 含まれているものだ。

    たぶんここまで来ればもうそんなに驚かないだろうが、terminfo データベース中の Linux コンソールのエントリでは、 DELkbs (バックスペースキー) 特性に対応させている。そしてエスケープに続く [3~ という文字列を kdch1 ("delete-one-char" キー) 特性に対応させている。 これまでは Backspace キーが DEL を出力するのを見て 奇妙に思っていたかもしれないが、端末データベースはすべてを正しく元に 戻しているのであって、正しい振る舞いをしているアプリケーションなら DELkbs キー特性として解釈するのだ。 だからカーソルの左にあるキャラクタを消すというわけだ。