top page > Klaviatur > here

console におけるキーボード


概要

対象は次のようなものです.

  1. キーボードは PC-98 専用,および AT 互換機 (PS/2 および USB)
  2. FreeBSD は 4 系以降
  3. console (X Window System は別のページに.)

目的は次のようなものです.

  1. console におけるキーボードに関する予備知識を提示する.
  2. 標準で用意されていない自前の設定を行なう際の資料を提示する.

目次

1. 予備知識
1.1 キーマップの選択と切り換え
1.2 キーマップの書式
1.3 キーマップの書き換え
1.4 補足 (1)
1.5 補足 (2)
1.6 補足 (3)
2. PC-98
3. AT 互換機
4. 参考資料

1. 予備知識

1.1  キーマップの選択と切り換え

キーマップは /usr/share/syscons/keymaps/ にあるファイル *.kbd に記述されており,これらの中から選択をすることにより設定します. (キーマップの名称は,これらのファイル名から拡張子 ".kbd" を除いたものです.) ただし,

jp.pc98.kbd       ← こちらが標準です.
jp.pc98.iso.kbd   ← これは何に使うのかわかりません.

PC-98 専用,また

jp.106.kbd        ← こちらが標準です.
jp.106x.kbd       ← [CTRL] と [CAPS] を入れ替えたものです.

jp106 専用で,残りは (おそらく) us101 のためのものなのですが,キーボードに応じて自動的に選択肢が絞られるわけではなく,すべてが選択できてしまうので要注意です.

キーマップを切り換える方法には,次の三通りがあります.

(1) (文字ベースの) GUI を用いて変更する.(再起動したら default に戻る.)

% kbdmap

(2) command line にて変更する.(再起動したら default に戻る.)

# kbdcontrol -k /dev/kbd0 < /dev/console
# kbdcontrol -l jp.106

(3) /etc/rc.conf を用いて OS の起動時に指定する. (default からの「切り換え」.)

keymap="jp.106"

このファイルで keymap を指定しない場合,または

keymap="NO"

とした場合には,キーマップとして driver 内部に持っているデータが使われます.

なお,sysinstall の "K キーマップ" を使ってのキーボードの選択は,機能としては (1), (3) を組み合わせたものです.

1.2  キーマップの書式

キーマップを記述したファイルはテキストであり,エディターを使って内容を確認したり変更したりすることができます. 先ず us.iso.kbd を見てみましょう.

# $FreeBSD: src/share/syscons/keymaps/us.iso.kbd,v 1.16 2001/03/11 23:41:19 ache Exp $
#                                                         alt
# scan                       cntrl          alt    alt   cntrl lock
# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state
# ------------------------------------------------------------------
  000   nop    nop    nop    nop    nop    nop    nop    nop     O
  001   esc    esc    esc    esc    esc    esc    debug  esc     O
  002   '1'    '!'    nop    nop    '1'    '!'    nop    nop     O
  003   '2'    '@'    nul    nul    '2'    '@'    nul    nul     O
(中略)
  046   'c'    'C'    etx    etx    'c'    'C'    etx    etx     C
(中略)
  083   del    '.'    '.'    '.'    '.'    '.'    boot   boot    N   ← Key Pad '.'
  103   fkey61 fkey61 fkey61 fkey61 fkey61 fkey61 boot   fkey61  O   ← DEL
(中略)
  104   slock  saver  slock  saver  susp   nop    susp   nop     O
  105   fkey62 fkey62 fkey62 fkey62 fkey62 fkey62 fkey62 fkey62  O
  106   fkey63 fkey63 fkey63 fkey63 fkey63 fkey63 fkey63 fkey63  O
  107   fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64  O
  108   nop    nop    nop    nop    nop    nop    nop    nop     O

また,ru.koi8-r.kbd も見てみましょう.

# $FreeBSD: src/share/syscons/keymaps/ru.koi8-r.kbd,v 1.15 2001/04/09 16:36:48 sobomax Exp $
#                                                         alt
# scan                       cntrl          alt    alt   cntrl lock
# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state
# ------------------------------------------------------------------
  000   nop    nop    nop    nop    nop    nop    nop    nop     O
  001   esc    esc    nop    nop    155    155    debug  nop     O
  002   '1'    '!'    nop    nop    177    161    nop    nop     O
  003   '2'    '@'    nul    nul    178    192    128    128     O
(中略)
  128   nop    nop    nop    nop    nop    nop    nop    nop     O
  129   esc    esc    nop    nop    155    155    debug  nop     O
  130   '!'    '1'    nop    nop    177    161    nop    nop     O
  131   '"'    '2'    nul    nul    178    192    128    128     O
(中略)
  235   fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64 fkey64  O
  236   nop    nop    nop    nop    nop    nop    nop    nop     O

次にこれらの読み方を概説します.

  1. 行頭の '#' は,その行がコメントであることを意味します.
  2. scancode は,(1) 0 から 127 まで,(2) 128 から 255 までの二組で構成されます. ただし,
  • 後者は必ずしも必要ありません. 例えば,jp.pc98.kbd, jp.106.kbd, us.iso.kbdscancode が 127 までしかありません.
  • 数字は小さい順でなければなりませんが,欠番は許されます. 欠番はすべて nop にされます.
  • (1) と (2) の間の切り換えは,ashift または alock で行ないます.
    scancode を 127 までしか記述していない場合,alock を設定してそのキーを押すと,128-255 はすべて nop なので K/B が効かなくなります.
  1. あるキーに対して,それと同時に押す修飾キー shift, control, alt の組み合わせにより,8 通りの内容を入力することがでます. キーマップには,それらが横並びに記述されています.
    (必ずしも文字の入力とは限りません. 例えば scancode 103 は control + alt + DEL で reboot するように設定されています.)
  2. 入力される内容は,'1' または 155 のような文字コード (10 進) または esc のような予約された文字列のいずれかにより指定します.
  3. 一番右側の列は,このキーがどの Lock Key の影響を受けるかを指定します. すなわち,
C : clock (Caps Lock) の影響を受ける.
N : nlock (Num Lock) の影響を受ける.
B : clock, nlock の両方の影響を受ける.
O : あらゆる lock の影響を受けない.

Lock Key の「初期状態」はすべて off です. これを指定する方法があるのか否かはわかりません.

  1. 修飾キーを表わす文字列としては次のようなものがあります. (代表的なもののみ.)
押しながら使うもの : lshift, rshift, lalt ,ralt, lcntrl, rcntrl, ashift
Lock toggle のもの : clock, nlock, alock

1.3  キーマップの書き換え

console においては,X Window System の xmodmap のようにキーの役割を変えるツールはないので,それをやりたければキーマップを書き換えるしか手段はありません. ただし,キーマップの変更は一歩間違うと大変なことになるので要注意です! これに初めて取り組む場合は,練習用の HDD + OS を仕立てた方が無難でしょう.

既存のファイルを変更する場合は,必ず backup を取っておくべきです.

# cp -p jp.106.kbd jp.106.kbd.org   ← ここに余分なファイルがあっても副作用はない.
# vi jp.106.kbd                     ← 修正する.

新規に作成する場合の要領は以下の通りです.

# cp jp.106.kbd jp.106n.kbd   ← 元になるキーマップを cp する.
# vi jp.106n.kbd              ← 修正する.
# vi INDEX.keymaps            ← このファイルに jp.106n.kbd を追加する.
                                 kbdmap command を使わないならこの作業は不要.

1.4  補足 (1)

FreeBSD の提供する文書 (man page) においては,alock, ashift によって切り換える scancode 128-255 の部分に関する記述が不完全なように思えます. 以下の三つの節を使って,この部分を補足します.

先ず,"scancode" という用語を再検討します. system scancode とキーマップの一列目の項目である scancode は,違う意味のものが scancode という言い方で混用されています.

キーの入力に対して PC が得る system scancode は,キーを識別するだけでなく,キーの状態の情報も含んでいます. すなわち,キーの状態を表わす最上位の 1 bit とキーを識別する 7 bit とから成ります. (キーを識別する部分に独自の用語が欲しいですね.)

一方,キーマップの一列目の項目の scancode ですが,これは本来はキーを識別するためだけのものであり,その値の範囲は 0-127 のはずです. しかし,なぜか 128-255 の値も設定できます. それをどう解釈すれば良いのでしょうか?

driver の中では,キーを識別する 7 bit を

keycode = scancode & 0x7F;

のように,新たな変数 keycode を導入して表わしています. [1] そして,alock または ashift が ON の場合には,この値に 128 を足して 128-255 の範囲の値に変換しています. そして,この変数によってキーマップを参照しています. すなわち,「キーマップの項目としての scancode」は実はこの keycode のことです.

ですから,先ずキーマップの論理的な構成として,128 を足さない,キーを識別するためだけの keycode 0-127 に対して,修飾キーとして ashift も加えた 16 通りについて書いた表を考えると良いでしょう. 次にそれを 8 通りづつ 2 組に分け,ashift に関係する方の組を後に置いて,それらの keycode に 128 を足してもう一方の組と区別することにすれば,それが現実の書式のキーマップです. (ただし,補足 (3) で述べるように lock state に絡んでもう一捻りあります.)

[1] ややこしいですが,"keycode" という用語は X Window System でも別の意味で使っています.

1.5  補足 (2)

ここでは,"alt" という用語を再検討します.

% man 5 kbdmap

にて "alt" に関わるいくつかを抜粋すると,次のようになります.

     lalt|alt      Act as left alt key.
     ralt          Act as right alt (altgr) key.
     alock         Act as alt lock key.
     ashift        Act as alt shift key.

この文書は,"alt" を二つの意味で混用しているように考えます. すなわち,キーマップに記述された 8 通りの状態のうち後半の 4 通りに切り換える操作と,scancode の 0-127 と 128-255 を切り換える操作とをです. 本来の "alt" の意味は前者だけのはずです. そう了解すれば,alock は "alt lock" ではなく,また ashift も "alt shift" ではありません.
(ralt には "altgr" という悩ましい説明が付いていますが,source を見る限り lalt と同じ機能です.)

一方,/usr/src/sys/sys/kbio.h では alock された状態を "AltGr locked" (alternate group locked) と呼んでいます. この group という呼称は X Window System の同様の機能の呼称とも一致するので,alock, ashift は各々 "alternate group lock", "alternate group shift" と呼ぶのが適切でしょう.

driver の source (/usr/src/sys/dev/kbd/kbd.c) の中では,"alt" と "alternate group" とは,記号定数 ALTSAGRS により区別されています.

1.6  補足 (3)

scancode 128-255 を,同 0-127 の alt の効きを逆にした,すなわち前半の 4 通りと後半の 4 通りを入れ換えたものにする必要はありません. しかし,基本的にはそう設定した方が使い易いでしょう.

このような設定をここでは「対称」と呼ぶことにします. 例えば,ru.iso5.kbd はほぼ対称ですが,ru.koi8-r.kbd は非対称です.

「対称」が完全に実現できない場合や,それにこだわるとかえって不便な場合もあります. 例えば,

(1) latin は 26 文字,cyrillic は 33 文字なので,latin では記号,cyrillic では文字となるようなキーが 7 つ生じます. そこで例えば,

  026   '['    '{'    esc    esc    229    197    esc    esc     O

に対応する (alock/ashift で切り換わる) scancode は 26+128=154 ですが,cyrillic 文字には clock を効かせたいです. lock state は独立して設定できますから [2],それは可能です.

  154   229    197    esc    esc    '['    '{'    esc    esc     C

ただし,たとえそうしたとしても,このキーを種々の修飾キーと組み合わせた場合,

  このキーと組み合わせる修飾キー  : 得られる結果
                 base,     shift  : [, {
clock         + (base,     shift) : [, {
        slock + (alt,  alt+shift) : [, {
clock + slock + (alt,  alt+shift) : {, [   ← この場合の順序が逆になる!

のようになってしまい,対称性を完全に実現することはできません.
(X Window System は,それが文字か記号かなどを識別するデータも持っており,修飾キーの効きに関しては console の場合のように二次元的な管理をしていないので,このような問題は生じません.)

(2) Ctrl + Alt + Del は「対称」にしない方が良いでしょう. alock が ON の状態においては,Ctrl + Del の二つのキーで reboot してしまうからです.

[2] キーマップが修飾キーに対して 16 通りでなく 8 通りが 2 組なのはそのためにだと考えます.

2. PC-98

ここには,PC-98 にて Lock Key を使う場合の注意点を書きます.

AT 互換機は,Lock/Unlock の機能を,それらに対応した LED の点灯も含めて software で実現しており,すべてのキーが対等です. 一方,PC-98 の [CAPS][かな] とは,キーボードの中で制御が完結した,他のキーとは別扱いの Lock Key です. LED の点灯も,これらのキーに割り当てられた機能に依らず,キーそのものに連動しています. これらを FreeBSD にて Lock Key として使う場合には特別の配慮が必要なのですが,それがなされているのは clock のみです. したがって,次のような挙動をします.

よって,例えば [かな]alock の機能を割り当てたいとすると,選択肢は二つあります. すなわち,

  1. 上記の挙動を逆手にとって,[かな]ashift を割り当てる. (こちらが合理的!)
  2. alockclock と同様に特別扱いするように driver を修正する.

/usr/share/syscons/keymaps/jp.pc98.kbd[かな] キーの部分は次の通りです.

  114   lalt   lalt   lalt   lalt   lalt   lalt   lalt   lalt    O

ここに ashift を割り当てるのであれば,こう修正します.

  114   ashift ashift ashift ashift ashift ashift ashift ashift  O
  242   ashift ashift ashift ashift ashift ashift ashift ashift  O

そうでなく,driver の修正を行なうならば,ここはこう修正します.

  114   alock  alock  alock  alock  alock  alock  alock  alock   O
  242   alock  alock  alock  alock  alock  alock  alock  alock   O

driver は次のように修正します. (FreeBSD 4.8 用の patch ですが,今でも大差ないと思います.)

--- /usr/src/sys/dev/kbd/kbd.c.org      Tue Jul 31 01:46:43 2001
+++ /usr/src/sys/dev/kbd/kbd.c  Sun Oct 31 22:43:44 2004
@@ -1107,7 +1107,14 @@
                        state &= ~SLKDOWN;
                        break;
                case ALK:
+#ifndef PC98
                        state &= ~ALKDOWN;
+#else
+                       state &= ~ALKED;
+                       i = state & LOCK_MASK;
+                       (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED,
+                                                      (caddr_t)&i);
+#endif
                        break;
                case NOP:
                        /* release events of regular keys are not reported */
@@ -1144,7 +1151,14 @@
                                set_lockkey_state(kbd, state, SLK);
                                break;
                        case ALK:
+#ifndef PC98
                                set_lockkey_state(kbd, state, ALK);
+#else
+                               state |= ALKED;
+                               i = state & LOCK_MASK;
+                               (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED,
+                                                              (caddr_t)&i);
+#endif
                                break;
                        /* NON-LOCKING KEYS */
                        case SPSC: case RBT:  case SUSP: case STBY:

しかしながら,あくまで私の理解ですが,PC-98 の console では AT 互換機のように font を変えることができません. したがって,scancode 128-255 に対しては default である半角カナしか表示できません. よって,console では [かな] を使う場面はないようにも思えます.
私は,その修正を行ない,ロシア語用のキーマップまで作成してしまってから font のことに気が付きました. この節は,今後現われるかもしれない,PC-98 で font を切り換えるような修正までする人のために書きました.

3. AT 互換機

us101 に関しては,キーマップは既に入念に整備されている状態にあると言えます.

jp106 に関しては,他の言語に対応したければ,us101 用のものを参考にして新たなキーマップ を作るしかありません.

なお,AT 互換機の console 環境で scancode 128-255 を使うようなキーマップを使う場合,CAPS の LED が本来の機能を失い,ALGR に対応した LED になります. PS/2, USB 共にそうなります. これをやめるには,atkbd.cusb.c の "replace CAPS LED with ALTGR LED for ALTGR keyboards" とコメントされている部分を修正するしかありません.

4. 参考資料

driver 内部に持っているキーマップのデータは,以下のファイルにあります.
FreeBSD 4.11 では,/usr/src/sys/dev/kbd/kbdtables.h に PC-98 と AT 互換機の両方のデータがあります.
FreeBSD 6.2 では,PC-98 のデータは /usr/src/sys/pc98/cbus/pckbdtables.h の方にあります.

キーマップの切り換えに関しては,以下に文書があります.

% jman syscons
% jman kbdmap
% jman kbdcontrol

キーマップを記述する際の「予約された文字列」は,以下に文書があります.

% jman 5 kbdmap
% jman keyboard