ユーザプログラムでは、単純に open(2) 呼び出しでマウスデバイスをオープンし、 read(2) でデバイスからマウスのデータを読み取ります。 動きとボタン状態は通常、固定長のデータパケットにエンコードされます。 マウスデバイスによっては、可変長のパケットでデータを送るかもしれません。 それぞれのドライバが実際に用いるプロトコル (データ形式) は大きく異なります。
マウスドライバは ``非ブロッキング'' 属性を持つことができます。 その場合、マウスデータが取得できなければドライバはすぐに戻ります。
マウスデバイスドライバは大抵いくつかのレベルの操作を提供します。 現在の操作レベルは ioctl(2) コマンドで調査、変更することができます。 レベル 0 が最も低いレベルであり、 このときドライバはユーザプログラムに基本的なサービスを提供します。 このレベルでは、ほとんどのドライバがマウスの水平移動と垂直移動、 および 3 つまでのボタンの状態を提供します。 レベル 1 では、ドライバがサポートしている場合、 マウスデータは標準的な形式の MOUSE_PROTO_SYSMOUSE にエンコードされます。 その形式は次の通りです:
この形式の最初の 5 バイトは MouseSystems 形式と互換になっています。 残りの 3 バイトは、最上位ビットが常に 0 にセットされています。 そのため、ユーザプログラムが MouseSystems データ形式を解釈できて、 ビットパターン 10000xxxb を検出することで このデータ形式の 1 バイト目を見つけ出そうとしている場合、 追加分のバイトを棄てることによって、 x, y および 3 つのボタンの状態を正しくデコードできます。
デバイスドライバが 2 以上の操作レベルを提供することもあります。 詳しくは個々のドライバのマニュアルページを参照してください。
typedef struct mousehw {
int buttons; /* ボタン数 */
int iftype; /* I/F の型 */
int type; /* マウス/トラックボール/トラックパッド... */
int model; /* I/F 依存のモデル ID */
int hwid; /* I/F 依存のハードウェア ID */
} mousehw_t;
buttons フィールドはドライバが検出したボタン数を保持します。 ドライバが正確な数を検出できなければ、 2 などの適当な値がこのフィールドに代入されることもあります。
iftype はインタフェースの型で、 MOUSE_IF_SERIAL MOUSE_IF_BUS MOUSE_IF_INPORT MOUSE_IF_PS2 MOUSE_IF_SYSMOUSE MOUSE_IF_UNKNOWN のいずれかです。
type はデバイスの型を示し、 MOUSE_MOUSE MOUSE_TRACKBALL MOUSE_STICK MOUSE_PAD MOUSE_UNKNOWN のいずれかです。
model は MOUSE_MODEL_GENERIC か、あるいは定数 MOUSE_MODEL_XXX のうちの 1 つです。
hwid はそのポインティングデバイスが返す ID 値です。 これはインタフェースの型に依ります。 取りうる値については特定のマウスドライバのマニュアルページを参照してください。
typedef struct mousemode {
int protocol; /* MOUSE_PROTO_XXX */
int rate; /* 報告頻度 (秒単位) */
int resolution; /* MOUSE_RES_XXX、不明なら -1 */
int accelfactor; /* アクセラレーションの要素 */
int level; /* ドライバの操作レベル */
int packetsize; /* データパケットの長さ */
unsigned char syncmask[2]; /* 同期ビット */
} mousemode_t;
protocol フィールドは、ユーザプログラムがマウスデータを読み取る際に、 デバイスの状態が返される形式を示します。 これは定数 MOUSE_PROTO_XXX のうちのひとつです。
rate フィールドは状態報告の頻度 (回/秒) であり、 デバイスはこの頻度でホストコンピュータに移動報告を送ります。 不明かまたは適用できなければ -1 です。
resolution フィールドはポインティングデバイスの解像度を示す値を保持します。 正の値か、定数 MOUSE_RES_XXX のうちの 1 つです。
accelfactor フィールドは、アクセラレーション機能を制御するための値を保持します。 この値は 0 以上でなければなりません。 0 であればアクセラレーション機能は無効です。
packetsize フィールドは、固定サイズのデータパケットの長さ または可変長パケットの固定部の長さを示します。 このサイズは、インタフェースの型、デバイスの型やモデル、 ドライバのプロトコルや操作レベルに依存します。
配列 syncmask は、データパケットの 1 バイト目を検出するための ビットマスクとビットパターンを保持します。 syncmask[0] はビットマスクで、データのバイトとの積 (AND) を取るためのものです。 その結果が syncmask[1] に等しければ、おそらくそのバイトはデータパケットの 1 バイト目でしょう。 但しこの 1 バイト目の検出法は 100% 信頼性があるとは言えません。 ですので、単に補助的な手段だととらえてください。
あるフィールドの現在の設定を変更したくないときは、 そのフィールドに -1 を入れてください。 また resolution と rate には 0 を入れることもできます。 そうすると、そのフィールドのデフォルト値が選択されます。
typedef struct mousedata {
int len; /* バッファ内のデータ数 */
int buf[16]; /* データ用バッファ */
} mousedata_t;
呼び出し元プロセスは、 バッファに読み込まれるバイト数を len フィールドに入れておかなくてはなりません。 本コマンドはすべてのドライバがサポートしているとは限りません。
typedef struct mousestatus {
int flags; /* 状態変更フラグ */
int button; /* ボタン状態 */
int obutton; /* 以前のボタン状態 */
int dx; /* x 方向の移動 */
int dy; /* y 方向の移動 */
int dz; /* z 方向の移動 */
} mousestatus_t;
button フィールドと obutton フィールドは、マウスボタンの現在の状態と以前の状態を保持します。 ボタンが押されたとき、対応するビットがセットされます。 マウスドライバは 0 から 31 までのビットを使って 31 個までのボタンをサポートできます。 いくつかのボタンビットが MOUSE_BUTTON1DOWN から MOUSE_BUTTON8DOWN として定義されています。 最初の 3 つのボタンは、左ボタン、中ボタン、右ボタンに対応します。
前回の MOUSE_GETSTATE 呼び出しからボタンの状態が変わっていれば、 flags フィールドの対応するビットがセットされます。 前回の呼び出しからマウスが移動していれば、 flags フィールド中の MOUSE_POSCHANGED ビットもセットされます。
その他のフィールドは、 前回の MOUSE_GETSTATE 呼び出しからの移動量を保持します。 本コマンドが呼び出された後に、毎回内部カウンタがリセットされます。