トラップ <CXL00145_AT_nifty.com>
2003.08.13 Create
2005.03.13 Modify
先の ハード編では、 stowaway keyboard と通信するためのちょっとした回路を製作しました。 ここでは、キーボードからキーコードを得て、 普通にキーボードとして使えるようにしてみます。
なお、本文では SL-Cシリーズとして SL-C7x0/860 に合わせて記述していますが、 SL-B500, SL-C3000 でも動作します(一部キーコードが異なるので、キー割り当てファイルの変更要)。
外部キーボードを実現するポイントは次の3つです。
Zaurus の I/Oポートは /dev/ttyS0 に割り当てられています。 stowaway keyboard の通信プロトコルは、9600bps, data 8bit, non parity, stop 1bit ですので、 この設定でポートを開いて読み込めばいいだけです。 単純なシリアルポート入出力ですので、実際に試してみた方が早いでしょう。
キーを押すことで、どんなコードが受信されるか確かめたのが次の表です。 キーが離された時は、このコードに $80 を OR した値が届きます。
[stowaway keyboard (for visor) key scan code]
コード | キー | コード | キー | コード | キー | コード | キー | コード | キー | コード | キー |
---|---|---|---|---|---|---|---|---|---|---|---|
$00 | 1 | $10 | x | $20 | $30 | - | $40 | * | $50 | Delete | |
$01 | 2 | $11 | a | $21 | $31 | \| | $41 | Enter | $51 | ← | |
$02 | 3 | $12 | s | $22 | Fn | $32 | BS | $42 | ToDo | $52 | ↓ |
$03 | z | $13 | d | $23 | Alt | $33 | 予定表 | $43 | $53 | → | |
$04 | 4 | $14 | f | $24 | $34 | 8 | $44 | j | $54 | ||
$05 | 5 | $15 | g | $25 | $35 | 9 | $45 | k | $55 | ||
$06 | 6 | $16 | h | $26 | $36 | 0~ | $46 | l | $56 | ||
$07 | 7 | $17 | 空白 | $27 | $37 | Space/New | $47 | + | $57 | ||
$08 | Cmd | $18 | Caps | $28 | $38 | @ | $48 | ?_ | $58 | LShift | |
$09 | q | $19 | tab | $29 | $39 | { | $49 | ↑ | $59 | RShift | |
$0a | w | $1a | Ctrl | $2a | $3a | } | $4a | メモ帳 | |||
$0b | e | $1b | $2b | $3b | アドレス | $4b | |||||
$0c | r | $1c | $2c | c | $3c | u | $4c | m | |||
$0d | t | $1d | $2d | v | $3d | i | $4d | < | |||
$0e | y | $1e | $2e | b | $3e | o | $4e | > | |||
$0f | /^ | $1f | $2f | n | $3f | p | $4f | 終了 |
具体的には、'A' のキーが押されたら $11 のコードが届き、 'A' のキーが離されたら、最上位ビットを立てたコード $91 が届きます。 なお、今離したキーで、全てのキーが離されているという場合には、 最後に離されたコード(この場合だと $91)が、もう1回届きます。 詳細は参考文献にありますので、そちらをご覧ください。
当然の事ですが、stowaway keyboard と Zaurus とではキーコードが異なります。 だから、受け取ったコードをそのまま送信しても満足にキー入力できるわけはなく、 コードの変換処理が必要です。
・・・とは言っても処理は簡単です(単にテーブルを引くだけ)。 面倒なのは、Zaurusにどんなキーコードを送らなければならないか調べることです。 まずは、SLシリーズの技術サポートページに情報がありますので、それが参考になるでしょう。
ただ、それだけではちょっと情報が不足してましたので、 カーネルソースを展開し sharp_keycode.h を見て 試行錯誤でテーブルを作りました。
ここまでは、ユーザーレイヤで動いているプログラムが、 キーボードとシリアル通信を行っているだけに過ぎません。 何とかして OS に渡してあげる必要がありますが、 さて、どうしましょ。
・・・というわけで、再びカーネルソースを参照すると、 キーコードとキーのOn/Off状態を引数にして handle_scancode() を呼び出せば良いとあります。 これはドライバのレベルで呼ぶのですが、 都合の良いことにユーザーレイヤのプログラムから簡単に使える方法があります。
1つは VNC のキー入力用ドライバ kbdsim の利用。 参考文献を読むと、/dev/kbdsim に キーコードと キーのON/OFF状態を 2byte 1組で WRITE してあげれば、 kbdsim 内部で WRITE 要求を受け取って handle_scancode() してくれるそうです。 VNC Server が入っていれば(入ってなくても kbdsim.o を入れて insmod すれば) 機種非依存で使えて便利です。
そしてもう1つは、SL-Cシリーズ/B500 限定ですが sharp_kbdctl.c の IOCTL を使う方法です。 カーネルソースを展開して見てもらえばわかりますが、/dev/sharp_kbdctl を開いて、 SHARP_KBDCTL_SENDKEY で 4byte の値を渡してあげれば、 一度に ON/OFF 情報を含めて 最大6個 のコード送信ができます。 他にもキーボード制御のIOCTLがあるので、機種限定とはいえ結構便利に使えます(最初から入ってますし)。
ともかく、このいずれかを使ってあげれば、ユーザーレイヤからキー入力できます。
以上を踏まえて 2003年2月 に作成し、日記ページで公開したのが、ser_code_ksim の初版です。 ser_code をベースに、 ksim を真似て /dev/kbdsim によるキー入力から始めたため、 ser_code_ksim という名称にしました。
公開した最初の ser_code_ksim。 借り物の SL-C700 を使って2日間で仕上げたものなので、 とりあえず動かしてみたというレベルでしかありません。 実際、問題点も多かったですね。
これらの問題はあったものの 端末エミュレータ上だけでなく GUI上でも普通に使え、 CtrlキーもPCとほぼ同様に使えるなど、やはり外部キーボードは便利だと再認識させてくれました。
SL-C760 を導入したので、約束どおり ser_code_ksim の不具合を修正。 palm 用キーボードには対応していないものの、キーリピートも効くし、 CPU負荷も大幅に減らして実用的なものとなりました。
ただし、どうせ公開するなら palm キーボード対応版に仕上げてからの方が良いだろうというのと、 キー割り当ての自由度を高めたいといった理由から、ごく一部の方にテストしてもらったのみで 未公開としています。
多くの不具合を解消し、新たに次の機能を追加。
概ね、こんなところで機能的には一区切りでしょうか。 残件としては、もし palm用キーボードからの HotSync 信号を WakeUp で受けられるのであれば、 それに対応させればよりスマートかな?というところです。
パッケージ化するついでに、処理の見直しを行いました(一番時間かかったのはアイコン作成でしたが・・・)。
※なお、パッケージ名の都合で - (ハイフン)と _ (アンダースコア)が、 従来とは逆になってしまいました(実行ファイルはそのまま)。
SL-C3000 のキーコードが従来と一部異なるため、専用のキー割り当てファイルを作成しました。 従来の SL-C 用キー割り当てファイルも一緒に 下記 download に置いておきます。 ダウンロードして、/opt/QtPalmtop/etc/ 以下に入れて使ってください。
設定タブの、ソフトウェアの追加/削除 から行ってください。 インストールされるファイルは下記になります。
アーカイブをどこか適当な実行パスの通っているところに展開してください。 /usr/local/bin/ に展開してもいいでしょうし、 /home/zaurus/ に展開しておいてターミナル開いて ./ser_code_ksim で実行というのでもいいでしょう。 この辺りはお好みに合わせてということで。
[ホームディレクトリ(/home/zaurus/) に入れた場合の例]
# cd /home/zaurus # tar xzvf ser-code-ksim_1.0.0.tar.gz展開すると、実行ファイルである ser_code_ksim と、設定ファイル ser_code_ksim.ini, ser_code_direct.ini, ソースファイル ser_code_ksim.c ができます。 使うだけであれば、ソースファイルは不要ですから消しても結構です。
設定タブの、ソフトウェアの追加/削除 からアンインストールしてください。
もし設定ファイル (ser_code_ksim.ini) を変更した場合は消されずに残るはずですので、 不要なら手作業で消してあげてください。
展開したもの (ser_code_ksim, ser_code_ksim.ini, ser_code_direct.ini, ser_code_ksim.c など) を削除してください。
[ホームディレクトリ(/home/zaurus/) に入れた場合の例]
# cd /home/zaurus # rm ser_code_ksim ser_code_ksim.ini ser_code_direct.ini ser_code_ksim.c
Home の アプリケーションタブに、keyboard start と joypad start, kbd/js stop の 3つのアイコンがありますので、 こちらから起動/停止が可能です。
実際には、シェルスクリプト sck_kup, sck_dup, sck_down を呼んでいるだけですので、 コマンドラインからスクリプトを実行しても構いません。
複数のターミナルが上がる環境であれば、ser_code_ksim のあるディレクトリに移って、 ./ser_code_ksim で起動するのが楽でしょう(止める時も Ctrl-C で止められるし)。 ターミナルが1つしか上がらない環境ならば、./ser_code_ksim -b でデーモン化すると良いです。 カレントディレクトリに設定ファイルが無い場合は、 後述の -m オプションで設定ファイルの場所を指定してあげてください。 設定ファイルを複数用意しておいて、-m オプションで配列を切り替えて使うということも可能です (CapsLock に Ctrl を割り当てた配列だとか、US配列だとか)。
※無論、PATH の通ったところに実行ファイルを置いた場合は ser_code_ksim で実行できます。
Ctrl-C で停止させてください(Zaurus本体キーボードなら Fn + C)。 シグナルを受けるとポートを閉じて正常に終了します。
ser_code_ksim のプロセス番号を調べて、kill でシグナルを送ってください。 シグナルを受けるとポートを閉じて正常に終了します。
# kill `ps -o pid= -C ser_code_ksim` または # ps -ef | grep ser_code_ksim | grep -v grep # kill 調べたプロセス番号
ser_code_ksim -h で使い方が表示されます
# ./ser_code_ksim -h Usage: ser_code_ksim [OPTION] -p : serial port device name (defalt: /dev/ttyS0) -k : vnc kbdsim module use -i : debug info print -d : direct mode -b : background daemon -v : print version -h : display this message -m : key mapping file name default: /opt/QtPalmtop/etc/ser_code_ksim.ini (or ser_code_direct.ini)
デフォルトではシリアルポートとして /dev/ttyS0 を、 設定ファイルは /opt/QtPalmtop/etc/ser_code_ksim.ini (ダイレクトモード時は ser_code_direct.ini) を見るようになっています。 例えば、シリアルポートに /dev/ttyS1 を使い、設定ファイルは /etc/ser_code_ksim.ini を使う場合には、 次のように指定することになります。
# ./ser_code_ksim -p /dev/ttyS1 -m /etc/ser_code_ksim.ini
標準では、/dev/sharp_kbdctl を使ったキー入力を行いますが、 VNC の /dev/kbdsim を使う場合には、-k オプションを指定してください。 なお、/dev/kbdsim は通常は root 権限でないと使えないようになっていますので、 su して root ユーザになってから実行するとかしてください。
# ./ser_code_ksim -k
# ./ser_code_ksim -i
通常モードでは、キーを押すことで Zaurus 用のコードを作成してキー入力を行います。 この時、内部的にはキーを離す処理や、キー割り当て変更により意図しないキーも押されます。 普通の文書入力ならこれでも良いのですが、 キーのON/OFF状態を必要とするゲームのようなアプリケーションにとっては困るため、 修飾キー処理を行わずに "N" 指定の行のみ有効とし、キーを押した/離したをダイレクトに OS に伝えるモードです (この場合、設定ファイルには修飾キー Shift, Ctrl, Fn, cMd の分も通常キーとして設定しておく必要あり)。
# ./ser_code_ksim -d
単に ser_code_ksim を起動したのでは、そのターミナルが占有されてしまいます。 ser_code_ksim & のようにすれば裏にまわすことができますが、 それでも起動したターミナルに関連づけられていることに変わりはありません。 -b オプションを指定すれば、バックグラウンドで動くデーモンになってくれます。
# ./ser_code_ksim -b
※なお、標準の Terminal (qpe-terminal-ja_1.5.0-3_arm.ipk) では、それでも少々問題が出る (実行した後に Terminal を閉じてしまうと、停止するまで Terminal に入れなくなる)があります。 embedded-console 等を使うか、または 1.1.0 から追加した HOME 画面からの起動/停止が便利でしょう。
2003年12月版から、設定ファイルの位置が変わりました。 -m オプションで明示的に指定しなければ、モードに応じて次のファイルが使用されます。
2003年8月版以降から、キー割り当て設定ファイルのフォーマットが大きく変わりました。 設定ファイルは、大きく分けて "キーリピート速度の設定", "修飾キーの定義", "通常キーの定義" の3つのブロックに分かれ、修飾キーも含めて任意の割り当てが可能です。 行頭が # (シャープ)の行や空行はコメント行として無視されます。 付属の ser_code_ksim.ini をもとにして、 好みの割り当てに修正して使うと良いでしょう。
キーは、それ自身では働きを持たない修飾キーと、それ自身で働く通常キーの2種類にわけられます。 修飾キーは、(便宜上)Shift, Ctrl, Fn, cMd の4種類があり、それぞれ最大 2個 定義可能です。 これら修飾キーは、通常のキーが押された時に、どのコードを出力するかを選択するためにあります。 つまり、普通は '1' なのに、Shift を押しながらだと '!' になるといったものです。
便宜上、Shift,Ctrl,Fn,cMd と呼んでいますが、別にその通りのキーを割り振る必要はなく、 例えば stowaway keyboard の CapsLockキー(A の左隣)を Ctrl にしても良いのです。 何でしたら、親指シフトキーボードのような配置にしても構いません。 Shift, Ctrl は必須でしょうが、Fn, cMd などは必要なければ修飾キーとして定義しなくても結構です。
書式: {keyrep_first | keyrep_next } 値(1〜32)
first は初回のリピート開始までの時間、nextはそれ以降のリピート時間。 どちらも 0.1秒 単位で指定し、値が大きいほどリピートが遅くなります。 デフォルトで 3, 1 に指定されていますので、変更の必要はないでしょう。
keyrep_first 3 keyrep_next 1
書式: {lshift | rshift | lfn | rfn | lcmd | rcmd | lctrl | rctrl } stowawayのキーコード
Shift, Ctrl, Fn, cMd のそれぞれの役割に対し、左右の2個(l,r)を指定可能。 以下の例では、左シフト、右シフト、左Fn、左Cmd、左Ctrl のみを定義している。 修飾キーとして指定したキーは、たとえ通常キー定義で指定されていても、こちらが優先される。
lshift 58 rshift 59 lfn 22 lcmd 08 lctrl 18
書式: stowawayのキーコード コメント 修飾キー組み合わせ(SCFMN) 4byteのZaurusキーコード指定
A のキーに対する定義例を以下に示します。 stowaway キーボードで A が押されると 11 が来ますから、第1項目は 11 ですね。 第2項目は、人が見てわかりやすいようにキーの名称などを記述します(空白,TAB は含めてはならない)。 第3項目は、修飾キーがどの状態の時の設定かを示します(後述)。 第4項目は、この時に Zaurus に送るキーコードの指定です(後述)。
11 a N 03000001 11 A S 0f001b01 11 ^A C 0f006801 11 ^A CS 3f1b6801この例では、そのまま押した時には 03000001 を出力。 Shiftキーを押しながらなら 0f001b01 を出力。 Ctrlキーを押しながらは 0f006801 を出力。 CtrlとShiftを一緒に押しながらなら 3f1b6801 を出力します。 他の修飾キーの組み合わせの場合は、何も出力しません。
通常キーの定義行での、修飾状態の指定について説明します。
何の修飾キーもいらない場合(そのまま押した場合)の指定には N を、 Shift を押している時なら S を、 Shift と Ctrl を押している時なら SC のように修飾子を並べて指定します(順番は関係ないので CS でも同義)。 CFMS のように指定した場合には、Ctrl, Fn, cMd, Shift の修飾キー全てが押されている時という指定になります。
CS と記述した場合には、Ctrl と Shift が両方押されている時(AND条件)という意味ですので、 仮にどちらかが押されていれば良いという場合(OR条件)ならば、 C だけの行と S だけの行の 2行を記述してください。
上記で何の説明も無しに 03000001 だの 3f1b6801 だのと書いていますが、 これは /dev/sharp_kbdctl への送信指定に合わせた Zaurus のキーコード指定です。 この4バイトは、ON/OFF フラグと3つのZaurus用キーコードを合わせたもので、 上位バイトから順に、1バイトずつ, フラグ, コード3, コード2, コード1となっています。
フラグ | コード3 | コード2 | コード1 | |
---|---|---|---|---|
4byteコード | 3f | 1b | 68 | 01 |
フラグバイトは 2bit ずつ 4組の値に分かれます。 上記の例では フラグバイトは 3f ですが、 これを2進数表記して 2bit ずつ分けると 00_11_11_11 となり、それぞれの組が コード3, コード2, コード1 に対応します。
--- | コード3 | コード2 | コード1 | |
---|---|---|---|---|
フラグ部bit | 00 | 11 | 11 | 11 |
2bitのフラグは、更に細かく見ると、 上位ビットがキーを離すコード送信の指定、下位ビットがキーを押すコード送信の指定となります。 1 を指定した場合にはコードを送信し、0 の場合には何もしません。 通常は、キーを押して離すで1セットですから、このように 11 となるのがほとんどでしょう。
Release flag | Press flag |
---|---|
1 | 1 |
つまり、この例 ( 3f 1b 68 01 ) であれば、次のようなキー入力操作になるというわけです。
同様にして、0f 00 1b 01 であれば、
03 00 00 01 であれば、
要するに、3つのキーの ON/OFF 指定をまとめて表記しているだけだと考えてください。 面倒であれば、1byte xx を送るだけなら 030000xx で、2byte yy xx を送るなら 0f00yyxx で、 3byte zz yy xx を送りたいなら 3fzzyyxx を指定すると思ってください。
ちなみに、上記で例にあげた コードで、1b は Zaurus の左SHIFT、 68 は Zaurus の Ctrl キーという扱いになっています。 SL-C7x0/860 本体には Ctrl キーは存在しないのですが、コードとしては 68 でいけます (SL-C3000 では 38 です)。 Zaurus のキーコードについては、 カーネルソースの sharp_keycode.h や、/opt/QtPalmtop/etc/keycode.tbl が参考になります。
SL-C7x0/860, C3000 で確認したキーコードの一部を載せておきます(16進数表記です)。
キー | SL-C7x0/860 | SL-C3000 |
---|---|---|
DELETE | 51 | 51 |
TAB | 41 | 41 |
SHIFT | 1b | 1b |
ENTER | 1c | 1c |
Fn | 1e | 1e |
カナひら | 79 | 45 |
全/半 | 7a | 46 |
CTRL | 68 | 38 |
ALT | 6a | 39 |
HOME | 28 | 28 |
CANCEL (ESC) | 22 | 22 |
OK | 27 | 27 |
MENU | 1d | 1d |
LEFT | 23 | 23 |
UP | 24 | 24 |
DOWN | 25 | 25 |
RIGHT | 26 | 26 |
カレンダー | 58 | 58 |
アドレス帳 | 59 | 59 |
メール | 5a | 5a |
*割り当て機能 | 47 | 3a |
メール受信実行 | 6e | 6e |
画面キャプチャ | 73 | 73 |
PCリンク開始 | 75 | 75 |
BACK_SPACE | 1f | 1f |
記号入力ボード | 20 | |
Num Lock | 20 | |
ライト(トグル) | 21 | 21 |
電源OFF | 6d | 6d |
漢字モード | 5f | |
縦持ち時のOK | 7b | 54? |
同CANCEL | 7c | 5e |
同ジョグアップ | 7d | 7d |
同ジョグダウン | 7e | 7e |
リモコン再生 | 65 | 3d,40 |
リモコン停止 | 64 | 3e,44 |
リモコン巻き戻し | 63 | 42,74 |
リモコン早送り | 62 | 43,6c |
リモコンボリュームUP | 60 | 76 |
リモコンボリュームDOWN | 61 | 77 |
リモコンミュート | 78 |
ser_code_ksim はキーボードモードで動作している場合、 内部的にキーを押してから離すまでを一度に処理しています。 この為、KeyHelper で Zaurus の Address キーを Launch にした時などにうまく働きません。 その場合は、次のように 030000xx を 010000xx に変更してください。 前者は xx のコードを押して離す設定、後者は xx のコードを押すだけという設定です。
# アドレス帳を Launch に設定する例 42 ToDo N 01000059
この他、Shift + Home などを利用したい場合には、 次のように Shift 時に送信するコードも指定しておく必要があります。
# Home, Shift + Home を働かせるための例 33 Yotei N 03000028 33 Yotei S 0f001b28 # Menu, Shift + Menu を働かせるための設定 3b Address N 0300001d 3b Address S 0f001b1d
バイナリだけで構わない方は ipk を、ソースも欲しい方は .tar.gz をどうぞ。