Mercator(メルカトル)が機能するためには、接続対象のアプリケーションの状態をメルカトルから看視できなければならないし、同時に、メルカトルから同アプリケーションを操作できなければならない。
外部のプロセスからアプリケーションを操作するのは実に簡単である。X サーバの XTEST 拡張を使えば、人間が生み出したものと変わらないイベント・ストリーム(打鍵、マウス・ボタンのクリック)を外部プロセスから発生させることができる。したがって、スクリーン・リーダ(screenreader)は XTEST を用いて、マウスとキーボードによるアプリケーションへの入力をプログラム的に模造することができる。
一方、アプリケーションの状態の看視は、それより難しい。スクリーン・リーダからアプリケーションのインタフェイスの構成が把握できなければならないし、また、アプリケーションの状態変更がスクリーン・リーダ側に一方的に(asynchronously非同期的に)通知されなければならない。
X アプリケーションの看視を可能にするため、X ウィンドウ・システムへの追加機能が四つ提案されている。最初に取り上げる二つは、X11R6 の X ウィンドウ・システムで既に採用・実装してある。後に取り上げる二つは、X11R6.1 で採用するよう提案中である。
- Hooks Object(フック・オブジェクト)
- Before Flush Hook()
- Remote Access Protocol(リモート・アクセス・プロトコル)
- External Agent Rendezvous Mechanism(外部エージェントのランデヴ機構)
これらを以下で説明する。
Xt Intrinsics 層に修正があり、X11R6 から新たなオブジェクトが追加された(Xt Intrinsics 層は、アプリケーション開発のためのウィジェット・モデルを提供するソフトウェア・ライブラリであり、同ウィジェット・モデルは Motif、Athena を始めとした他のツールキットでも使われている)。このオブジェクトのことをフック・オブジェクト(Hooks Object)という。同オブジェクトには「フック(hooks)」と呼ばれる手続きが入っており、これはアプリケーションの状態が変更する度に呼び出される。
フック・オブジェクトが保持するフックは五つある。
- Create フック
- Change フック
- Destroy フック
- Configure フック
- Geometry フック
Xt Intrinsics ライブラリに追加の実装があり、アプリケーションの状態を変える Xt 関数(リソース値の変更、ウィジェットの作成・破壊など)の呼出しを受けて、フック・オブジェクト内の適切なフック手続きを呼び出すようになった。
Create フックは、ウィジェットを作成した時に呼び出される。
Change フックは、リソースの値を変更した時に呼び出される。
Destroy フックは、ウィジェットを破壊した時に呼び出される。
Configure フックは、ウィジェットの「configuration」(位置形状)が変わる度に呼び出される。configuretion は、位置、大きさ、表示状態(map state)、管理状態(manage state)から成る。
Geometry フックは、Constraint 型ウィジェットとその子供との間で行われるジオメトリ交渉の過程において、その開始時点と終了時点に一回づつ呼び出される。
フック・オブジェクトの導入それ自体によって、Xt 系のアプリケーションへの接続が可能になる訳ではない。ただ、接続機能の設営に使えるインフラストラクチャが用意されただけである。狙いは、呼び出された時に外部エージェントへ通知を出してくれるようなフック手続き一式を実装することである。この手続きと、そこから生まれるメッセージとは、Remote Access Protocol(後述)で定義しており、X11R6.1 で採用されるよう X 協会に提案中である。
アプリケーションのインタフェイスの利用者から見える部品は Xt によって提供されているものの、文字列の描画と画像の描画では依然として低水準の Xlib ライブラリが呼び出されている。スクリーン・リーダは、アプリケーションのインタフェイスの実物と自身が提示する同インタフェイスの「見た目(view)」とを確実に合わせるために、Xlib から生じる X プロトコルの情報を取得できなければならない。
X11R6 の時点で、X 協会は Xlib のクライアント側拡張を正式に採用し、実装している。この拡張の中身は「BeforeFlushHook」である。このフックは「slot」であり、ここに処理手続きをインストールすることができる。BeforeFlushHook にインストールした手続きは、クライアントの X リクエスト用バッファを放流する(is flushed)直前、Xlib によって自動的に呼び出される(名前はここから)。
目標は、擬似サーバのような煩わしい技術無しに、外部エージェントが低水準の X プロトコルの情報を全て取得できるようにすることである。フック・オブジェクトと同じく、BeforeFlushHook もまた、インフラストラクチャを用意するだけである。BeforeFlushHook へ実際にどんな手続きがインストールされるのか、あるいは同手続きは何をするのかは、R6 では定義していない。
Remote Access Protocol(通称 RAP)は、クライアントとスクリーンリーダ・アプリケーションとの間で行われる通信のための共通言語を定義する。同プロトコルは多くの「requests(要求)」から成る。スクリーン・リーダ(RAP の用語ではエージェント(agent))は、これをクライアント・アプリケーションに送信することができる。リクエストを用いて、アプリケーションの構造に関する情報やリソースの値などを取り出す。何れのリクエストにもクライアントからの「replies(返答)」があり、その返答の中に要求した値が格納されている。
加えて、クライアントは、自身のフック・オブジェクト・コールバックの何れかが呼び出される度に、非同期的に(返答を必要とせず一方的に)「notification(通知)」メッセージを生成する。この通知によって、スクリーン・リーダは問い合せる(poll)ことなくアプリケーションの状態変更を認識できるようになる。
このプロトコルとその実装たる手続き群は現在策定中であり、同時に、 X11R6.1 で標準として採用するように X 協会に提案中である。
RAP の詳細は「Remote Access Protocol Description」の節を見てほしい。(訳註:別の文書の?)
RAP プロトコルそのものの策定に加えて、スクリーン・リーダがクライアントとの接続を開設する際の標準作法と、クライアントが接続要求を待ち受ける仕組みとを用意しなければならない。後者の仕組みにおいては、アプリケーションにコードの修正を要求してはいけない。
Xtea (Xt External Agent の略)という当座の名前で呼ばれている手続きを幾つか定義した。この手続きによって通信が可能となる。同手続きは、X11R6.1 にて採用するよう X 協会に提案済みである。X 協会の実装でそのライブラリがどこに配置されるのか、正確な場所は不明のままの提案ではあるが。
ランデヴ機構の基本動作を以下に述べる。クライアントは、「プロトコル名」から「プロトコル初期化関数」を割り出す対応表を保持している。名前・初期化子の対を対応表にインストールしたり、同表から削除したりする手続きを用意する。対応表とこれを操作する手続き群は、協会標準に採用されれば、おそらく Xt か Xmu ライブラリに取り込まれる。
クライアント・メッセージ・イベント・ハンドラもまた、協会実装の VendorShell ウィジェット・クラスにインストールされる。このイベント・ハンドラは、クライアント・メッセージが届く度に呼び出される。同イベント・ハンドラは、イベントが外部エージェントから来たことを示す「magic token」があるか否か、イベントの中を調べる。トークンが見つからなかった場合、イベントを廃棄する。見つかった場合、同ハンドラはイベントの中を調べて、インストールするプロトコルの名前を探し出す。名前・初期化子の対応表で名前を検索し、一致するものがあれば、そのプロトコルの初期化子を呼び出す。
RAP プロトコルの初期化子は、クライアント側からエージェント(スクリーンリーダ)への接続を確立する。この際、クライアント・メッセージ・イベントで運ばれて来た情報「return address」を利用する。一度接続が確立すると、スクリーン・リーダとクライアントは RAP プロトコルによって通信できるようになる。
ランデヴ関連で為すべきは、VendorShell に簡単な手直しを加えること(クライアント・メッセージ・イベント・ハンドラを内部に追加)、及び、幾つかの定型処理を Xmu もしくは Xt に追加して、RAP プロトコル始動に用いるプロトコル名・初期化子の対応表を管理できるようにすることである。
このランデヴ機構が汎用なものであり、RAP 以外のプロトコルでも利用できることに注目してほしい。
上記の四つの部品によって、スクリーン・リーダは X ウィンドウ・システムに接続できるようになる。これらの機構を通じて、スクリーン・リーダはアプリケーション・インタフェイスの状態を看視できる。さらに、スクリーン・リーダのプロトコルへの参加は、アプリケーションの開発者から見て透明である(transparent透過的)。アプリケーションの開発者は、アプリケーションが RAP に参加しているか、あるいは、スクリーン・リーダと協同しているかを意識する必要がない。