忍者ブログ

素人翻訳

適当に翻訳する。

X11におけるGraphics Context

 X11 のグラフィクス・コンテクストは、
・X10 の反省から生まれた。
・描画関数が受け取る引数の中のあるものを纏めたもの。

=====

参考論文
「The X Window System Version 11」
James Gettys、Philip L. Karlton、Scott McGregor
CRL 90/08(6頁、26〜29頁、33〜36頁など)

=====

Graphics Context の狙い

 X11 から GC(Graphics Context)の利用が始まった。X10(X バージョン 10)では使われていなかった。X10 では、描画関数を呼び出す度に、必要な情報すべてを引数で渡していた。VAXstation 100 に倣った「state-free」な描画手続きである。このやり方のまま X10 にない描画機能を追加していくと、描画関数の引数が増えすぎる。Xクライアント・Xサーバ間の通信量や、関数インタフェイスの複雑化が問題。

 GC を用いた「state-based」な描画手続きだと、
(1)描画リクエストで使う資源の初期化(リソースIDの割当て等)の手間・通信量が減る。
(2)描画リクエストの引数の数が減ることによって、リクエストそのものが小さくなり、Xクライアント・Xサーバ間の通信量が減る。
(3)描画リクエストの関数定義は、引数の数が減ってスッキリする。

 XクライアントとXサーバとの接続を表す情報塊の中にウィンドウと描画文脈の情報を含めるかどうか、あるいは「ウィンドウ」を表す構造体の中にグラフィックス・コンテキストを含めるかどうか、検討された。こうしたやり方だと、GCを用いる現在のやり方よりも描画処理のオーバーヘッド(通信量)が一層減るものの、マルチ・スレッド環境への対応が大変で、「ウィンドウ」構造体が大きくなりすぎる。そこで、X11では描画リクエストの度に「ウィンドウ」と「グラフィクス・コンテクスト」を指定することになった。

GC の効果

 GC の採用によって、Xlib の描画手続きは一部の引数をプロトコル・リクエストから取得し、残りの引数を同リクエストで指定した GC から取得するようになった。毎度毎度同じ値が指定されるような引数は GC の一部として記録されるようになったので、描画リクエストのサイズが小さくなった。

 どの引数を GC に入れ、どの引数を入れないのか、決めるのが大変だった。頻繁に値の変更される引数を Graphics Context に入れてしまうと、GC の内容を変更するリクエストと実際の描画リクエストの二つを描画の度に送信しなければいけなくなる。最終的に現在の23個をGCに入れることにした。Xlib.h の構造体「XGCValues」の通り。フォントなども GC に含めることになった。頻繁にフォントを替える場合には、複数の GC を用意して、描画の度に指定する GC を替えるようにすれば、GCの内容を変更するリクエストを何度も送らなくて済むと考えられた。

 GC がなければ、

XFillRectangle(display, drawable, gc, x, y, width, height);

は次のようになっていた。

XFillRectangle(display, drawable, x, y, width, height, function, planemask, foreground, background, tile_or_stipple, ts_x_origin, ts_y_origin, clip_x_origin, clip_y_origin, clipmask);

問合せ不可

 X11プロトコルでは、アプリケーションはGC等の内容をサーバに問い合わせることができない。一度でもアプリケーションの手元にあった情報は、アプリケーションが自力で記憶しておくものと決めた。

 関数 XGetGCValues は、Xlib が記憶している GC のキャッシュを調べて、その値を返す。X サーバには問い合わせない。

PR

X11、INCR プロパティを用いたセレクション・データの転送

 X11には、クライアント間通信の仕組みとして、セレクション機構が用意されている。

 セレクション機構を使ってクライアント間でデータを転送する時、転送するデータが大き過ぎるなら、分割して転送する。これは Incremental 転送と呼ばれる。INCR という型のプロパティを用いる。

 INCR プロパティを用いたセレクション・データの転送は、以下の手順で行う(図の後に説明がある)。

(1)要求者→Xサーバ[XConvertSelection]
  セレクションを要求するクライアント(要求者)が関数 XConvertSelection を呼び出す。これによって、セレクション・データが欲しいことを X サーバに伝える。(要求者が XSelectInput を使って SelectionNotify イベントの配信を依頼する必要はない。)
(2)Xサーバ→所有者[SelectionRequest]
  X サーバは、セレクション・データの要求があったことをセレクションの所有者に伝える為に SelectionRequest イベントを発行する。
(3)所有者→Xサーバ[XChangeProperty]
  セレクションの所有者は、通常、関数 XChangeProperty を用いて、指定されたウィンドウの指定されたプロパティに指定された型でセレクション・データを格納する。しかし、セレクションの中身のデータ量が一度に転送できる分量より多い場合、先ずセレクション・データの大きさを伝えるために、関数 XChangeProperty を用いて、指定されたウィンドウの指定されたプロパティに INCR 型で(int整数で)セレクション・データの大きさを格納する。
(4)所有者→Xサーバ[XSelectInput]
  同時にセレクションの所有者は XSelectInput を用いて、X サーバに PropertyNotify イベントの配信を依頼する。
(5)所有者→Xサーバ[XSendEvent]
  さらに、セレクションの所有者は、どこのウィンドウの何というプロパティに INCR 型のデータを格納したのかを XSelectionEvent 構造体に記述し、これを要求者へ届けるよう XSendEvent で X サーバに依頼する。
(6)Xサーバ→要求者[SelectionNotify]
  X サーバは、XSendEvent を受けて、SelectionNotify イベントを要求者に転送する。
(7)要求者→Xサーバ[XSelectInput]
  セレクションの要求者は、受け取った SelectionNotify イベントを見て、指定したプロパティに格納されているのが INCR 型の整数値であることを知る。そして、Incremental 転送(分割転送)を開始するべく、PropertyChangeMask を指定して XSelectInput を呼び出す。
(8)要求者→Xサーバ[XDeleteProperty]
  セレクションの要求者は次いで、XDeleteProperty を呼び出し、INCR 型データの入ったプロパティを削除するよう X サーバに依頼する。
(9)Xサーバ→所有者→Xサーバ[PropertyNotify、XChangeProperty]
  「state」に PropertyDelete が入った PropertyNotify イベントを初めて受け取った所有者は、引数 mode に PropModeReplace を指定して関数 XChangeProperty を呼び出し、最初の SelectionRequest で指定されたウィンドウ、プロパティ、型に従ってセレクション・データの一部を書き込む。
---以下繰り返し---
(10)Xサーバ→要求者→Xサーバ→要求者[PropertyNotify、XGetWindowProperty]
  「state」に PropertyNewValue が入った PropertyNotify イベントを受け取った要求者は、引数 delete に True を指定して関数 XGetWindowProperty を呼び出し、新たに書き込まれたデータを読み込む。この時、取得したデータの長さが 0 であれば、前回の転送でセレクション・データを全て取得し終えたということなので、この繰り返しから抜ける。
(11)Xサーバ→所有者→Xサーバ[PropertyNotify、XChangeProperty]
  「state」に PropertyDelete が入った PropertyNotify イベントを受け取った所有者は、引数 mode に PropModeAppend を指定して関数 XChangeProperty を呼び出し、データの続きの一部を上と同じプロパティに書き込む。但し、前回の転送で全データの引き渡しが済んでいた場合、同プロパティには長さ 0 のデータ(NULL)を書き込む。
---繰り返しここまで---
(12)要求者→Xサーバ[XDeleteProperty]
  長さ 0 のデータを受け取った要求者は、関数 XDeleteProperty を呼び出し、使用したプロパティを削除する。
(13)終わり。

 xsel-1.2.0 では、所有者は全データの転送完了後に property 部が None の XSelectionEvent 構造体を使用して SelectionNotify を送信している。多分、送信しなくても良い。分割転送が途中で失敗した場合は、SelectionNotify で通知する。

★★★

 INCR Property、Selection Mechanism、Incremental Transfer、セレクション・メカニズム、順次転送、分割転送

カレンダー

12 2025/01 02
S M T W T F S
1 2 4
5 6 7 8 9 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

最新コメント

[09/07 NONAME]
[08/18 NONAME]
[05/18 NONAME]
[04/09 NONAME]
[03/21 NONAME]

最新記事

(01/10)
(01/03)
(12/20)
(12/08)
(11/20)
(10/30)
(10/24)
(09/20)
(09/16)
(09/11)
(09/03)
(09/02)
(08/27)
(08/17)
(07/31)
(07/30)
(07/19)
(07/13)
(05/02)
(03/17)
(11/01)
(07/20)
(05/17)
(04/20)
(03/10)

ブログ内検索

広告

バーコード

広告