Chapter 16 Application Utility Functions

16 章: アプリケーションユーティリティ関数

一度 X システムの初期化が終わると、Xlib のユーティリティ関数を使って 以下の処理が行える:

まとめてみた場合には、この章で説明する関数は頻繁に必要となる機能や ツールキットを補う機能を提供する。 これらの関数の多くは、サーバに対する実際のプロトコルリクエストを生成 しない。

キーボードユーティリティ関数の使用

この節では KeyCode と KeySym とのマッピング、KeySym の分類、 KeySym と文字列名とのマッピングについて説明する。 この節で説明する最初の 3 つの関数は、サーバのキーボードマッピング のキャッシュされたコピーを操作する。 それぞれの KeyCode に対する最初の 4 つの KeySyms は、12.7 節で説明した 規則にしたがって変更される。 あるキーについて定義されている、変形されていない KeySym を得るには 12.7 節で説明されている関数を使う。

イベントの KeyCode に対する KeySym を得るには XLookupKeysymを使う。

KeySym XLookupKeysym(key_event, index)
XKeyEvent *key_event;
int index;
key_event
KeyPressイベントか KeyReleaseイベントを指定する。
index
イベントの KeyCode に対する KeySym のリストにおけるインデックスを指定する。

関数 XLookupKeysymは与えられたキーボードイベントと指定されたインデックスを使い、 XKeyPressedEventXKeyReleasedEvent構造体の KeyCode メンバに対応するリストから得た KeySym を返す。 イベントの KeyCode に対して KeySym が定義されていなければ、 XLookupKeysymNoSymbolを返す。

特定の KeyCode に対する KeySym を得るには XKeycodeToKeysymを使う。

KeySym XKeycodeToKeysym(display, keycode, index)
Display *display;
KeyCode keycode;
int index;
display
X サーバへの接続を指定する。
keycode
KeyCode を指定する。
index
KeyCode ベクトルの要素を指定する。

関数 XKeycodeToKeysymは Xlib の内部テーブルを使い、指定した KeyCode と KeyCode ベクトルの要 素に対して定義された KeySym を返す。 シンボルが定義されていない場合、 XKeycodeToKeysymNoSymbolを返す。

特定の KeySym を持つキーに対する KeyCode を指定するには XKeysymToKeycode を使う。

KeyCode XKeysymToKeycode(display, keysym)
Display *display;
KeySym keysym;
display
X サーバへの接続を指定する。
keysym
検索の対象となる KeySym を指定する。

指定した KeySym がどの KeyCode に対しても定義されていない場合には、 XKeysymToKeycodeは 0 を返す。

KeyCode と KeySym のマッピングは Xlib の内部にキャッシュされる。 この情報がサーバ内で変更される際に、キャッシュをリフレッシュするために 呼ばれる Xlib の関数がある。 格納されているモディファイアとキーマップの情報をリフレッシュするには XRefreshKeyboardMappingを使う。

XRefreshKeyboardMapping(event_map)
XMappingEvent *event_map;
event_map
使用するマッピングイベントを指定する。

関数 XRefreshKeyboardMappingは、格納されているモディファイアとキーマップの情報を更新する。 通常この関数が呼び出されるのは、 MappingNotifyイベントが発生して、その request メンバが MappingKeyboardMappingModifierだったときである。 関数を呼び出した結果、Xlib のキーボードの情報が更新される。

大文字と小文字の形式の KeySym を得るには XConvertCaseを使う。 を使う。

void XConvertCase(keysym, lower_return, upper_return)
KeySym keysym;
KeySym *lower_return;
KeySym *upper_return;
keysym
変換する KeySym の名前を指定する。
lower_return
キーシンボルか小文字の形式のキーシンボルが返される。
upper_return
キーシンボルか大文字の形式のキーシンボルが返される。

KeySym が大文字・小文字の変換に従う場合、関数 XConvertCaseは指定した KeySym を大文字および小文字の形式で返す。 そうでない場合には、指定した KeySym が lower_return と upper_return の 両方に返される。 Latin と Cyrillic 以外の KeySym の変換に対応しているかどうかは実装による。

KeySym は文字列名の他に数値コードを持っている。 KeySym の名前を KeySym コードに変換するには XStringToKeysymを使う。

KeySym XStringToKeysym(string)
char *string;
string
変換する KeySym の名前を指定する。

標準の KeySym 名は <X11/keysymdef.h>内のそれぞれの名前から接頭辞 XK_ を取り除くことによって得られる。 Xlib の標準に含まれていない KeySym もこの関数で得られる。 この方法で得られる KeySym と Xlib がこれらの KeySym を得るために使う 機構は実装依存である。

KeySym の名前のエンコーディングがホストポータブル文字エンコーディング でない場合の実行結果は実装依存である。 指定した文字列が有効な KeySym にマッチしない場合、 XStringToKeysymNoSymbolを返す。

KeySym コードを KeySym の名前に変換するには XKeysymToStringを使う。

char *XKeysymToString(keysym)
KeySym keysym;
keysym
変換される KeySym を指定する。

返される文字列は静的領域に置かれるので変更してはならない。 この文字列のエンコーディングはホストポータブル文字エンコーディングであ る。 指定した KeySym が定義されていない場合、 XKeysymToStringは NULL を返す。

KeySym を分類するマクロ

例えば KeySym がテンキーのキーか、それともファンクションキーかを調べた い場合がある。 KeySym マクロを使うと以下のことを調べられる。

IsCursorKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym がカーソルキーならば Trueを返す。

IsFunctionKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym がファンクションキーならば Trueを返す。

IsKeypadKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym が標準のテンキーならば Trueを返す。

IsPrivateKeypadKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym がベンダー独自ののテンキーならば Trueを返す。

IsMiscFunctionKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym がその他のファンクションキーならば Trueを返す。

IsModifierKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym がモディファイアキーならば Trueを返す。

IsPFKey(keysym)
keysym
調べる KeySym を指定する。

指定した KeySym が PF キーならば Trueを返す。

Latin-1 キーボードを使うイベント関数

13 章では国際化テキスト入力機能を説明したが、場合によっては Latin-1 文字や ASCII 制御文字しか扱わないアプリケーションを書く方が都 合が良いこともあるので、Xlib にはそのための簡単な関数が用意されている。 XLookupStringは 12.7 節で説明したモディファイアの標準セマンティクスを処理する。 この関数は 13 章で説明した入力メソッド機能は全く使わないし、 現在のロケールに依存することもない。

キーイベントを ISO Latin-1 文字列にマップするには XLookupStringを使う。

int XLookupString(event_struct, buffer_return, bytes_buffer, keysym_return, status_in_out)
XKeyEvent *event_struct;
char *buffer_return;
int bytes_buffer;
KeySym *keysym_return;
XComposeStatus *status_in_out;
event_struct
使用するキーイベント構造体を指定する。 XKeyPressedEventまたは XKeyReleasedEventを指定できる。
buffer_return
トランスレートされた文字が返される。
bytes_buffer
バッファの大きさを指定する。 トランスレートされた文字列のうち bytes_buffer を越えた分は返されない。
keysym_return
この引き数が NULL でなければ、イベントから求めた KeySym が返される。
status_in_out
XComposeStatus構造体か NULL を指定する。 またはこれらが返される。

XLookupStringはキーイベントを KeySym と文字列にトランスレートする。 KeySym は X プロトコル仕様で定義されている Shift ,Lock ,グループ、numlock モディファイアの標準の解釈を使って取得する。 KeySym が再バインドされていた場合( XRebindKeysymを参照)、バインドされている文字列がバッファに格納される。 そうでない場合、可能であれば KeySym は ISO Latin-1 文字か (Control モ ディファイアが有効であれば) ACSII 制御文字にマップされ、その文字がバッ ファに格納される。 XLookupStringはバッファに格納した文字数を返す。

もし XComposeStatus構造体が存在していれば(NULLでなければ)、 この構造体には組み立て処理を実行するための XLookupStringの呼び出し間での保存が必要な状態が記録される。 この状態は Xlib のプライベートなものである。 XComposeStatusの生成は実装依存である。 移植性を必要とするプログラムでは、この引き数に NULL を渡すべきである。

XLookupStringは前の節で説明した、キャッシュされているキーボード情報に依存する。 したがって、この情報を最新に保つためには XRefreshKeyboardMappingを使う必要がある。

XLookupStringにとっての KeySym の意味を再バインドするには XRebindKeysymを使う。

XRebindKeysym(display, keysym, list, mod_count, string, num_bytes)
Display *display;
KeySym keysym;
KeySym list[];
int mod_count;
unsigned char *string;
int num_bytes;
display
X サーバへの接続を指定する。
keysym
再バインドされる KeySym を指定する。
list
モディファイアとして使う KeySym のリストを指定する。
mod_count
モディファイアのリスト内のモディファイアの数を指定する。
string
XLookupStringにコピーされ、返される文字列を指定する。
num_bytes
引き数 string のバイト数を指定する。

関数 XRebindKeysymを使うとクライアントにとっての KeySym の意味を再バインドできる。 この関数は X サーバのキーを再定義するのではなく、単に長い文字列をキー に割り当てる簡単な方法を提供するものである。 XLookupStringは適切な組合せのモディファイアキーが押された時と、KeySym が トランスレーションに対して用いられた時にこの文字列を返す。 テキスト変換は行われない。 適切にエンコードした文字列を与える責任はクライアントが負う。 存在しない KeySym にも再バインドができる点に注意せすること。

恒久的にメモリを割り当てる

返すことが絶対にないメモリを割り当てるには Xpermallocを使う。

char *Xpermalloc(size)
unsigned int size;

Xpermalloc関数はプログラムの生存期間の間は解放されることがありえないメモリを割り 当てる。このメモリは C 言語の double 型のアラインメントで割り当てられ る。 この関数を使うと、OS 標準のメモリ割り当て機構を使うよりもいくらか性能 が向上し、メモリも節約できるかもしれない。

ウィンドウのジオメトリ文字列の解析

標準のウィンドウジオメトリ文字列を解析するには XParseGeometryを使う。

int XParseGeometry(parsestring, x_return, y_return, width_return, height_return)
char *parsestring;
int *x_return, *y_return;
unsigned int *width_return, *height_return;
parsestring
解析する文字列を指定する。
x_return

y_return
x, y のオフセットが返される。
width_return

height_return
決定された幅と高さが返される。

伝統的に X のアプリケーションでは、標準の文字列を使って ウィンドウのサイズや位置を指定する。 XParseGeometryを使うと標準のウィンドウのジオメトリを解析することができるので、 アプリケーションをこの標準に準拠させることが簡単に行える。 具体的には、この関数は次の形式の文字列を解析する。

[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>] 

各フィールドはこの関数の引き数に対応する。 (<> で囲んだものは整数、[] で囲んだものは省略可能、{} で囲んだも のは「どれか1つの選択」を意味する。 実際の文字列には括弧が現われてはならないので注意すること。) 文字列のエンコーディングがホストポータブル文字エンコーディングでない場合の 結果は実装依存である。

関数 XParseGeometryは、4 つの値(width, height, xoffset, yoffset)のうち実際に文字列中で 設定されているものと、x, y の値が負でないかどうかを示すビットマスク を返す。 伝統的には、-0 と +0 は異なる値である。ユーザは「画面の右端あるいは下 端からの相対座標」を指定する必要があるからである。 見つかったそれぞれの値に対して、対応する引き数が更新される。 見つからなかった値については、引き数は変更されないままである。 ビットは XValue , YValue , WidthValue , HeightValue ,XNegative , YNegativeで表現される。これは <X11/Xutil.h>で定義されている。 値のうちのいずれかか符号のうちのいずれかが文字列中に現われていれば、このビットは 必ず設定される。

この関数が XValue フラグか YValue フラグを返した場合、クライアントは要求された位置にウィンドウを配置すべ きである。

ウィンドウのジオメトリ情報を作るには XWMGeometryを作る。

int XWMGeometry(display, screen, user_geom, def_geom, bwidth, hints, x_return, y_return,
width_return, height_return, gravity_return)
Display *display;
int screen;
char *user_geom;
char *def_geom;
unsigned int bwidth;
XSizeHints *hints;
int *x_return, *y_return;
int *width_return;
int *height_return;
int *gravity_return;
display
X サーバへの接続を指定する。
screen
スクリーンを指定する。
user_geom
ユーザ指定のジオメトリか NULL を指定する。
def_geom
アプリケーションのデフォルトのジオメトリか NULL を指定する。
bwidth
境界幅を指定する。
hints
通常の状態での、ウィンドウのサイズのヒントを指定する。
y_return
x, y のオフセットが返される。
width_return

height_return
決定された幅と高さが返される。
gravity_return
ウィンドウの gravity 値が返される。

関数 XWMGeometry は、ユーザやこの関数を呼び出したプログラムが指定した何らかのジオメトリ 情報( XParseGeometryで使用されるフォーマット)をサイズヒント(普通は WM_NORMAL_HINTS に格納 されているヒント)と結びつけ、ウィンドウを記述する位置、サイズ、gravity 値 (NorthWestGravity , NorthEastGravity , SouthEastGravity ,SouthWestGravityのいずれか)を返す。 XSizeHints構造体に基本サイズが設定されていない場合には、最小サイズが設定されてい ればこれを使用する。 そうでない場合には、ベースサイズは 0 とされる。 ヒント構造体に最小サイズが設定されていない場合は、基本サイズが使用され る。 この関数は( XParseGeometryが返す形式の)マスク値を返す。 この値は、どの値がユーザ指定であるか、ウィンドウの位置は画面右端や下端か らの相対座標であるかどうかを示す。 これらの座標は既に、x_return, y_return の値として処理されている点に注 意すること。

また、不正なジオメトリを指定すると高さや幅として 0 が返される場合が ある点に注意すること。 関数を呼ぶ時には、ヒントを直接更新するためにヒントの win_gravity フィールドのアドレスを渡してもよい。

リージョンの操作

リージョンはピクセル位置の任意の集合である。 Xlib にはリージョンを操作するための関数が用意されている。 opaque な型 Regionが <X11/Xutil.h>で定義されている。 Xlib にはリージョン操作に使える関数が用意されている。 この節では以下の方法を説明する:

リージョンの生成、コピー、破棄

新しい空のリージョンを作るには XCreateRegion を使う。

Region XCreateRegion()

多角形からリージョンを作るには XPolygonRegion を使う。

Region XPolygonRegion(points, n, fill_rule)
XPoint points[];
int n;
int fill_rule;
points
点の配列を指定する。
n
多角形の頂点数を指定する。
fill_rule
指定した GC に設定する塗りつぶし規則を指定する。 EvenOddRuleWindingRuleを指定できる。

関数 XPolygonRegionは点の配列によって定義される多角形に対するリージョンを返す。 fill_rule の説明については XCreateGCを参照すること。

GC の clip-mask をリージョンに設定するには XSetRegionを使う。

XSetRegion(display, gc, r)
Display *display;
GC gc;
Region r;
display
X サーバへの接続を指定する。
gc
GC を指定する。
r
リージョンを指定する。

関数 XSetRegionは指定したリージョンに GC 内の clip-mask を設定する。 リージョンはドロウアブルの原点からの相対座標で指定される。 結果として得られる GC のクリップの原点は実装依存である。 一度クリップが GC 内に設定されれば、リージョンは破棄してもよい。

指定されたリージョンに対応するメモリを解放するには XDestroyRegionを使う。

XDestroyRegion(r)
Region r;
r
リージョンを指定する。

リージョンの移動と収縮

リージョンを指定量だけ動かすには XOffsetRegionを使う。

XOffsetRegion(r, dx, dy)
Region r;
int dx, dy;
r
リージョンを指定する。
dx

dy
x, y 座標を指定する。 これは指定したリージョンの移動量を定義する。

リージョンを指定した量だけ小さくするには XShrinkRegionを使う。

XShrinkRegion(r, dx, dy)
Region r;
int dx, dy;
r
リージョンを指定する。
dx

dy
x, y 座標を指定する。 これは指定したリージョンの縮小量を定義する。

正の値の場合はリージョンのサイズは縮小され、負の値の場合はリージョンは 拡大される。

リージョンを使った計算

リージョンを包む最小の長方形を生成するには XClipBoxを使う。

XClipBox(r, rect_return)
Region r;
XRectangle *rect_return;
r
リージョンを指定する。
rect_return
多角形を囲む最小の長方形が返される。

関数 XPolygonRegionは点の配列によって定義される多角形に対するリージョンを返す。

2 つのリージョンが重なっている部分を計算するには XIntersectRegionを使う。

XIntersectRegion(sra, srb, dr_return)
Region sra, srb, dr_return;
sra

srb
計算の対称にするリージョンを 2 つ指定する。
dr_return
計算結果が返される。

2 つのリージョンの和集合を求めるには XUnionRegionを使う。

XUnionRegion(sra, srb, dr_return)
Region sra, srb, dr_return;
sra

srb
計算の対称にするリージョンを 2 つ指定する。
dr_return
計算結果が返される。

元のリージョンと長方形の和集合を作るには XUnionRectWithRegionを使う。

XUnionRectWithRegion(rectangle, src_region, dest_region_return)
XRectangle *rectangle;
Region src_region;
Region dest_region_return;
rectangle
長方形を指定する。
src_region
計算に使う元のリージョンを指定する。
dest_region_return
目的のリージョンが返される。

関数 XUnionRectWithRegionは、指定した長方形と指定した元のリージョンの和集合を使って対象の リージョンを更新する。

2 つのリージョンの差を取るには XSubtractRegionを使う。

XSubtractRegion(sra, srb, dr_return)
Region sra, srb, dr_return;
sra

srb
計算の対称にするリージョンを 2 つ指定する。
dr_return
計算結果が返される。

関数 XSubtractRegionsra から srb を引き、その結果を dr_return に格納する。

2 つのリージョンの和集合と共通部分の差を計算するには XXorRegionを使う。

XXorRegion(sra, srb, dr_return)
Region sra, srb, dr_return;
sra

srb
計算の対称にするリージョンを 2 つ指定する。
dr_return
計算結果が返される。

リージョンが空かどうか、あるいは別のリージョンと同じかどうかを調べる

指定されたリージョンが空かどうか調べるには XEmptyRegionを使う。

Bool XEmptyRegion(r)
Region r;
r
リージョンを指定する。

関数 XEmptyRegionはリージョンが空ならば Trueを返す。

2 つのリージョンが同じオフセット、大きさ、形状を持っているかどうかを調 べるには XEqualRegionを使う。

Bool XEqualRegion(r1, r2)
Region r1, r2;
r1

r2
リージョンを 2 つ指定する。

関数 XEqualRegionは、2 つのリージョンが同じオフセット、大きさ、形を持つときに Trueを返す。

リージョン内の点や長方形の位置の指定

指定された点が指定されたリージョンの中にあるかどうかを調べるには XPointInRegionを使う。

Bool XPointInRegion(r, x, y)
Region r;
int x, y;
r
リージョンを指定する。
x

y
点を定義する x, y 座標を指定する。

関数 XPointInRegionは、点(x, y)がリージョンrに含まれているときに Trueを返す。

指定された長方形がリージョンの内側にあるかどうかを調べるには XRectInRegionを使う。

int XRectInRegion(r, x, y, width, height)
Region r;
int x, y;
unsigned int width, height;
r
リージョンを指定する。
x

y
x, y 座標を指定する。これは長方形の左上の座標を定義する。
width

height
幅と高さを指定する。これは長方形を定義する。

関数 XRectInRegionは、長方形全体が指定したリージョンの内側である場合に RectangleInを返し、長方形全体が指定したリージョンの外側である場合に RectangleOutを返し、 長方形が指定したリージョンに部分的に含まれている場合に RectanglePartを返す。

カットバッファの使用

Xlib にはカットバッファを操作するための関数が用意されている。 カットバッファはカット&ペースト形式のクライアント間通信の非常に簡単な 形である。 セレクションはクライアント間でデータを交換するためのより強力かつ便利な 仕組みであり(4.5 節を参照)、普通はカットバッファよりもセレクションを使 うべきである。

カットバッファはディスプレイの最初のルートウィンドウのプロパティとして 実装されている。 バッファは STRING エンコーディングのテキストしか格納できない。 Xlib が取得や格納を行う際にテキストのエンコーディングを変えることはない。 バッファは 8 つ用意されており、リングとして使うことも (番号 0 から番号 7 を)明示的に指定して使うこともできる。

カットバッファ 0 にデータを格納するには XStoreBytes を使う。

XStoreBytes(display, bytes, nbytes)
Display *display;
char *bytes;
int nbytes;
display
X サーバへの接続を指定する。
bytes
バイト列を指定する。 これは必ずしも ASCII でなくてもよいし、NULL で終わる必要もない。
nbytes
格納するバイト数を指定する。

データの途中に NULL 文字があっても良いし、データが NULL 文字で終わる必 要もない。 カットバッファの内容は後で任意のクライアントから XFetchBytesを呼び出すことで取り出せる。

XStoreBytesはエラー BadAllocを起こすことがある。

指定されたカットバッファにデータを格納するには XStoreBufferを使う。

XStoreBuffer(display, bytes, nbytes, buffer)
Display *display;
char *bytes;
int nbytes;
int buffer;
display
X サーバへの接続を指定する。
bytes
バイト列を指定する。 これは必ずしも ASCII でなくてもよいし、NULL で終わる必要もない。
nbytes
格納するバイト数を指定する。
buffer
バイト列を格納するバッファを指定する。

不正なバッファが指定された場合、この呼び出しでは何も起こらない。 データの途中に NULL 文字があっても良いし、データが NULL 文字で終わる必 要もない。

XStoreBufferはエラー BadAllocを起こすことがある。

カットバッファ 0 のデータを返すには XFetchBytesを使う。

char *XFetchBytes(display, nbytes_return)
Display *display;
int *nbytes_return;
display
X サーバへの接続を指定する。
nbytes_return
バッファ内のデータのバイト数が返される。

関数 XFetchBytesは、カットバッファ内にデータがあれば、引き数 nbytes_return にそのバイト 数を返す。 そうでない場合は関数は NULL を返し、nbytes_return には 0 が設定される。 適切な量のメモリが割り当てられ、そのポインタが返される。 クライアントはデータを使い終わった後、 XFreeを呼んでメモリを解放しなければならない。

指定されたカットバッファからデータを返すには XFetchBufferを使う。

char *XFetchBuffer(display, nbytes_return, buffer)
Display *display;
int *nbytes_return;
int buffer;
display
X サーバへの接続を指定する。
nbytes_return
バッファ内のデータのバイト数が返される。
buffer
格納しているデータを取り込むバッファを指定する。

関数 XFetchBufferは、バッファ内にデータがない場合と不正なバッファが指定された場合には 引き数 nbytes_return に 0 を返す。

カットバッファをローテートさせるには XRotateBuffersを使う。

XRotateBuffers(display, rotate)
Display *display;
int rotate;
display
X サーバへの接続を指定する。
rotate
カットバッファをローテートさせる量を指定する。

関数 XRotateBuffersはバッファをローテートさせる。これはバッファ 0 をバッファ n とし、 バッファ 1 を n + 1 mod 8 にするという形で行われる。 このカットバッファの番号付けはディスプレイについて大域的なものである。 8 つのバッファがいずれも作られていない場合には、 XRotateBuffersはエラー BadMatchとなることに注意せよ。

適切なビジュアル型の決定

一つのディスプレイは複数のスクリーンに対応可能である。 各スクリーンは、それぞれの深さでサポートされている複数の種類の ビジュアル型を持てる。 この節で説明する関数を使うと、アプリケーションで使うビジュアルを 決めることができる。

この節の関数はビジュアル情報マスクと XVisualInfo 構造体を使う。これらは <X11/Xutil.h>で定義されており、内容は以下の通りである:

/* ビジュアル情報マスクのビット値 */

#define VisualNoMask 0x0
#define VisualIDMask 0x1
#define VisualScreenMask 0x2
#define VisualDepthMask 0x4
#define VisualClassMask 0x8
#define VisualRedMaskMask 0x10
#define VisualGreenMaskMask 0x20
#define VisualBlueMaskMask 0x40
#define VisualColormapSizeMask 0x80
#define VisualBitsPerRGBMask 0x100
#define VisualAllMask 0x1FF
/* 値 */
typedef struct {
	Visual *visual;
	VisualID visualid;
	int screen;
	unsigned int depth;
	int class;
	unsigned long red_mask;
	unsigned long green_mask;
	unsigned long blue_mask;
	int colormap_size;
	int bits_per_rgb;
} XVisualInfo;

指定されたテンプレートにマッチするビジュアル情報構造体のリストを得るには XGetVisualInfoを使う。

XVisualInfo *XGetVisualInfo(display, vinfo_mask, vinfo_template, nitems_return)
Display *display;
long vinfo_mask;
XVisualInfo *vinfo_template;
int *nitems_return;
display
X サーバへの接続を指定する。
vinfo_mask
ビジュアルのマスク値を指定する。
vinfo_template
ビジュアル構造体とのマッチングで使うビジュアル属性を指定する。
nitems_return
マッチしたビジュアル構造体の数が返される。

関数 XGetVisualInfoは vinfo_template で指定した属性と同じ属性を持つビジュアル構造体の リストを返す。 指定した vinfo_template を使ったテンプレートにマッチするビジュアル構造体 がない場合は、 XGetVisualInfoは NULL を返す。 この関数に返されたデータを解放するには、 XFreeを使用すること。

スクリーンの指定された深さとクラスにマッチするビジュアル情報を得るには XMatchVisualInfoを使う。

Status XMatchVisualInfo(display, screen, depth, class, vinfo_return)
Display *display;
int screen;
int depth;
int class;
XVisualInfo *vinfo_return;
display
X サーバへの接続を指定する。
screen
スクリーンを指定する。
depth
スクリーンの深さを指定する。
class
スクリーンのクラスを指定する。
vinfo_return
マッチしたビジュアル情報が返される。

XMatchVisualInfo関数は、あるスクリーンについて指定した深さとクラスにマッチするビジュアル のビジュアル情報を返す。 指定した深さとクラスにマッチするビジュアルは複数個存在することがあるの で、選ばれる正確なビジュアルは未定義である。 マッチするビジュアルがあった場合、 XMatchVisualInfoは 0 でない値を返し、ビジュアルの情報を vinfo_return に設定する。 そうでない場合、つまりビジュアルが見つからなかった場合は、 XMatchVisualInfoは 0 を返す。

イメージの操作

Xlib にはイメージの基本操作を行う関数がいくつか用意されている。 イメージに対する全ての操作は XImage 構造体を使って定義されている。この構造体は <X11/Xlib.h>で定義されている。 イメージのフォーマットの種類は数が非常に多くなるかもしれないので、 この方法によってアプリケーションからイメージの詳細をうまく隠している。

この節ではイメージの一般的な操作のための関数について説明する。 メーカーは自分達のハードウェアがよく出会うフォーマットに関する 実装を特に高速にしておくことができる。 これらの関数は一般的な画像処理に使うには十分でもないし、望ましくもない。 これらの関数はどちらかというと画面形式のイメージに対して使う最小限の 関数として用意されています。 イメージの取得と貼り付けを行うための基本操作は XGetImageXPutImageです。

注意: 今のところ、ディスク上のイメージを読み書きする関数は定義されてい ません。

XImage 構造体は、クライアントのメモリ内に存在する形でイメージを記述する。 ユーザはイメージをサーバに送る時に高さ、幅、X 方向のオフセットといった 一部のメンバを変更するようなリクエストを行える。 bytes_per_line とオフセットを組み合わせて使うとイメージのサブセットを 取り出せることを覚えておくとよいだろう。 他のメンバ(例えばバイト順、bitmap_unit 等)はイメージとサーバの両方の 特性である。 もしこれらのメンバがイメージとサーバの間で異なる場合は、 XPutImage が適切な変換を行う。 プレーン n の最初の行の最初のバイトはアドレス (data + (n * height * bytes_per_line)) になければならない。 XImage 構造体の内容については 8.7 節を参照すること。

XImage 構造体を割り当て、ディスプレイから得たイメージフォーマット値で初期化す るには XCreateImageを使う。

XImage *XCreateImage(display, visual, depth, format, offset, data, width, height, bitmap_pad,
bytes_per_line)
Display *display;
Visual *visual;
unsigned int depth;
int format;
int offset;
char *data;
unsigned int width;
unsigned int height;
int bitmap_pad;
int bytes_per_line;
display
X サーバへの接続を指定する。
visual
Visual構造体を指定する。
depth
イメージの深さを指定する。
format
イメージの形式を指定する。 XYBitmap ,XYPixmap ,ZPixmapのいずれかを指定できる。
offset
スキャンラインの先頭で無視するビット数を指定する。
data
イメージデータを指定する。
width
イメージの幅をピクセル数で指定する。
height
イメージの高さをピクセル数で指定する。
bitmap_pad
スキャンラインの最小単位(8, 16, 32 のいずれか)を指定する。 言い替えれば、クライアントのメモリ中では、スキャンラインの先頭は次の スキャンラインの先頭とこのビット数の整数倍だけ離れている。
bytes_per_line
クライアントのイメージ内での、あるスキャンラインの先頭と次の スキャンラインの先頭の間のバイト数を指定する。

関数 XCreateImageは、指定したディスプレイにおける XImageに必要なメモリを割り当てる。しかし、イメージそのもののためのメモリは 割り当てない。 この関数はメモリの割り当てと言うよりも、ディスプレイより構造体のバイト順、 ビット順、ビットマップの基本単位(bitmap-unit)を初期化して XImage構造体へのポインタを返すものである。 red, green, blue マスク値は Z フォーマットのイメージに対してのみ定義 される。これらの値は受け取った Visual より求められる。 この他の値も渡されることがある。 引き数 offset を使うと各スキャンラインの先頭に移動する必要がないので、 イメージを高速に表示できる。 bytes_per_line に 0 を指定した場合、Xlib はスキャンラインはメモリ中で 連続であるものと仮定して bytes_per_line の値を計算する。

XCreateImage ,XGetImage ,XSubImageを使ってイメージを生成した場合、関数 XDestroyImageが呼び出すイメージ破棄の手続きはイメージ構造体とそれが指すデータの両方 を解放する点に注意すること。

ピクセルの取得、ピクセルの設定、サブイメージの生成、イメージへの 定数値追加に使われる基本関数はイメージオブジェクト内に定義される。 この章の関数は、実際にはイメージオブジェクト内の関数を呼び出すマクロで あり、 <X11/Xutil.h>で定義されている。

イメージ内のピクセル値を取得するには XGetPixelを使う。

unsigned long XGetPixel(ximage, x, y)
XImage *ximage;
int x;
int y;
ximage
イメージを指定する。
x

y
x, y 座標を指定する。

関数 XGetPixelは指定したイメージの指定した位置のピクセル値を返す。 返されるピクセル値は正規化されたフォーマットである(つまり long の最下位バイトがピクセルの最下位バイトとなる)。 イメージは x, y 座標を持っていなくてはならない。

イメージ内にピクセル値を設定するには XPutPixelを使う。

XPutPixel(ximage, x, y, pixel)
XImage *ximage;
int x;
int y;
unsigned long pixel;
ximage
イメージを指定する。
x

y
x, y 座標を指定する。
pixel
ピクセル値を指定する。

関数 XPutPixelは、指定したイメージ上のピクセルを指定したピクセル値で上書きする。 入力するピクセル値は正規化されたフォーマットでなくてはならない(つまり long の最下位バイトがピクセルの最下位バイトとなる)。 イメージは x, y 座標を持っていなくてはならない。

サブイメージを作るには XSubImageを使う。

XImage *XSubImage(ximage, x, y, subimage_width, subimage_height)
XImage *ximage;
int x;
int y;
unsigned int subimage_width;
unsigned int subimage_height;
ximage
イメージを指定する。
x

y
x, y 座標を指定する。
subimage_width
新しいサブイメージの幅をピクセル単位で指定する。
subimage_height
新しいサブイメージの高さをピクセル単位で指定する。

関数 XSubImageは、既存のイメージの一部分であるイメージを新しく作る。 この関数は新しい XImage構造体に必要なメモリを割り当て、新しいイメージへのポインタを返す。 データは元のイメージからコピーされる。 また、イメージは x, y, subimage_width, subimage_height を含まなくては ならない。

イメージ内の各ピクセル値を定数値だけ増加させるには XAddPixelを使う。

XAddPixel(ximage, value)
XImage *ximage;
long value;
ximage
イメージを指定する。
value
加算される定数を指定する。

関数 XAddPixelはイメージ内の全てのピクセル値に定数を加える。 この関数は、色リソースを割り当てて得たピクセル値を持っていて、 イメージをその形式にする必要があるときに便利である。

以前に XCreateImageを呼び出して割り当てたメモリを解放するには XDestroyImageを使う。

XDestroyImage(ximage)
XImage *ximage;
ximage
イメージを指定する。

関数 XDestroyImageは、 XImageに対応するメモリを解放する。

XCreateImage ,XGetImage ,XSubImageを使ってイメージを生成した場合、このマクロが呼び出すイメージ破棄の手続 きはイメージ構造体とそれが指すデータの両方を解放する点に注意すること。

ビットマップの操作

Xlib にはファイルからのビットマップの読み取り、ファイルへのビットマップ の書き込み、ビットマップの作成を行うための関数が用意されている。 この節ではクライアントのファイルシステムとビットマップのやりとりを行う 関数を説明する。このような関数を使うと、後の接続でビットマップ の再利用が可能になる(例えば、全く別のクライアントからの利用や、 別のディスプレイやサーバからの利用)。

X バージョン 11 のビットマップファイルのフォーマットは以下の通りである:

#define name_width width
#define name_height height
#define name_x_hot x
#define name_y_hot y
static unsigned char name_bits[] = { 0xNN,... }

サフィックス _x_hot, _y_hot で終わる変数の行は省略可能である。これらの 行が存在するのは、ビットマップに対してホットスポットが定義されている 場合だけだからである。 残りの変数に対する行は必須である。 ``unsigned'' の指定は省略可能である: つまり、_bits 配列の型は ``char'' でも ``unsigned char'' でもよい。 _bits 配列はビットマップが入るだけの大きさでなければならない。 ビットマップの基本単位は 8 である。

ファイルからビットマップを読み出してピックスマップに格納するには XReadBitmapFileを使う。

int XReadBitmapFile(display, d, filename, width_return, height_return, bitmap_return, x_hot_return,
y_hot_return)
Display *display;
Drawable d;
char *filename;
unsigned int *width_return, *height_return;
Pixmap *bitmap_return;
int *x_hot_return, *y_hot_return;
display
X サーバへの接続を指定する。
d
filename
スクリーンを指定するためのドロウアブルを指定する。 ファイル名の文字列の形式は OS に依存する。
width_return

height_return
読み込んだビットマップの幅と高さが返される。
bitmap_return
生成されたビットマップが返される。
x_hot_return

y_hot_return
ホットスポットの座標が返される。

関数 XReadBitmapFileはビットマップを含むファイルを読み込む。 ファイルは現在のロケールのエンコーディングに従って展開される。 標準フォーマット以外のファイルを読み込めるかどうかは実装に依存する。 ファイルを開くことができなかった場合、 XReadBitmapFileBitmapOpenFailedを返す。 ファイルを開くことはできたが、それが正しいビットマップデータでなかった 場合には BitmapFileInvalidが返される。 十分な作業領域を割り当てられなかった場合には BitmapNoMemoryが返される。 ファイルが読み込み可能で正しいデータであれば、 BitmapSuccessが返される。

XReadBitmapFile は、ファイルから読み込む際にビットマップの幅と高さを width_return と height_return に返す。 次に適切なサイズのピックスマップを生成し、ファイルからビットマップを読 み込んでこのピックスマップに格納し、このピックスマップを関数の引き数 bitmap に割り当てる。 この関数を呼び出したクライアントは、ビットマップを使い終わった後は XFreePixmapを使ってこれを解放しなければならない。 name_x_hot と name_y_hot が存在する場合、 XReadBitmapFileはこれらを x_hot_return と y_hot_return に返す。そうでない場合には -1,-1 を返す。

XReadBitmapFileはエラー BadAllocBadDrawableを起こすことがある。

ファイルからビットマップを読み込み、これをデータとして返すには XReadBitmapFileDataを使う。

int XReadBitmapFileData(filename, width_return, height_return, data_return, x_hot_return, y_hot_return)
char *filename;
unsigned int *width_return, *height_return;
unsigned char *data_return;
int *x_hot_return, *y_hot_return;
filename
使用するファイル名を指定する。 ファイル名の文字列の形式は OS に依存する。
width_return

height_return
読み込んだビットマップの幅と高さが返される。
data_return
ビットマップデータが返される。
x_hot_return

y_hot_return
ホットスポットの座標が返される。

関数 XReadBitmapFileDataXReadBitmapFileと同じようにビットマップを含むファイルを読み込むが、サーバ内に ピックスマップを生成せずに直接データを返す。 ビットマップのデータは data_return に返される。クライアントはこの データを使い終わった後は、 XFreeを使ってメモリを解放しなければならない。 ステータスと値が返される変数については XReadBitmapFileと同じである。

ピックスマップからファイルにビットマップを書き出すには XWriteBitmapFileを使う。

int XWriteBitmapFile(display, filename, bitmap, width, height, x_hot, y_hot)
Display *display;
char *filename;
Pixmap bitmap;
unsigned int width, height;
int x_hot, y_hot;
display
X サーバへの接続を指定する。
filename
使用するファイル名を指定する。 ファイル名の文字列の形式は OS に依存する。
bitmap
ビットマップを指定する。
width

height
幅と高さを指定する。
x_hot

y_hot
ファイル中にホットスポットを配置する座標を指定(存在しないときは -1, -1 を指定)。

関数 XWriteBitmapFileはビットマップを X バージョン 11 のフォーマットでファイルに書き出す。 出力ファイル内で使われるビットマップの名前は、ファイル名から ディレクトリ部分を取り除いたものから決められる。 ファイルは現在のロケールのエンコーディングで出力される。 書き込むファイルを開けなかった場合は、この関数は BitmapOpenFailedを返す。 十分なメモリを割り当てられなかった場合は、 XWriteBitmapFileBitmapNoMemoryを返す。 それ以外の場合、つまりエラーが起きなかった場合には、この関数は BitmapSuccessを返す。 x_hot と y_hot が -1, -1 でない場合、 XWriteBitmapFileはこれらをビットマップのホットスポット座標として出力する。

XWriteBitmapFileはエラー BadDrawable,BadMatchを起こすことがある。

ピックスマップを作成し、この中にビットマップ形式のデータを格納するには XCreatePixmapFromBitmapDataを使う。

Pixmap XCreatePixmapFromBitmapData(display, d, data, width, height, fg, bg, depth)
Display *display;
Drawable d;
char *data;
unsigned int width, height;
unsigned long fg, bg;
unsigned int depth;
display
X サーバへの接続を指定する。
d
data
スクリーンを指定するためのドロウアブルを指定する。
width

height
幅と高さを指定する。
fg

bg
使用する前景色と背景色のピクセル値を指定する。
depth
ピックスマップの深さを指定する。

関数 XCreatePixmapFromBitmapDataは与えられた深さのピックスマップを生成し、その後に XPutImageを使ってビットマップ形式のデータをこのピックスマップに書き込む。 この深さは、指定したドロウアブルに対応するスクリーンが対応していなけれ ばならない。対応していなければ、エラー BadMatchとなる。

XCreatePixmapFromBitmapDataはエラー BadAlloc ,BadMatchを起こすことがある。

XWriteBitmapFile で書き出したデータを、実行する度に読み込むのではなく直接プログラムに取り込むには XCreateBitmapFromDataを使う。

Pixmap XCreateBitmapFromData(display, d, data, width, height)
Display *display;
Drawable d;
char *data;
unsigned int width, height;
display
X サーバへの接続を指定する。
d
スクリーンを指定するためのドロウアブルを指定する。
data
ビットマップデータの場所を指定する。
width

height
幅と高さを指定する。

関数 XCreateBitmapFromDataを使うと、ビットマップを実行時にファイルから読み込むのではなく、 XWriteBitmapFileで書き出したビットマップファイル(X バージョン11形式のみ)を( #includeを使って) C のプログラム中に含めることができる。 次のプログラム例は gray というビットマップを作るものである。

#include "gray.bitmap"

Pixmap bitmap; bitmap = XCreateBitmapFromData(display, window, gray_bits, gray_width, gray_height);

十分な作業用メモリ領域を割り当てられなかった場合、 XCreateBitmapFromDataNoneを返す。 ビットマップを使い終わった後に XFreePixmapを使ってこれを解放するのはクライアントの責任である。

XCreateBitmapFromDataはエラー BadAlloc ,BadGCを起こすことがある。

コンテクストマネージャの使用

コンテクストマネージャは、プログラム内でデータを X のリソース ID (ほと んどの場合はウィンドウ)に関連付ける機能を提供する。 これはプログラム内でローカルな関連付けである点に注意すること。 つまり、このデータはサーバのプロパティリストには格納されない。 データは数や大きさを問わずにリソース ID に関連付けでき、データのそれぞ れには型を関連付けることができる。 コンテクストマネージャは、取得するデータのリソース ID と型を知っている 必要がある。

本質的には、コンテクストマネージャは 2 次元の素なマトリクスと見ること ができる。1 つの次元の添字は X のリソース ID であり、もう 1 つの次元の 添字はコンテクストの型フィールドである。 配列の各要素はデータを指すポインタである。 Xlib にはコンテクスト管理関数が用意されている。これらの関数を用いると、 データの保存、データの取得、エントリの削除、ユニークな コンテクスト型の作成を行える。 使われるシンボルは <X11/Xutil.h>で定義されている。

リソース ID とコンテクスト型に対応するデータ値を保存するには XSaveContextを使う。

int XSaveContext(display, rid, context, data)
Display *display;
XID rid;
XContext context;
XPointer data;
display
X サーバへの接続を指定する。
rid
データが関連づけられるリソースIDを指定する。
context
データが属するコンテクスト型を指定する。
data
ウィンドウと型に関連づけられるデータを指定する。

指定したリソースIDと型に対するエントリーが既に存在する場合、 XSaveContextは指定したコンテクストでこのエントリーを上書きする。 関数 XSaveContextはエラーが起きた場合には 0 でないエラーコードを返し、そうでなければ 0 を返す。 起こる可能性があるエラーは XCNOMEM(メモリ不足)である。

リソース ID と型に対応するデータを取得するには XFindContextを使う。

int XFindContext(display, rid, context, data_return)
Display *display;
XID rid;
XContext context;
XPointer *data_return;
display
X サーバへの接続を指定する。
rid
データが関連づけられるリソースIDを指定する。
context
データが属するコンテクスト型を指定する。
data_return
データが返される。

これは返り値であるので、データはポインタである。 関数 XFindContextはエラーが起きた場合には 0 でないエラーコードを返し、そうでなければ 0 を返す。 起こる可能性があるエラーは XCNOENT(コンテクストが見つからない)である。

指定されたリソース ID と型に対応するエントリを削除するには XDeleteContextを使う。

int XDeleteContext(display, rid, context)
Display *display;
XID rid;
XContext context;
display
X サーバへの接続を指定する。
rid
データが関連づけられるリソースIDを指定する。
context
データが属するコンテクスト型を指定する。

関数 XDeleteContextは、与えられたリソースIDと型に対するエントリーを構造体から削除する。 この関数は、 XFindContextと同じ引き数を与えられた場合、同じエラーコードを返す。 XDeleteContextはアドレスが保存されているデータの解放は行わない。

後に XSaveContextXFindContextで使えるユニークなコンテクスト型を作成するには XUniqueContextを使う。

XContext XUniqueContext()


目次に戻る