入り口に戻る

原文はこちら。

翻訳にあたって、オープンソースグループ・ジャパンの MIT ライセンスの訳を参考にした。

# X Synchronization Extension Library(日本語訳)

## X Consortium Standard

### Tim Glauert

Olivetti Research
MultiWorks

### Dave Carver

Digital Equipment Corporation
MIT/Project Athena

### Jim Gettys

Digital Equipment Corporation
Cambridge Research Laboratory

### David P. Wiggins

X Consortium, Inc.

X Version 11, Release 7.7

Version 3.0

Copyright © 1991 Olivetti Research Limited, Cambridge England, Digital Equipment Corporation, Maynard, Massachusetts

Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies. Olivetti, Digital, MIT, and the X Consortium make no representations about the suitability for any purpose of the information in this document. This documentation is provided as is without express or implied warranty.

(訳)

(本文書を使用、複製、変更、および頒布することは、目的を問わず無償で許可する。但し、上記の著作権表示を文書のすべての複製に記載するものとする。Olivetti、Digital、MIT、及び X Consortium は、本文書に含まれる情報のいかなる目的への適切性についても、何ら表明を行わない。本文書は明示または暗黙の保証なしに提供される。)

Copyright © 1991 X Consortium, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.

X Window System is a trademark of The OpenGroup.

(訳)

(本ソフトウェアおよび関連する文書のファイル（以下「ソフトウェア」）の複製を取得した全ての人物に対し、以下の条件に従うことを前提に、ソフトウェアを無制限に扱うことを無償で許可する。これには、ソフトウェアの複製を使用、複製、改変、結合、公開、頒布、再許諾、および/または販売する権利、およびソフトウェアを提供する人物に同様の行為を許可する権利が含まれるが、これらに限定されない。)

(上記の著作権表示および本許諾表示を、ソフトウェアの全ての複製または実質的な部分に記載するものとする。)

(ソフトウェアは「現状有姿」で提供され、明示的であるか黙示的であるかを問わず、いかなる種類の保証も行われない。ここでいう保証には、商品性、特定目的への適合性、および権利の非侵害性に関する保証も含まれるが、これらに限定されるものではない。THE X CONSORTIUM は、契約、不法行為、またはその他の行為であるかを問わず、ソフトウェアまたはソフトウェアの使用もしくはその他に取り扱いに起因または関連して生じるいかなる請求、損害賠償、その他の責任について、一切の責任を負わない。)

(X Consortium の名称は、この表示に記載されている場合を除き、X Consortium の事前の書面による承認を得ずに、宣伝であろうとその他の形であろうと、ソフトウェアの販売を促進するもの、またはソフトウェアの使用その他の扱いを奨励するものに使用してはならない。)

(X Window System は The OpenGroup の商標である。)

## 第１章　同期プロトコル

X プロトコル本体は、異なるクライアントのリクエスト群の実行順序について、何も保証しない。そのため、クライアント間の同期は、クライアントの次元で、オペレーティング・システムとネットワークとに依存した手法で実施されなければならない。たとえこのような同期の手法に標準となるものが確立されているとしても、ネットワークの使用は、クライアント群の同期と、その結果として生じるリクエストの X サーバへの配送との間に、予測できない遅延を持ち込んでしまう。

X プロトコル本体はまた、リクエストが実行された時刻についても、何ら保証しない。そのため、リアルタイムでなければならないという制約を持つクライアントは全て、ホスト・コンピュータ上に自前の時間調整機能を実装しなければならない。このような時間調整機能はどのようなものであっても、オペレーティング・システムとネットワークに内在する遅延によるエラーに弱いものであり、また、クライアントとサーバとを同期し続けるための往復リクエストが必要であることから、非効率なものでもある。

この同期拡張(synchronization extension)は、クライアント間の同期が完全に X サーバの中で行われることを可能にするための機能要素(primitives)を提供する。これによって、ネットワークに起因するいかなるエラーも除くことができ、オペレーティング・システムとホストの両方を異にするクライアント同士であっても同期を取ることが可能となる。これは、音声、映像、画像のデータ・ストリームを同期し続けるマルチメディアのアプリケーションにとって重要なことである。また、この拡張では X サーバの中に内部タイマー(timer)を用意しており、クライアントのリクエストはこの内部タイマーと同期を取ることができる。これによって、単純なアニメーション・アプリケーションは如何なる往復リクエストも用いずに実装することが可能となり、クライアント、ネットワーク、及びサーバにおけるバッファリングのやり方も最適化される。

## 詳説

X サーバの中で同期を取るためにこの拡張が用いる仕組みは、特定の同期条件(synchronization condition)が調うまでクライアントから来たリクエストの処理をブロックするというものである。条件が調った場合、クライアントは(ブロックされている状態から)解放され、リクエストの処理が再開される。クライアント間の同期を取るために、複数のクライアントを同一の条件の下にブロックすることが可能である。また、アニメーション・フレーム・マーカー(animation frame marker)のような条件を使って、単一のクライアントをブロックすることもできる。

この拡張においては、X サーバが新たに管理する資源(resource)として、「`Counter`」(カウンタ)及び「`Alarm`」(アラーム)を導入する。カウンタは、64-bit の整数値であり、クライアントのリクエストによって、あるいはサーバの内部の処理によって、増えたり減ったりするものである。クライアントは `Await` リクエストを送信することでブロック状態(待機状態)になることができる。この Await リクエストは、同期条件(TRIGGER という)の集合の中の１つが TRUE になるまで待機するリクエストである。

クライアントは、`CreateCounter` リクエストを使って `Counter` (カウンタ) を作成することができる。カウンタは、これを引数とする２つのリクエスト `SetCounter` と `ChangeCounter` を使って変更することができる。これらは、異なるクライアントの間の同期処理を実装するのに使うことができる。

`System Counter` (システム・カウンタ)と呼ばれるカウンタも存在する。これは、クライアントがリクエストで変更するものではなく、X サーバが内部で変更するものである。システム・カウンタの変更の結果は、サーバが現在のリクエストの処理を終えるまでの間、外から知ることはできない。別の言い方をすると、システム・カウンタの更新は、リクエストが実際に実行されている時ではなく、リクエスト群の処理と処理の合間に行われているように見える。この拡張では次のようなシステム・カウンタを用意している。即ち、X プロトコル本体で定義されている「サーバ時間」とともに進むシステム・カウンタを用意しており、また、実際の世界の時間とともに進むシステム・カウンタや CRT 画面が更新(refresh)する度に変化するシステム・カウンタも(場合によっては)提供することができる。他の拡張も、独自のシステム・カウンタを提供することができる。

この拡張には `Alarm` 機構が備わっている。クライアントは、同機構を使うことによって、特定のカウンタが変更される度にイベントを受け取ることができるようになる。

## 第２章　C 言語バインディング

C 関数(routine)は、プロトコル(の手続き)を直接利用できるようにするものであり、プロトコル(の手続き)の機能(semantics)に何かを追加したりはしない。

この拡張を利用するために取り込むべきインクルード・ファイルは <X11/extensions/sync.h> である。C 言語バインディングにおける関数名のほとんどは、SYNC 拡張プロトコルに由来するものであり、プロトコル名の頭に XSync を付けて大文字小文字を変更しただけである。

## C 関数

以下の関数の大部分は、SYNC プロトコル・リクエストを生成するものである。

`Status XSyncQueryExtension(`Display *dpy, int *event_base_return, int *error_base_return`)`;

dpy のディスプレイが SYNC 拡張に対応していれば、`XSyncQueryExtension` は True を返し、*event_base_return には最初の SYNC イベントのイベント番号が設定され、*error_base_return には最初の SYNC エラーのエラー番号が設定される。dpy が SYNC 拡張に対応してなかった場合、この関数は False を返す。

`Status XSyncInitialize(`Display *dpy, int *major_version_return, int *minor_version_return`)`;

`XSyncInitialize` は、*major_version_return と *minor_version_return にサーバが使用している SYNC プロトコルの版番号(上位と下位)を設定する。XSync ライブラリがサーバの返した版と互換性のあるものであれば、この関数は `True` を返す。dpy のディスプレイが SYNC 拡張に対応していなかった場合、もしくはサーバと通信している最中にエラーが発生した場合、もしくはサーバとライブラリのプロトコルの版に互換性が無い場合、この関数は `False` を返す。この関数より先に呼び出すことができる XSync 関数は、XSyncQueryExtension だけである。クライアントがこの規則に違反した場合、同クライアントが行った全ての XSync 呼び出しの結果は未定義となる。

`XSyncSystemCounter *XSyncListSystemCounters(`Display *dpy, int *n_counters_return`)`;

`XSyncListSystemCounters` は、dpy のディスプレイが使用しているシステム・カウンタの配列へのポインタを返し、*n_counters_return に配列内のカウンタの個数を設定する。この配列は `XSyncFreeSystemCounterList` で解放するものとする。dpy が SYNC 拡張に対応していなかった場合、もしくはサーバと通信している最中にエラーが発生した場合、もしくはサーバがシステム・カウンタに対応していない場合、この関数は NULL を返す。

XSyncSystemCounter は以下のフィールドを持つ。

char * name; /* システム・カウンタの名前。null 文字終端 */
XSyncCounter counter; /* このシステム・カウンタのカウンタ ID */
XSyncValue resolution; /* このシステム・カウンタの分解能 */

`void XSyncFreeSystemCounterList(`XSyncSystemCounter *list`)`;

`XSyncFreeSystemCounterList` は、`XSyncListSystemCounters` で返ってきたシステム・カウンタの配列のメモリを解放する。

`XSyncCounter XSyncCreateCounter(`Display *dpy, XSyncValue initial_value`)`;

`XSyncCreateCounter` は、dpy のディスプレイにカウンタを作成し、同カウンタの ID を返す。このカウンタは、initial_value で指定された初期値を持つ。dpy が SYNC 拡張に対応していなかった場合、`None` を返す。

`Status XSyncSetCounter(`Display *dpy, XSyncCounter counter, XSyncValue value`)`;

`XSyncSetCounter` は、counter で指定されたカウンタに value で指定された値を設定する。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncChangeCounter(`Display *dpy, XSyncCounter counter, XSyncValue value`)`;

`XSyncChangeCounter` は、counter で指定されたカウンタの値に value で指定された値を加算する。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncDestroyCounter(`Display *dpy, XSyncCounter counter`)`;

`XSyncDestroyCounter` は、counter で指定されたカウンタを破棄する。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncQueryCounter(`Display *dpy, XSyncCounter counter, XSyncValue *value_return`)`;

`XSyncQueryCounter` は、*value_return にカウンタの現在の値を設定する。サーバと通信している最中にエラーが発生した場合、もしくは dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncAwait(`Display *dpy, XSyncWaitCondition *wait_list, int n_conditions`)`;

`XSyncAwait` は、wait_list に入っている条件群が調うのを待ち受ける。n_conditions は、wait_list に入っている条件(wait conditions)の数である。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。待受けはサーバによって非同期に実行され、この関数はリクエスト発行後、直ちに返る。

XSyncWaitCondition は以下のフィールドを持つ。

XSyncCounter trigger.counter; /* トリガーの判断に使うカウンタ */
XSyncValueType trigger.value_type; /* absolute/relative */
XSyncValue trigger.wait_value; /* カウンタと比べる値 */
XSyncTestType trigger.test_type; /* pos/neg comparison/transtion */
XSyncValue event_threshold; /* 閾値を超えたらイベントを送信 */

`XSyncValueType` は、`XSyncAbsolute` か `XSyncRelative` のどちらかである。

`XSyncTestType` は、`XSyncPositiveTransition`、`XSyncNegativeTransition`、`XSyncPositiveComparison`、もしくは `XSyncNegativeComparison` の中のいづれか(１つ)である。

`XSyncAlarm XSyncCreateAlarm(`Display *dpy, unsigned long values_mask, XSyncAlarmAttributes *values``)`;

`XSyncCreateAlarm` は、アラームを作成し、その ID を返す。dpy のディスプレイが SYNC 拡張に対応していない場合、(ID ではなく) None を返す。values_mask と values によって、アラームの属性値を指定する。

`XSyncAlarmAttributes` は以下のフィールドを持つ。下表の attribute_mask の列は、対応する属性の値が実際に指定されていることを伝えるために、リクエストを呼び出した者が OR 演算を使って values_mask に格納するシンボルである。該当する attribute_mask を OR 演算で繋いで values_mask に格納しなかった属性については、すべてデフォルトの値を使用する。デフォルトの値に関しては、SYNC プロトコルの `CreateAlarm` の説明を参照。

type field name attribute_mask
XSyncCounter trigger.counter; XSyncCACounter
XSyncValueType trigger.value_type; XSyncCAValueType
XSyncValue trigger.wait_value; XSyncCAValue
XSyncTestType trigger.test_type; XSyncCATestType
XSyncValue delta; XSyncCADelta
Bool events; XSyncCAEvents
XSyncAlarmState state; クライアント側では設定できない

`Status XSyncDestroyAlarm(`Display *dpy, XSyncAlarm alarm`)`;

`XSyncDestroyAlarm` は、alarm で指定されたアラームを破棄するものである。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncQueryAlarm(`Display *dpy, XSyncAlarm alarm, XSyncAlarmAttributes *values_return`)`;

`XSyncQueryAlarm` は、*values_return に alarm で指定されたアラームの属性群を設定する。サーバと通信している最中にエラーが発生した場合、もしくは dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncChangeAlarm(`Display *dpy, XSyncAlarm alarm, unsigned long values_mask, XSyncAlarmAttributes *values`)`;

`XSyncChangeAlarm` は、alarm で指定されたアラームの属性群を変更する。変更する属性は、`XSyncCreateAlarm` の時と同じやり方で指定する。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncSetPriority(`Display *dpy, XID client_resource_id, int priority`)`;

`XSyncSetPriority` は、client_resource_id で指定されたリソースを所有しているクライアントの優先度を priority で指定された値に設定するものである。client_resource_id が None であった場合、このリクエストを呼び出した者の優先度が設定される。dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

`Status XSyncGetPriority(`Display *dpy, XID client_resource_id, int *return_priority`)`;

`XSyncGetPriority` は、client_resource_id で指定されたリソースを所有しているクライアントの優先度を *return_priority に設定するものである。client_resource_id が None であれば、このリクエストを呼び出した者の優先度が *return_priority に設定される。サーバと通信している最中にエラーが発生した場合、もしくは dpy のディスプレイが SYNC 拡張に対応していなかった場合、`False` が返る。それ以外の場合は `True` が返る。

## C マクロ/関数

以下の手続きは、64 ビットの値を操作するものである。各手続きは、マクロと関数の両方の形式で定義されている。デフォルトでは(特に何も変更しなければ)、マクロ形式のものが使用される。関数形式のものを利用するには、マクロ名と関数名とが衝突しないように、マクロ名を「#undef」して無効化する。

`void XSyncIntToValue(`XSyncValue *pv, int i`)`;

i を `XSyncValue` 型に変換し、結果を *pv に格納する。正負の符号の拡張を行う(*pv は i と同じ符号を持つ)。(訳註：`XSyncValue` は 64 ビットの値、int は 32 ビット。)

`void XSyncIntsToValue(`XSyncValue *pv, unsigned int low, int high`)`;

low の値を *pv の下位 32 ビットに格納し、high の値を *pv の上位 32 ビットに格納する。

`Bool XSyncValueGreaterThan(`XSyncValue a, XSyncValue b`)`;

a が b より大きければ `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueLessThan(`XSyncValue a, XSyncValue b`)`;

a が b より小さければ `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueGreaterOrEqual(`XSyncValue a, XSyncValue b`)`;

a が b 以上であれば(大きいか等しければ) `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueLessOrEqual(`XSyncValue a, XSyncValue b`)`;

a が b 以下であれば(小さいか等しければ) `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueEqual(`XSyncValue a, XSyncValue b`)`;

a と b が等しければ `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueIsNegative(`XSyncValue v`)`;

v の値が負であれば `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueIsZero(`XSyncValue v`)`;

v の値が 0 であれば `True` を返し、そうでなければ `False` を返す。

`Bool XSyncValueIsPositive(`XSyncValue v`)`;

v の値が正であれば `True` を返し、そうでなければ `False` を返す。

`unsigned int XSyncValueLow32(`XSyncValue v`)`;

v の下位 32 ビットを返す。

`unsigned int XSyncValueHigh32(`XSyncValue v`)`;

v の上位 32 ビットを返す。

`void XSyncValueAdd(`XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow`)`;

a と b を足して結果を *presult に格納する。結果が 64 ビットに収まらなかった場合、*poverﬂow は `True` に設定され、そうでない場合は `False` に設定される。

`void XSyncValueSubtract(`XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow`)`;

a から b を引いて結果を *presult に格納する。結果が 64 ビットに収まらなかった場合、*poverﬂow は `True` に設定され、そうでない場合は `False` に設定される。

`void XSyncMaxValue(`XSyncValue *pv`)`;

64 ビットで表現できる数値の中、最大のものを *pv に設定する。

`void XSyncMinValue(`XSyncValue *pv`)`;

64 ビットで表現できる数値の中、最小のものを *pv に設定する。

## イベント

下表の event_base は、関数 `XSyncQueryExtension` のところで定義されている event_base_return の値であると仮定する。

`XSyncCounterNotifyEvent` の type フィールドの値は、event_base + `XSyncCounterNotify` である。この構造体のメンバは以下の通り。

int type; /* event base + XSyncCounterNotify */
unsigned long serial; /* サーバが最後に処理したリクエストの番号 */
Bool send event; /* SendEvent リクエスト由来であれば true */
Display * display; /* イベントを読み込む Display */
XSyncCounter counter; /* 待受けの対象のカウンタ */
XSyncValue wait_value; /* 待ち受けている値 */
XSyncValue counter_value; /* このイベントが送信された時のカウンタの値 */
Time time; /* ミリ秒 */
int count; /* 続いて来るイベントの数 */
Bool destroyed; /* カウンタが破棄された場合は True */

`XSyncAlarmNotifyEvent` の type フィールドの値は、event_base + `XSyncAlarmNotify` である。この構造体のメンバは以下の通り。

int type; /* event_base + XSyncAlarmNotify */
unsigned long serial; /* サーバが最後に処理したリクエストの番号 */
Bool send_event; /* SendEvent リクエスト由来であれば true */
Display * display; /* イベントを読み込む Display */
XSyncAlarm alarm; /* トリガーされたアラーム */
XSyncValue counter_value /* アラームをトリガーした値 */
XSyncValue alarm_value /* アラームのトリガーの試験値 */
Time time; /* ミリ秒 */
XSyncAlarmState state; /* アラームの新たな状態 */

## エラー

error_base は、関数 `XSyncQueryExtension` のところで定義した error_base_return の値であると仮定する。

`XSyncAlarmError` の error_code フィールドの値は `XSyncBadAlarm` である(訳註：error_base + XSyncBadAlarm である)。この構造体のメンバは以下の通り。

int type
Display * display; /* イベントを読み込む Display */
XSyncCounter counter; /* リソース ID */
unsigned long serial; /* 蹉跌したリクエストの通し番号 */
unsigned char error_code; /* error_base + XSyncBadAlarm */
unsigned char request_code; /* 蹉跌したリクエストの主たる命令コード */
unsigned char minor_code; /* 蹉跌したリクエストの従たる命令コード */

`XSyncCounterError` の error_code フィールドの値は、error_base + `XSyncBadCounter` である。この構造体のメンバは以下の通り。

int type
Display * display; /* イベントを読み込む Display */
XSyncCounter counter; /* リソース ID */
unsigned long serial; /* 蹉跌したリクエストの通し番号 */
unsigned char error_code; /* error_base + XSyncBadCounter */
unsigned char request_code; /* 蹉跌したリクエストの主たる命令コード */
unsigned char minor_code; /* 蹉跌したリクエストの従たる命令コード */

入り口に戻る