入り口に戻る

原文はこちら

翻訳にあたって、オープンソースグループ・ジャパンの 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

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.

(訳)

(以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを無償で許可する。これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれる。)

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

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

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

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


目次

1. 同期プロトコル
詳説
2. C 言語バインディング
C 関数
C マクロ/関数
イベント
エラー

第1章 同期プロトコル

目次

詳説

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

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

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

詳説

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

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

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

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

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

第2章 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 は、XSyncAbsoluteXSyncRelative のどちらかである。

XSyncTestType は、XSyncPositiveTransitionXSyncNegativeTransitionXSyncPositiveComparison、もしくは XSyncNegativeComparison の中のいづれか(1つ)である。

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 ビットに収まらなかった場合、*poverflow は True に設定され、そうでない場合は False に設定される。

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

a から b を引いて結果を *presult に格納する。結果が 64 ビットに収まらなかった場合、*poverflow は 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;   /* 蹉跌したリクエストの従たる命令コード */

入り口に戻る