キーボード ( KB ) ドライバおよびポインティングデバイス ( PD ) ドライバを分離にせずに、1つのドライバにまとめる。
KBPDドライバは、多様な KB や PD に対応するため、 実 IO ドライバと分離した構造とする。 したがって、この KBPD ドライバは実際の KB / PD デバイスには直接依存しない、 IOアクセスを行わないドライバとなる。

(rdv) | 処理要求受け付け用ランデブポート |
(mbf) | 事象通知用メッセージバッファ |
(mbx) | データ用メイルボックス |
(flg) | コマンド用イベントフラグ |
実 IO ドライバは、 デバイスからの KB / PD 操作を固定の形式で、 データ用メイルボックスに送信する。 複数の実 IO ドライバから同一のメイルボックスに送信される。
KBPD ドライバは、 実 IO ドライバで用意したイベントフラグを使ってコマンド ( 1 ワード ) を送信することができる。 複数の実 IO ドライバが存在する場合、 すべてに対してコマンドを送信する。 コマンドとしては、KB の LED の制御などがある。
OS とは独立にリンクし、IMS から次のように起動する。
[IMS]% kerext kbpd [!pri]
pri :
複数の種類の異なるキーボードを接続し、同時に使用するための仕組を持つ。

キーボードの種類ごとにキーテーブル ( KeyTab ) を持つ。
キーボードとキーテーブルは、キーボード ID により対応させる。
同じ種類のキーボードを複数接続した場合は、
それらは同じキーテーブルに対応する。
キーテーブルは、 キーボードが発生するキートップコードに対応するように作成する。
キーマップ ( KeyMap ) には、
キーボードが発生するキートップコードにオフセット値
( KeyTopOfs )
を加えた値をキートップコードとして対応するビットが ON / OFF される。
また、このオフセット値を加えたキートップコードが上位 ( イベント管理 ) へ通知される。
KeyTopOfs は、
種類の異なるキーボードのキートップコードが重複しないようにするために使用できる。
しかし、重複しても不都合がなければ部分的またはすべてが重複するように
KeyTopOfs を設定してもよい。
以下の属性データをサポートする。
| R | 読み込みのみ可 |
| W | 書き込みのみ可 |
| RW | 読み込み / 書き込み可 |
/* KBPD データ番号 */
typedef enum {
/* 共通属性 */
DN_KPEVENT = DN_EVENT,
/* 個別属性 */
DN_KPINPUT = -100,
DN_KPSTAT = -101,
DN_KEYMAP = -102,
DN_KEYTAB = -103,
DN_KEYMODE = -104,
DN_PDMODE = -105,
DN_PDRANGE = -106,
DN_PDSIM = -107,
DN_PDSIMINH = -108,
DN_KEYID = -109,
DN_KPMETABUT = -110,
/* キーボード定義1 (-200 〜 -327) */
DN_KEYDEF_S = -200,
DN_KEYDEF_E = -327,
/* キーボード定義2 (-400 〜 -527) */
DN_KEYDEF2_S = -400,
DN_KEYDEF2_E = -527
} KPDataNo;
DN_KPEVENT :
data: ID
DN_KPINPUT :
data: ID
実 IO ドライバが入力を送信するためのメイルボックス ID
KBPD ドライバ側で初期化時に生成する。
DN_KPSTAT :
data: KPStat
typedef struct {
H xpos; /* X座標位置 */
H ypos; /* Y座標位置 */
MetaBut stat; /* メタ/ボタン状態 */
} KPStat;
typedef enum {
HiraMode = 0, /* 日本語ひらがな */
AlphaMode = 1, /* 英語(小文字) */
KataMode = 2, /* 日本語カタカナ */
CapsMode = 3 /* 英語(大文字) */
} InputMode;
typedef enum {
PdSim_Off = 0, /* PD シミュレーション OFF */
PdSim_Std = 1, /* 標準 PD シミュレーション */
PdSim_MainBut = 2, /* メインボタン PD シミュレーション */
PdSim_TenKey = 3 /* テンキー PD シミュレーション */
} PdSimMode;
typedef struct {
UW rsv1:8; /* 予約(0) */
UW pdsim:2; /* PDシミュレーション(PdSimMode) */
UW nodsp:1; /* ポインタ非表示 */
UW rsv2:3; /* 予約(0) */
UW kbsel:1; /* キーボード選択 */
UW han:1; /* 半角モード */
UW tcmd:1; /* 命令一時シフト */
UW text:1; /* 拡張一時シフト */
UW trsh:1; /* 右シフト一時シフト*/
UW tlsh:1; /* 左シフト一時シフト*/
UW lcmd:1; /* 命令簡易ロック */
UW lext:1; /* 拡張簡易ロック */
UW lrsh:1; /* 右シフト簡易ロック */
UW llsh:1; /* 左シフト簡易ロック */
UW cmd:1; /* 命令シフト */
UW ext:1; /* 拡張シフト */
UW rsh:1; /* 右シフト */
UW lsh:1; /* 左シフト */
UW mode:2; /* キー入力モード(InputMode) */
UW sub:1; /* サブボタン */
UW main:1; /* メインボタン */
} MetaBut;
stat :
cmd, ext, rsh, lsh には、
一時シフト / 簡易ロックの状態も反映される。
すなわち、tcmd または lcmd が 1 のときは、cmd は必ず 1 となる。
nodsp :
han :
kbsel :
xpos :
ypos :
DN_KPMETABUT:
data: MetaBut[2]
現在のメタキーおよびボタン状態を次のように変更する。
新しい状態 = 現在の状態 & MetaBut[0] | MetaBut[1]
その結果、状態が変化したときは、事象通知が発生する。 矛盾した状態が設定された場合の動作は不定。
DN_KEYMAP :
data: KeyMap #define KEYMAX 256 typedef UB KeyMap[KEYMAX/8];現在のキーの状態。
KeyTopOfs を加えた )
キートップコードが同一のキーが同時に複数押された場合のキーマップの状態は不定となる。
DN_KEYTAB :
data: KeyTab
typedef struct {
W keymax; /* 実際の最大キー数 */
W kctmax; /* 実際の変換表の数 */
UH kctsel[KCTSEL]; /* 変換表の番号 */
UH kct[KCTMAX]; /* 変換表本体 */
} KeyTab;
#define KCTSEL 64
#define KCTMAX 4000
KCTMAX は 256 × 64 が理論的な最大値だが、
最大値分のテーブルが必要になることはほとんどないため、
デフォルトとして 4000 とする。
keymax :
KEYMAX )
kctmax :
KCTSEL )
kctsel :
MetaKey の値をインデックスにした配列で対応する変換表の番号
0 〜 (kctmax - 1) が入っている。
MetaKey: CERLKA の 6 ビットの値
即ち、(MetaBut >> 2) & (KCTSEL-1) の値
kct[keymax * kctsel[MetaKey] + keytop]
keytop: キートップコード(0〜KEYMAX)
読み込み/書き込みでは、
実際のキーテーブルのサイズがデータ長となる。DN_KEYTAB
は過去との互換性のために残されている。
今後は DN_KEYDEF を使用すべきである。
DN_KEYTAB は、
DN_KEYID のキーボード ID
に対応するキーボード定義1 のキーテーブルの設定/取得となる。
DN_KEYMODE :
data: KeyMode
typedef struct {
MSEC ontime; /* ON有効時間 */
MSEC offtime; /* OFF有効時間 */
MSEC invtime; /* 無効時間 */
MSEC contime; /* 同時押し間隔 */
MSEC sclktime; /* ショートクリック*/
MSEC dclktime /* ダブルクリック */
Bool tslock; /* 一時シフト仕様 */
} KeyMode;
#define KB_MAXTIME 10000
ontime :
offtime :
invtime :
contime :
sclktime :
dclktime :
KB_MAXTIME
のレンジで補正される。負の値の時は、値は変更しない。
tslock :
True : 一時シフト仕様、False : 通常
sclktime, dclktime は有効であるため、
通常は上位で sclktime は最大値に、
dclktime は 0 に設定する。
DN_PDMODE :
data: PdMode
typedef struct {
MSEC ontime; /* ON有効時間 */
MSEC offtime; /* OFF有効時間*/
MSEC invtime; /* 無効時間 */
MSEC timeout; /* タイムアウト時間*/
PdAttr attr; /* PD属性 */
} PdMode;
typedef struct {
UW rsv1:17; /* 予約(0) */
UW wheel:1; /* ホイール */
UW qpress:1; /* クイックプレス */
UW reverse:1; /* 左右反転 */
UW accel:3; /* 加速度 */
UW absolute:1; /* 絶対/相対 */
UW rate:4; /* スキャン速度 */
UW sense:4; /* 感度 */
} PdAttr;
#define PD_MAXTIME 10000
ontime :
offtime :
invtime :
timeout :
0 〜 PD_MAXTIME
のレンジで補正される。
負の値の時は、値は変更しない。
attr.wheel :
attr.qpress :
attr.reverse :
main と sub を入れ替える。
attr.accel :
0 :加速なし 1〜7 :加速小〜大
attr.absolute :
attr.rate :
attr.sense :
PDの感度 0〜15 ( 0 : 最低 )DN_PDRANGE :
data: PdRange
typedef struct {
H xmax; /* X座標最大値 */
H ymax; /* Y座標最大値 */
} PdRange;
PD位置は、このレンジを超えることはない。DN_PDSIM :
data: W移動速度を 0 〜 15 のレンジで指定する。
0 :PDシミュレーション禁止 1〜15 :移動速度(1:最低)
DN_PDSIMINH :
data: Bool
True の時、PDシミュレーションは一時的に禁止される。False の時、一時的な禁止を解除する。
DN_KEYID :
data: UWデフォルトキーボードのキーボードID の設定 / 取得。
DN_KEYTAB の対象となるデフォルトキーボードを示す。DN_KEYDEF ( kid ) :
DN_KEYDEF2 ( kid ) :
#define DN_KEYDEF(kid) (DN_KEYDEF_S - (kid))
#define DN_KEYDEF2(kid) (DN_KEYDEF2_S - (kid))
data: KeyDef
typedef struct {
W keytopofs; /* オフセット値 */
KeyTab keytab; /* キーテーブル(可変長) */
} KeyDef;
キーボード ID
( kid )のキーボードに対して、
キーテーブルとキートップコードオフセット値を設定する。
または、現在の設定を取得する。keytab.keymax = 0 を設定することで、
そのキーボードID のキーボード定義が削除される。
キーボード ID (0x00 〜 0x7f) #define KID_unknown 0x00 /* 未定義キーボード */ #define KID_TRON_JP 0x01 /* TRON 日本語キーボード */ #define KID_IBM_EG 0x40 /* IBM 101 (系) 英語キーボード */ #define KID_IBM_JP 0x41 /* IBM 106 (系) 日本語キーボード */
なし
以下の KeyEvt、または PdEvt を事象通知する。
typedef struct {
DevEvtKind kind; /* 事象種別 */
UH keytop; /* キートップコード */
UH code; /* 文字コード */
MetaBut stat; /* メタキー状態 */
} KeyEvt;
kind: DE_KEYDOWN キーダウン
DE_KEYUP キーアップ
DE_KEYMETA メタキー状態の変化
DE_KEYDOWN, DE_KEYUP は、
メタキーおよび、未使用キー ( キーコード = 0 ) を除く、
すべてのキーに対して、
それぞれ押した時、
離した時に事象通知される。
DE_KEYMETA
は以下のいずれかのメタキー状態が変化した時に事象通知される。
tcmd 〜 tlsh | 一時シフト状態 |
lcmd 〜llsh | 簡易ロック状態 |
cmd 〜lsh | シフト状態 |
mode | キー入力モード |
han | 半角モード |
kbsel | キーボード選択 |
keytop :
KeyTopOfs を加えた値DE_KEYMETA の時は無効 ( 0 )
code :
DE_KEYMETA の時は無効 ( 0 )
typedef struct {
DevEvtKind kind; /* 事象種別 */
KPStat stat; /* PD位置/ボタン状態 */
} PdEvt;
kind: DE_PDBUT PDボタン変化および位置移動
DE_PDMOVE PD位置移動
DE_PDSTATE PDの状態変化
PD のいずれかのボタンが押された場合、離された場合、 および、PD 位置が移動した場合に事象通知される。
| ボタン状態変化 | 位置移動 | PdEvt.kind |
|---|---|---|
| なし | なし | --- |
| なし | あり | DE_PDMOVE |
| あり | なし | DE_PDBUT |
| あり | あり | DE_PDBUT ( DE_PDMOVE は通知しない ) |
DE_PDSTATE は以下の状態が変化したときに事象通知される。
pdsim PD シミュレーションモード
typedef struct {
DevEvtKind kind; /* 事象種別 */
H wheel; /* ホイール回転量 */
H rsv[3]; /* 予約(0) */
} PdEvt2;
kind :
DE_PDEXT PD 拡張事象
ホイールを回転したときに事象通知される。
wheel: > 0 ホイールを手前に回転
< 0 ホイールを奥に回転
実IOドライバは以下のいずれかのメッセージを入力メイルボックスに送信する。
typedef enum {
INP_PD = 0, /* PDデータ */
INP_KEY = 1, /* キーデータ */
INP_FLG = 2, /* イベントフラグ登録 */
INP_PD2 = 3 /* PDデータ 2 */
/* 負数は特殊用途用に予約 */
} InputCmd;
/* デバイスエラー */
typedef enum {
DEV_OK = 0, /* 正常 */
DEV_OVRRUN = 1, /* 受信オーバーラン */
DEV_FAIL = 2, /* ハードウエア故障 */
DEV_SYSERR = 3 /* 実IOドライバ障害 */
} DevError;
INP_PD : PD入力の送信
typedef struct {
UW read:1; /* 読み込み済みフラグ */
InputCmd cmd:7; /* =INP_PD */
UW rsv1:4; /* 予約(0) */
DevError err:4; /* デバイスエラー */
UW nodsp:1; /* ポインタを表示しない */
UW rsv2:1; /* 予約(0) */
UW onebut:1; /* 1ボタン動作 */
UW abs:1; /* 座標値は絶対/相対 */
UW norel:1; /* 相対動作不可 */
UW tmout:1; /* PDタイムアウト有効 */
UW butrev:1; /* ボタン左右反転有効 */
UW xyrev:1; /* XY座標値反転有効 */
UW rsv3:3; /* 予約(0) */
UW qpress:1; /* クイックプレス修飾 */
UW inv:1; /* 有効領域外(座標値は不正) */
UW vst:1; /* 有効領域外から内に移動した */
UW sub:1; /* サブボタン状態 */
UW main:1; /* メインボタン状態 */
} PdInStat;
nodsp :
MetaBut に反映される ( タッチパネル入力で 1 にセットされる )。
norel :
abs = 1 の時有効で、PD属性が相対動作となっていても絶対動作を行う。)tmout :
butrev :
xyrev :
abs = 0 の時のみ有効。
qpress:
qpress はメインボタンに対する修飾で、
シフトキーの様な扱いとなる。通常、電子ペンでは2つ目のサイドボタン、
マウスでは中ボタンの状態を示す。
onebut:
qpress を1ボタン動作とする。inv :
vst :
typedef struct {
T_MSG head;
PdInStat stat;
H xpos; /* X 座標位置 ( 相対 / 絶対) */
H ypos; /* Y 座標位置 ( 相対 / 絶対) */
} PdInput;
xpos :
ypos :
(0,0)-(PDIN_XMAX-1, PDIN_YMAX-1)
の固定レンジの値となる。
相対座標の時の値は、座標値の変化分 ( ± ) となる。
#define PDIN_XMAX 4096 #define PDIN_YMAX 3072この座標レンジは、機種により異なる。
read = 1 にセットする。
typedef struct {
UW read:1; /* 読み込み済みフラグ */
InputCmd cmd:7; /* =INP_PD2 */
UW rsv1:4; /* 予約(0) */
DevError err:4; /* デバイスエラー */
UW rsv2:16; /* 予約(0) */
} PdIn2Stat;
typedef struct {
T_MSG head;
PdIn2Stat stat;
H wheel; /* ホイール回転量 */
H rsv; /* 予約(0) */
} PdInput2;
ホイールを回転させたときに送信される。
KBPD ドライバは読み込んだ後、read = 1にセットする。
wheel > 0 ホイールを手前に回転 wheel < 0 ホイールを奥に回転INP_KEY: キー入力の送信
typedef struct {
UW read:1; /* 読み込み済みフラグ */
InputCmd cmd:7; /* =INP_KEY */
UW rsv1:4; /* 予約(0) */
DevError err:4; /* デバイスエラー */
UW rsv2:8; /* 予約(0) */
UW kbid:7; /* キーボード ID */
UW press:1; /* ON:1、OFF:0 */
} KeyInStat;
typedef struct {
T_MSG head;
KeyInStat stat;
W keytop; /* キートップコード */
} KeyInput;
キーを押した/離した時に送信される。
KBPDドライバは読み込んだ後、read = 1 にセットする。
typedef struct {
UW read:1; /* 読み込み済みフラグ */
InputCmd cmd:7; /* =INP_FLG */
UW rsv1:4; /* 予約(0) */
DevError err:4; /* 常に DEV_OK */
UW rsv:7; /* 予約(0) */
UW kb:1; /* kbid が有効のとき1 */
UW kbid:7; /* キーボード ID */
UW reg:1; /* 登録:1、登録削除:0 */
} FlgInStat;
typedef struct {
T_MSG head;
FlgInStat stat;
ID flgid; /* イベントフラグID */
} FlgInput;
実 IO ドライバの初期化時に、
コマンド受け付けが必要な場合に登録される。
コマンド受け付けが不要な場合は登録しない。
イベントフラグは最大 4 つまで登録可能でそれ以上は無視される。
実 IO ドライバの終了時に登録削除する。
KBPD ドライバは、登録されたイベントフラグすべてに対して必要に応じたコマンドを送信する。
KBPD ドライバは読み込んだ後、read = 1 にセットする。
コマンドの受け渡しは、以下のような手順で行う。
/* コマンド設定READY待ち */ wai_flg(&dmy, flg_id, 0x80000000, TWF_ORW | TWF_CLR); /* コマンド設定 : cmd < 0x80000000 */ set_flg(flg_id, cmd);
for (;;) {
/* コマンド入力READY */
set_flg(flg_id, 0x80000000);
/* コマンド待ち */
wai_flg(&cmd, flg_id, 0x7fffffff, TWF_ORW | TWF_CLR);
<コマンド処理>
}
KBPD ドライバは、実 IO ドライバによって登録されたすべてのイベントフラグに対して以下のコマンドを送信する。
#define ScanRateCmd(rate) (0x01000000 | (rate))
rate = PDのスキャン速度。0〜15 (0:最低)
#define SenseCmd(sense) (0x02000000 | (sense))
sense = PDの感度。0〜15 (0:最低)
| PD_ABS 絶対動作指定
| PD_ACMSK 加速度マスク
#define PD_ABS 0x0100
絶対動作指定のとき、絶対動作が可能な PD のときは、
絶対座標で INP_PD のデータを送信しなくてはいけない。
絶対動作指定でないとき、相対動作が可能な PD のときは、
相対座標で INP_PD のデータを送信しなくてはいけない。
#define PD_ACMSK 0x0e00
ポインタ移動加速度の設定 (相対座標動作時のみ有効)
0 加速なし 1〜7 加速小〜大
#define InputModeCmd(mode) (0x03000000 | (mode))
mode : InputMode の値
(HiraMode, AlphaMode, KataMode, CapsMode)
SuspendKBPD)、
およびサスペンド状態からの復帰 ( ResumeKBPD) を行うコマンド。ResumeKBPD 以外のコマンドを受け付ける必要はない
( 無視してよい )。また、KB および PD からのデータを送信しない。
#define SuspendKBPD (0x10000000) #define ResumeKBPD (0x10000001)KBPD ドライバは、サスペンドへの移行時に、 すべてのキー及びボタンをアップし、 押されたままの状態にならないようにする。
| ── | 実際のキー / ボタンの状態 |
| ━━ | 処理されたキー / ボタンの状態 |
ontime :
ontime 以上ONの状態が続いた場合にONと判断する。

ontimeofftime :
offtime 以上 OFF の状態が続いた場合に OFF と判断する。
offtimeinvtime :
invtime 以内の ON は無視する。
invtimecontime :
contime 以内の時は、メタキーの修飾を有効にする。
timeout :
timeout 時間たっても PD
からの入力が何もない場合タイムアウトとみなして OFF したと判断し、
OFFの事象を自動的に発生する。sclktime :
sclktime 以内にクリックした場合、一時シフト状態になる。

dclktime 以内にダブルクリックした場合に簡易ロック状態になる。

dclktimetslock :
sclktime は十分大きな値,
dclktime は 0 に設定される。

tslock「左シフト」+「右シフト」+「 CC キー ( ←→↑↓のいずれか )」で、 標準 PD シミュレーションモードと通常モード ( PD シミュレーション・オフ)を交互に切り換える。
標準 PD シミュレーションモードでは、 ポインタの中に (↑) が表示される。
標準 PD シミュレーションモードでは、 以下のキー操作により、PD動作を行う。
「左シフト」 + 「右シフト」 + 「HOME、End、PgUp、PgDnのいずれか / サブ CC キー(←→↑↓のいずれか)」で、 メインボタン PD シミュレーションモードと通常モードを交互に切り換える。
メインボタン PD シミュレーションモードでは、 ポインタの中に ( ▲ ) が表示される。
メインボタン PD シミュレーションモードでは、 以下のキー操作により、PD 動作を行う。
「左シフト」+「右シフト」+「テンキー内の→ ← ↑ ↓のいずれか」で、 テンキー PD シミュレーションモードと通常モードを交互に切り換える。
NumLock] の消灯、点灯を問わない
テンキー PD シミュレーションモードでは、ポインタの中に(↑)が表示される。
テンキー PD シミュレーションモードでは:
3 種の PD シミュレーションモードから通常状態への移行は、それぞれ、以下のいずれのキー操作でも可能とする。
言い替えれば、現在の PD シミュレーションモードに移行させたキー操作以外に、 他の 2 種のキー操作でも通常状態の戻れる、ということである。
以下に KBPD ドライバで使用する特殊キーコードを示す。 このコードは、キーコード変換テーブルで変換したコードである。
#define KC_EIJI 0x1000 /* 英語←→日本語切換 */ #define KC_CAPN 0x1001 /* ひら←→カタ切換 */ #define KC_SHT_R 0x1002 /* 右シフト */ #define KC_SHT_L 0x1003 /* 左シフト */ #define KC_EXP 0x1004 /* 拡張 */ #define KC_CMD 0x1005 /* 命令 */ #define KC_JPN0 0x1006 /* 日本語ひら */ #define KC_JPN1 0x1007 /* 日本語カタ */ #define KC_ENG0 0x1008 /* 英語 */ #define KC_ENG1 0x1009 /* 英語CAPS */ #define KC_KBSEL 0x100a /* かな←→ローマ字 */ #define KC_HAN 0x1150 /* 全角←→半角切替 */ #define KC_JPN0_Z 0x1016 /* 日本語ひら & 全角 */ #define KC_JPN1_Z 0x1017 /* 日本語カタ & 全角 */ #define KC_ENG0_H 0x1018 /* 英語 & 半角 */ #define KC_ENG1_H 0x1019 /* 英語CAPS & 半角 */
#define KC_CNV 0x001e /* 変換 */ #define KC_RCNV 0x001f /* 逆変換 */ #define KC_HOME 0x1245 /* Home */ #define KC_PGUP 0x1246 /* PageUp */ #define KC_PGDN 0x1247 /* PageDown */ #define KC_END 0x125e /* End */ #define KC_CC_U 0x0100 /* メインCCキー ↑ */ #define KC_CC_D 0x0101 /* メインCCキー ↓ */ #define KC_CC_R 0x0102 /* メインCCキー → */ #define KC_CC_L 0x0103 /* メインCCキー ← */ #define KC_SC_U 0x0104 /* サブCCキー ↑ */ #define KC_SC_D 0x0105 /* サブCCキー ↓ */ #define KC_SC_R 0x0106 /* サブCCキー → */ #define KC_SC_L 0x0107 /* サブCCキー ← */
デバイスドライバ共通仕様を参照。
KBPD ドライバ固有の特殊なエラーコードはない。