リソースマネージャは少し変わった形のデータベースマネージャである。 ほとんどのデータベースシステムでは、不正確な指定を使った問い合わせを行 うとレコードの集合が返ってくる。 しかしリソースマネージャの場合は、正確な指定をデータベースに問い合わせ を行うためや、1 つだけに絞られた値を得るために不正確な値を大量に指定で きる。 色、フォントなどのリソースについてユーザの希望を知る必要があるアプリケー ションはこの機能を使うべきである。 「リソースマネージャ」という名前の由来になっているのは、このような X のリソース用のデータベースとしての使い方である。ただし、リソースマネージャ は他の使い方も可能である。
例えば、ユーザは全てのウィンドウの背景色を青色にするが、メールを読む アプリケーションのウィンドウだけは背景色を赤色にしたいと考えるかもしれ ない。 うまく設計、調整されたアプリケーション群であれば、ユーザは 2 行指定す るだけでこの情報を定義できる。
リソースマネージャの動作の例として、xmh というメールを読むための アプリケーションを考える。 このアプリケーションがトップウィンドウから個々のコマンドボタンに至るま で複雑なウィンドウ階層を持つように設計されているものとする。 ツールキットによっては、コマンドボタンも実際に小さなサブウィンドウであ る場合もある。 これらはよく「オブジェクト」や「ウィジェット」と呼ばれる。 このようなツールキットシステムでは、各ユーザインタフェースオブジェクト は他のオブジェクトを組み立てて作ることができ、名前とクラスを割り当てる ことができる。 完全に制限された名前とクラスは任意の数の要素名を持てるが、 完全に制限された名前の数は必ず、完全に制限されたクラスの名前の要素数と 同じである。 一般的に名前やクラスの構成は、これらのオブジェクトを使って組み立てた アプリケーションの構造を反映している。また名前はアプリケーション名から 始まる。
例えば、xmh というメールプログラムは ``xmh'' という名前を持ち、 ``Mail'' プログラムのクラスの一つである。 慣習的に、クラス要素の最初の文字は大文字にし、名前要素の最初の文字は 小文字にする。 名前とクラスの最後はそれぞれ属性となる(例えば ``foreground'' や ``font'')。 各ウィンドウに適切な名前とクラスが割り当てられていれば、アプリケーション の任意の部分の属性をユーザが変更することは容易である。
トップレベルでは、このアプリケーションは ``toc'' という名前の paned ウィンドウ(つまり複数の部分に分割されたウィンドウ)で作られている。 paned ウィンドウ内の 1 つの pane は ``buttons'' という名前のボタン ボックスウィンドウであり、その中にはコマンドボタンが詰め込まれている。 これらのコマンドボタンの 1 つは新着メールを取り込むためのボタンであり、 ``incorporate'' という名前が付いている。 このウィンドウは完全に制限された名前 ``xmh.toc.buttons.incorporate'' と完全に制限されたクラス ``Xmh.Paned.Box.Command'' を持っている。 この完全に指定された名前は、親の名前である ``xmh.toc.buttons'' の後に 自分の名前である ``incorporate'' を追加したものである。 このウィンドウのクラスは親のクラスである ``Xmh.Paned.Box'' に固有の クラスである ``Command'' を追加したものである。 あるリソースの完全に制限された名前は、オブジェクトの完全に制限された 名前に属性の名前を追加したものであり、完全に制限されたクラスは オブジェクトのクラスに自分自身のクラスを追加したものである。
incorporate ボタンに必要なリソースとしては以下が考えられる: タイトル文字列、 フォント、 非アクティブ状態の時の前景色、 非アクティブ状態の時の背景色、 アクティブ状態の時の前景色、 アクティブ状態の時の背景色。 それぞれのリソースはボタンの属性と考えられ、それに合った名前とクラスを 持っている。 例えばアクティブ状態時のボタンの前景色は ``activeForeground'' という 名前を持ち、``Foreground'' というクラスになる。
アプリケーションがリソース(例えば色など)を参照した時には、参照ルーチン にはリソースの完全な名前と完全なクラスが渡される。 リソースマネージャはこの完全な指定をリソースデータベース内にある 不完全なエントリと比べて一番マッチするものを見つけ、そのエントリに対応 する値を返す。
リソースマネージャのための定義は <X11/Xresource.h>に含まれている。
リソースファイルの書式は、改行かファイル末尾で終わるリソース行の列であ る。 個別のリソースについての文法は以下の通りである:
ResourceLine = Comment | IncludeFile | ResourceSpec | <空行> Comment = "!" {<NULL 文字と改行文字以外の任意の文字>} IncludeFile = "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace FileName = <OS にとって有効なファイル名> ResourceSpec = WhiteSpace ResourceName WhiteSpace ":" WhiteSpace Value ResourceName = [Binding] {Component Binding} ComponentName Binding = "." | "*" WhiteSpace = {<空白文字> | <水平タブ>} Component = "?" | ComponentName ComponentName = NameChar {NameChar} NameChar = "a"-"z" | "A"-"Z" | "0"-"9" | "_" | "-" Value = {<NULL 文字と改行文字以外の任意の文字>}
垂直バー(|)で区切られた要素は、どれか 1 つを選ぶことを示す。 中括弧({...})は、括弧で括られた要素の 0 回以上のくり返しを示す。 大括弧([...])は、括弧で括られた要素がなくてもよいことを示す。 クォート("...")は、リテラル文字の前後で用いられる。
IncludeFile 行は、指定したファイルの内容でその行を置き換えることと解釈 される。 ``include'' の語は小文字でなければならない。 ファイル名は、その行が現われたファイルのディレクトリに対して相対的に解 釈される(例えば、ファイル名がディレクトリを含まない場合や相対ディレク トリ指定を含む場合)。
ResourceName が2つ以上の Binding を連続して含む場合、このシーケンスが ``.'' しか含まないならば、このシーケンスは 1 つの``.'' 文字で置き換 えられる。 そうでない場合、このシーケンスは 1 つの ``*'' 文字に置き換えられる。
リソースデータベースは、与えられた ResourceName に対して 1 つより多くの エントリーを含むことは決してない。リソースファイルが同じ ResourceName について複数の行を含む場合、ファイル中で後に現われた方が用いられる。
ResourceSpec では、名前やコロンの後の空白文字は全て無視される。 Value を空白で始めることができるように、2 文字からなるシーケンス ``\\space''(スペースの前にバックスラッシュがある)は、1 つの 空白として得認識され、``\\tab''(水平タブの前にバックスラッシュ がある)は、1 つの水平タブ文字として認識される。 途中に改行文字を含む Value が使えるように、2 文字からなるシーケンス ``\\n'' は 1 つの改行文字として認識される。 テキストファイル中で複数行にまたがる Value が使えるように、2 文字からな るシーケンス ``\\newline'' (改行の前にバックスラッシュ)は、 Valuse から取り除かれる。 任意の文字コードが使えるように、4 文字からなるシーケンス ``\\nnn'' は、シーケンスで指定された 8 進数の値を含む 1 つの バイトデータに置き換えられる。ここで、それぞれの n は範囲が ``0''-``7'' である数字である。 最後に、2 文字からなるシーケンス ``\\\\'' は、1 つのバックスラッシュに 置き換えられる。
このシーケンスの例であるが、以下のリソース行は 4 つの文字( バックスラッシュ、NULL, ``z'', 改行)を含んでいる:
magic.values: \\\\\\000\ z\\n
与えられた問い合わせにマッチするリソースデータベースのエントリを決定す るアルゴリズムは、リソースマネージャの中心部分である。 どんな問い合わせの場合でも、必要なリソースの名前とクラスを完全に指定し なければならない(文字 ``*''と ``?'' の使用は許されない)。 Xlib では、コンポーネント内で完全な名前とクラスを 100 個まで使用できる。 リソースは、パターンマッチングの組み合わせを使用して、一部だけ指定された名前 とクラスでデータベースに格納される。 アスタリスク(*)は緩い結合であり、任意の数のコンポーネントが間に入るこ とを表現するために使われる。これは、間にコンポーネントが全く入らないこ とを含む。 ピリオド(.)は強い結合であり、隣接するコンポーネント同士を分割するため に使われる。 疑問符(?)は、任意の名前かクラス 1 つにマッチさせるために使われる。 データベースのエントリーは、緩い結合で終えることはできない。 最後のコンポーネント(``?'' であってはならない)は必ず指定しなければならない。 検索アルゴリズムは、問い合わせられた完全な名前とクラスに最も近くマッチ する(最も明確である)エントリーについてデータベースを検索する。 データベース内の複数のエントリーが完全な名前とクラスにマッチした場合は、 1 つだけを選ぶために優先順位の規則が用いられる。
完全な名前とクラスのコンポーネントは、左から右へ(最も高いレベルから低 いレベルへ)向かって、一度に 1 つずつ調べられる。 各レベルでは、対応するコンポーネントかマッチするそれぞれのエントリーの 結合あるいはその両方が決定され、マッチしたコンポーネントや結合は優先順 位の規則に基づいて比較される。 全ての中から 1 つのエントリーが規則によって決まるまで、次のレベルに移動 する前に、規則の各項目がそれぞれのレベルに適用される。 このルールを優先度の順に示す。
この規則の例を示すために、以下のようなリソースデータベースのエントリを 考える:
xmh*Paned*activeForeground: red (エントリ A) *incorporate.Foreground: blue (エントリ B) xmh.toc*Command*activeForeground: green (エントリ C) xmh.toc*?.Foreground: white (エントリ D) xmh.toc*Command.activeForeground: black (エントリ E)
この時、以下のようなリソースの問い合わせを考える:
xmh.toc.messagefunctions.incorporate.activeForeground (name) Xmh.Paned.Box.Command.Foreground (class)
最初のレベル(xmh, Xmh)では、規則 1 によりエントリ B が消される。 2 番目のレベル(toc, Paned)では、規則 2 によりエントリ A が消される。 3 番目のレベル(messagefunctions, Box)では消されるエントリはない。 4 番目のレベル(incorporate, Command)では、規則 2 によりエントリ D が消 される。 5 番目のレベル(activeForeground, Foreground)では、規則 3 により エントリ C が消される。
リソースマネージャの利用の大部分は、名前、クラス、表現型を 文字列定数として定義することである。 しかし、常にリソースマネージャ内の文字列を参照すると遅くなってしまうか もしれない。なぜならツールキットによってはこのような文字列を多用するか らである。 この問題を解決するため、リソースマネージャのための関数の多くでは、 文字列の代わりに文字列を省略して用いる。 すると文字列の比較の代わりに単純な比較を実行できる。 文字列の省略名はクォークと呼ばれ、 XrmQuark 方を持つ。 場合によっては、対応する文字列を持たないクォークを割り当ててもよい。
文字列に対するクォークの関係は、サーバ内の文字列に対するアトムの関係と 同じである。ただし、クォークはアプリケーション内で完全にローカルに使わ れる。
新しいクォークを割り当てるには XrmUniqueQuarkを使う。
XrmQuark XrmUniqueQuark( )
関数 XrmUniqueQuarkは、リソースマネージャが認識しているどの文字列も表さないことが保証され るクォークを割り当てる。
それぞれの名前、クラス、表現型は XrmQuarkとして typedef されている。
typedef int XrmQuark, *XrmQuarkList; typedef XrmQuark XrmName; typedef XrmQuark XrmClass; typedef XrmQuark XrmRepresentation; #define NULLQUARK ((XrmQuark) 0)
リストはクォークの NULL で終わる配列として表現される。 配列の大きさは使用するコンポーネントの数に対して十分でなければならない。
typedef XrmQuarkList XrmNameList; typedef XrmQuarkList XrmClassList;
文字列をクォークに変換するには XrmStringToQuarkまたは XrmPermStringToQuarkを使う。
#define XrmStringToName(string) XrmStringToQuark(string) #define XrmStringToClass(string) XrmStringToQuark(string) #define XrmStringToRepresentation(string) XrmStringToQuark(string)XrmQuark XrmStringToQuark(string)
char *string;XrmQuark XrmPermStringToQuark(string)
char *string;
これらの関数は、文字列をクォーク表現に変換するために使うことができる。 文字列のエンコーディングがホストポータブル文字エンコーディングでない場 合、変換の動作は実装に依存する。 XrmStringToQuarkに渡す引き数 string は、ずっと割り当てられたままの領域である必要はない。 関数 XrmPermStringToQuarkは XrmStringToQuarkとほぼ同じであるが、引き数 string が割り当てられたままの領域で あることを Xlib が想定してもよい点が異なる。したがって、引き数 string は XrmQuarkToStringが返す値として使うことができる。
- string
- 割り当てられるクォークかクォークのリストに対する文字列を指定する。
与えられたクォークについて、 XrmStringToQuarkが NULL でない値を返した場合、それ以降の全ての関数呼び出しに対して同じ 値(同一のアドレス)が返される。
クォークを文字列に変換するには XrmQuarkToString を使う。
#define XrmNameToString(name) XrmQuarkToString(name) #define XrmClassToString(class) XrmQuarkToString(class) #define XrmRepresentationToString(type) XrmQuarkToString(type)char *XrmQuarkToString(quark)
XrmQuark quark;
これらの関数は、クォーク表現を文字列に変換するために使うことができる。 関数の返り値が指す文字列の変更や解放を行ってはならない。 返される文字列は、文字列をクォークに変換する関数に渡された元の文字列 とバイトのレベルで等しい。 そのクォークに対する文字列が存在しない場合、 XrmQuarkToStringは NULL を返す。 与えられたクォークに対して XrmQuarkToStringが NULL でない値を返した場合、それ以降の全ての関数呼び出しに対して同じ 値(同一のアドレス)が返される。
- quark
- 等価な文字列を求める対象であるクォークを指定する。
1 つ以上のコンポーネントを持つ文字列をクォークのリストに変換するには XrmStringToQuarkListを使う。
#define XrmStringToNameList(str, name) XrmStringToQuarkList((str), (name)) #define XrmStringToClassList(str, class) XrmStringToQuarkList((str), (class))void XrmStringToQuarkList(string, quarks_return)
char *string;
XrmQuarkList quarks_return;
関数 XrmStringToQuarkListは NULL で終わる文字列(一般的には完全に限定された名前)をクォークのリス トに変換する。 この文字列は有効な ResourceName 形式でなければならない(15.1 節を参照)。 この文字列のエンコーディングがホストポータブル文字エンコーディングでな い場合、変換の動作は実装依存である。
- string
- 割り当てられるクォークかクォークのリストに対する文字列を指定する。
- quarks_return
- クォークのリストが返される。
割り当てリストは、 XrmBindingList型であり、クラスや名前のリストの要素が強くあるいは緩く関連づけされてい る(つまり、ワールドカードを使った中間要素が指定されている)ことを示す。
typedef enum {XrmBindTightly, XrmBindLoosely} XrmBinding, *XrmBindingList;
XrmBindTightlyは、ピリオドが要素を区切っていること示す。また、 XrmBindLooselyは、アスタリスクが要素を区切っていることを示す。
1 つ以上のコンポーネントを持つ文字列を割り当てリストとクォークのリスト に変換するには XrmStringToBindingQuarkListを使う。
XrmStringToBindingQuarkList(string, bindings_return, quarks_return)
char *string;
XrmBindingList bindings_return;
XrmQuarkList quarks_return;
リストが含む要素名は、ピリオドかアスタリスクで区切られている。 この文字列は正しい ResourceName 形式(15.1 節を参照)でなければならない。 文字列の最初の文字がピリオドかアスタリスクではない場合は、強い結合とし て扱われる。 例えば ``*a.b*c'' は次のようになる:
- string
- 割り当てられるクォークかクォークのリストに対する文字列を指定する。
- bindings_return
- 割り当てリストが返される。 呼び出し側は XrmStringToBindingQuarkListを呼び出す前に割り当てリストを十分格納できる領域を割り当てなければなら ない。
- quarks_return
- クォークのリストが返される。 呼び出し側は XrmStringToBindingQuarkListを呼び出す前にクォークのリストを十分格納できる領域を割り当てなければなら ない。
クォーク a b c 結び付き 緩い 強い 緩い
リソースデータベースは opaque な型 XrmDatabase を持つ。 データベースのそれぞれの値は XrmValue 構造体に格納される。 この構造体は大きさ、アドレス、表現型からなる。 大きさはバイト単位で指定される。 表現型はアプリケーションで定義した何らかの型(例えば ``font'' や ``color'' のような文字列)のタグが付いたデータを持つための方法である。 これは C のデータ型やクラスとは何の関係もない。 XrmValue 構造体の定義を以下に示す:
typedef struct { unsigned int size; XPointer addr; } XrmValue, *XrmValuePtr;
リソースマネージャを初期化するには XrmInitializeを使う。
void XrmInitialize( );
データベースをディスクから取り込むには XrmGetFileDatabaseを使う。
XrmDatabase XrmGetFileDatabase(filename)
char *filename;
関数 XrmGetFileDatabaseは指定されたファイルをオープンし、新しいリソースデータベースを作成し、 指定されたファイルから読み込んだ仕様を使ってデータベースをロードする。 指定されたファイルは、有効なリソース行形式(15.1 節を参照)のエントリーの列 を持たなければならない。文法的に誤りのあるファイルを読んだ結果として得 られるデータベースは実装依存である。 このファイルは現在のロケールで展開され、データベースは現在のロケールで 作成される。 指定されたファイルをオープンできない場合、 XrmGetFileDatabaseは NULL を返す。
- filename
- リソースデータベースのファイル名を指定する。
データベースのコピーをディスクに格納するには XrmPutFileDatabaseを使う。
void XrmPutFileDatabase(database, stored_db)
XrmDatabase database;
char *stored_db;
関数 XrmPutFileDatabaseは、指定されたデータベースのコピーを指定されたファイルに格納する。 テキストは有効なリソース行形式(15.1 節参照)のエントリーの列として ファイルに書かれる。 ファイルはデータベースのロケールで書かれる。 エンコーディングがホストポータブル文字エンコーディングでないリソース名 を持つエントリーや、データベースのロケールのエンコーディングでない値を 持つエントリーは、実装依存の方法で出力される。 エントリーが書かれる順序は実装依存である。
- database
- 使用するデータベースを指定する。
- stored_db
- データベースが格納されるファイル名を指定する。
スクリーンに依存しないディスプレイのリソースを指すポインタを得るには XResourceManagerStringを使う。
char *XResourceManagerString(display)
Display *display;
関数 XResourceManagerStringは、サーバのスクリーン 0 のルートウィンドウから取得した RESOURCE_MANAGER プロパティを返す。これは XOpenDisplayで接続をオープンした時に返された値である。 プロパティは STRING 型から現在のロケールに変換される。 この変換は、単独要素の STRING プロパティに対して XmbTextPropertyToTextListが行うものと全く同じである。 返される文字列は Xlib が所有しているので、クライアントはこれを解放して はならない。 プロパティ値は XrmGetStringDatabaseが受け取ることのできるフォーマットでなくてはならない。 プロパティが存在しない場合には NULL が返される。
- display
- X サーバへの接続を指定する。
スクリーン固有のリソースを指すポインタを得るには XScreenResourceString を使う。
char *XScreenResourceString(screen)
Screen *screen;
関数 XScreenResourceStringは、指定したスクリーンのルートウィンドウから取得した SCREEN_RESOURCES プロパティを返す。 このプロパティは STRING 型から現在のロケールに変換される。 この変換は、単独要素の STRING プロパティに対して XmbTextPropertyToTextListが行うものと全く同じである。 プロパティ値は XrmGetStringDatabaseが受け取ることのできるフォーマットでなくてはならない。 プロパティが存在しない場合には NULL が返される。 関数の呼び出し側は XFreeを使って返された文字列を解放する責任を負う。
- screen
- スクリーンを指定する。
文字列からデータベースを作成するには XrmGetStringDatabaseを使う。
XrmDatabase XrmGetStringDatabase(data)
char *data;
関数 XrmGetStringDatabaseは、新しいデータベースを生成し、NULL で終わる指定された文字列で指定さ れたリソースを格納する。 XrmGetStringDatabaseは XrmGetFileDatabaseと似ているが、ファイルからの情報ではなく文字列からの情報を読む点が異な る。 文字列は、有効なリソース行形式(15.1 節参照)のエントリー列を持たなくては ならない。また、この文字列は NULL で終わる。 文法的に誤りのある文字列を用いた結果のデータベースは実装依存である。 文字列は現在のロケールで展開され、データベースは現在のロケールで生成さ れる。
- data
- 文字列を使ってデータベースの内容を指定する。
データベースのロケール名を取得するには XrmLocaleOfDatabaseを使う。
char *XrmLocaleOfDatabase(database)
XrmDatabase database;
関数 XrmLocaleOfDatabaseは、指定したデータベースに関連づけられたロケールの名前を返す。これは NULL で終わる文字列である。 返されたロケール名文字列は Xlib が所有しているので、クライアントは変更 や解放をしてはならない。 データベースが破棄されるまで、Xlib はこの文字列を解放してはならない。 文字列は解放されるまで Xlib によって変更されることはない。
- database
- リソースデータベースを指定する。
リソースデータベースを破棄し、これに割り当てられていたメモリを解放する には XrmDestroyDatabaseを使う。
void XrmDestroyDatabase(database)
XrmDatabase database;
データベースが NULL ならば、 XrmDestroyDatabaseはすぐに復帰する。
- database
- リソースデータベースを指定する。
リソースデータベースとディスプレイを関連付けるには XrmSetDatabaseを使う。
void XrmSetDatabase(display, database)
Display *display;
XrmDatabase database;
関数 XrmSetDatabaseは、指定したデータベース(あるいは NULL)を指定したディスプレイに関連づ ける。 以前にこのディスプレイに関連づけされたデータベースは(もしあっても)破棄 されない。 クライアントやツールキットにとって、この関数は一度生成したデータベース を保持するために便利だと思われる。
- display
- X サーバへの接続を指定する。
- database
- リソースデータベースを指定する。
ディスプレイに関連付けられたデータベースを取得するには XrmGetDatabaseを使う。
XrmDatabase XrmGetDatabase(display)
Display *display;
関数 XrmGetDatabaseは、指定したディスプレイに関連づけされたデータベースを返す。 データベースがまだ設定されていない場合は、この関数は NULL を返す。
- display
- X サーバへの接続を指定する。
リソースファイルの内容をデータベースにマージするには XrmCombineFileDatabaseを使う。
Status XrmCombineFileDatabase(filename, target_db, override)
char *filename;
XrmDatabase *target_db;
Bool override;
関数 XrmCombineFileDatabaseは、リソースファイルの内容をデータベースにマージする。 あるエントリーについて、ファイルとデータベースが同じ指示子を用いている 場合、引き数 override が Trueならば、データベースのエントリーはファイルのエントリーに置き換えられる。 そうでない場合、ファイルのエントリーは破棄される。 ファイルは現在のロケールで展開される。 ファイルを読み込むことができない場合、ステータスとして 0 が返される。 そうでない場合には、0 でないステータスが返される。 target_db が NULL の場合、 XrmCombineFileDatabaseは新しいデータベースを作成して target_db に対して返す。 そうでない場合、target_db が指すデータベースはマージによって破棄される ことはない。 データベースのロケールに関係なく、データベースのエントリーの値や型は変 更されることなくマージされる。 マージ先のデータベースのロケールは変更されない。
- filename
- リソースデータベースのファイル名を指定する。
- target_db
- 元のデータベースがマージされる先のリソースデータベースを指定する。
- override
- マージ元のエントリーがマージ先のエントリーを上書きするかどうかを指定する。
あるデータベースの内容を他のデータベースにマージするには XrmCombineDatabaseを使う。
void XrmCombineDatabase(source_db, target_db, override)
XrmDatabase source_db, *target_db;
Bool override;
関数 XrmCombineDatabaseは、あるデータベースの内容を他のデータベースにマージする。 あるエントリーについて、2つのデータベースが同じ指示子を用いている場合、 引き数 override が Trueならば、target_db のエントリーは source_db のエントリーに置き換えられる。 そうでない場合、source_db のエントリーは破棄される。 target_db が NULL の場合、 XrmCombineDatabaseは単に source_db の内容を target_db に格納する。 そうでない場合、source_db はマージによって破壊されるが、target_db が指 すデータベースは破壊されない。 データベースそれぞれのロケールに関係なく、データベースは値やタイプの変 更をすることなくマージされる。 マージ先のデータベースのロケールは変更されない。
- source_db
- 対象となるデータベースにマージされるリソースデータベースを指定する。
- target_db
- 元のデータベースがマージされる先のリソースデータベースを指定する。
- override
- マージ元のエントリーがマージ先のエントリーを上書きするかどうかを指定する。
あるデータベースを別のデータベースに対して上書きのセマンティクスで マージするには XrmMergeDatabasesを使う。
void XrmMergeDatabases(source_db, target_db)
XrmDatabase source_db, *target_db;
関数 XrmMergeDatabasesを呼ぶことは、引き数 override に Trueを指定して関数 XrmCombineDatabaseを呼ぶことと等価である。
- source_db
- 対象となるデータベースにマージされるリソースデータベースを指定する。
- target_db
- 元のデータベースがマージされる先のリソースデータベースを指定する。
リソースデータベースからリソースを取り込むには XrmGetResource ,XrmQGetResource ,XrmQGetSearchResourceのいずれかを使う。
Bool XrmGetResource(database, str_name, str_class, str_type_return, value_return)
XrmDatabase database;
char *str_name;
char *str_class;
char **str_type_return;
XrmValue *value_return;
- database
- 使われるデータベースを指定する。
- str_name
- 取り出す値の完全に限定された名前を(文字列として)指定する。
- str_class
- 取り出す値の完全に限定されたクラスを(クォークとして)指定する。
- str_type_return
- 対象の表現型が(文字列として)返される。
- value_return
- データベース内での値が返される。
Bool XrmQGetResource(database, quark_name, quark_class, quark_type_return, value_return)
XrmDatabase database;
XrmNameList quark_name;
XrmClassList quark_class;
XrmRepresentation *quark_type_return;
XrmValue *value_return;
関数 XrmGetResource と XrmQGetResource は、指定したデータベースからリソースを取り出す。 どちらの関数も完全に限定された名前/クラスの組、目的のリソース表現、値 のアドレス(サイズ/アドレスの組)を引き数として取る。 値と返される型はデータベースのメモリを指す。 したがって、このデータを変更してはならない。
- database
- 使われるデータベースを指定する。
- quark_name
- 取り出す値の完全に限定された名前を(クォークとして)指定する。
- quark_class
- 取り出す値の完全に限定されたクラスを(クォークとして)指定する。
- quark_type_return
- 対象の表現型が(クォークとして)返される。
- value_return
- データベース内での値が返される。
データベースは XrmPutResource , XrmQPutResource ,XrmMergeDatabasesのいずれかのエントリーの解放または上書きだけを行う。 新しい値をデータベースに格納しないクライアントやデータベースのマージ をしないクライアントは、返されたアドレスが存在する限り、これをいつ使っ ても安全である。 XrmGetResource と XrmQGetResource のどちらもリソースが見つかった場合には Trueを返す。 見つからなかった場合には Falseが返される。
ほとんどのアプリケーションやツールキットは、リソースを取得するために リソースデータベースの中をランダムに検索したりはしない。 X ツールキットがリソースデータベースをアクセスする時のパターンはかなり 決まっている。 1 つ目から 20 個目までの検索では、検索ごとに最後の名前/クラスの部分だ けが変えられる。 関数 XrmGetResource は最悪ケースでは %2 sup n% のアルゴリズムを使っている。 ここで n は名前/クラスのリストの長さである。 この問題は、名前/クラスのリストの最初の部分がマッチするデータベースの リストのレベルをアプリケーションプログラマが予め取得しておくことによっ て改善できる。
データベースのリストのレベルを取得するには XrmQGetSearchListを使う。
typedef XrmHashTable *XrmSearchList;Bool XrmQGetSearchList(database, names, classes, list_return, list_length)
XrmDatabase database;
XrmNameList names;
XrmClassList classes;
XrmSearchList list_return;
int list_length;
関数 XrmQGetSearchListは、名前とクラスのリストを引き数に取り、マッチが起こったと思われるデータ ベースのレベルのリストを返す。 返されるリストは最善から最悪の順で並んでおり、順位を決定するアルゴリズ ムは XrmGetResource と同じである。 list_return が検索リストを格納できる十分な大きさならば、 XrmQGetSearchListは Trueを返し、そうでなければ Falseを返す。
- database
- 使われるデータベースを指定する。
- names
- リソース名のリストを指定する。
- classes
- リソースクラスのリストを指定する。
- list_return
- 後で使用するための検索リストが返される。 呼出側は XrmQGetSearchListを呼び出す前にはリストが十分入るだけのメモリを割り当てていなければなら ない。
- list_length
- list_return に対して割り当てられたエントリーの数(バイト数ではない)を 指定する。
関数を呼び出した側が割り当てなければならない検索リストの大きさは、 データベースに格納されているリソース指定子が含むレベル数とワイルドカー ドの数によって決まる。 最悪の場合には、この大きさは %3 sup n% である。 ここで、 n は名前やクラスが含んでいる名前やクラスのコンポーネン トの数である。
最初に XrmQGetSearchList を用い、その後に共通の名前とクラスのプレフィックスを使って複数回リソース を検索する場合には、 XrmQGetSearchListに渡す名前やクラスのリスト中では共通のプレフィクスだけを指定すべきである。
与えられたリソースについてリソースデータベースのレベルを検索するには XrmQGetSearchResourceを使う。
Bool XrmQGetSearchResource(list, name, class, type_return, value_return)
XrmSearchList list;
XrmName name;
XrmClass class;
XrmRepresentation *type_return;
XrmValue *value_return;
関数 XrmQGetSearchResourceは、指定した名前とクラスで完全に識別されているリソースに対して、指定し たデータベースのレベルを検索する。 検索は最初にマッチした時点で終了する。 XrmQGetSearchResourceはリソースが見つかった場合には True を返し、 見つからなかった場合には Falseを返す。
- list
- XrmQGetSearchListが返す検索リストを指定する。
- name
- リソース名を指定する。
- class
- リソースクラスを指定する。
- type_return
- データの表現型が返される。
- value_return
- データベース内での値が返される。
リソース名の最後のコンポーネント以外の全てを含む名前とクラスのリストを 使って XrmQGetSearchListを呼び出し、続いて 最後のコンポーネントである名前とクラスを使って XrmQGetSearchResource を呼び出すと、完全に限定された名前とクラスを使って XrmGetResource と XrmQGetResource を呼び出した場合と同じデータベースのエントリーが返される。
リソースをデータベースに格納するには XrmPutResource または XrmQPutResourceを使う。 どちらの関数も部分的なリソース指定、表現型、値を引き数に取る。
void XrmPutResource(database, specifier, type, value)
XrmDatabase *database;
char *specifier;
char *type;
XrmValue *value;
引き数 databaseが NULL の場合、 XrmPutResourceは新しいデータベースを生成し、それを指すポインタを返す。 XrmPutResourceは XrmStringToBindingQuarkListを呼び、そして以下の関数を呼び出す簡易関数である。
- database
- リソースデータベースを指定する。
- specifier
- リソースの完全あるいは部分的な指示を指定する。
- type
- リソースの型を指定する。
- value
- リソースの値を指定する。これは文字列として指定する。
XrmQPutResource(database, bindings, quarks, XrmStringToQuark(type), value)引き数 specifier と type のエンコーディングがホストポータブル文字エン コーディングでない場合、結果は実装依存である。 引き数 value は変更されることなくデータベースに格納される。
void XrmQPutResource(database, bindings, quarks, type, value)
XrmDatabase *database;
XrmBindingList bindings;
XrmQuarkList quarks;
XrmRepresentation type;
XrmValue *value;
引き数 database が NULL の場合、 XrmQPutResourceは新しいデータベースを生成し、それを指すポインタを返す。 同一の結合とクォークを持つリソースエントリーがデータベース内に存在 する場合、前の型と値は指定された新しい型と値に置き換えられる。 引き数 value は変更されることなくデータベースに格納される。
- database
- リソースデータベースを指定する。
- bindings
- 割り当てのリストを指定する。
- quarks
- リソースの名前あるいはクラスのリストを指定する。このクラスや名前は完全な場 合と部分的な場合がある。
- type
- リソースの型を指定する。
- value
- リソースの値を指定する。これは文字列として指定する。
文字列として指定されたリソースを追加するには XrmPutStringResourceを使う。
void XrmPutStringResource(database, specifier, value)
XrmDatabase *database;
char *specifier;
char *value;
引き数 database が NULL の場合、 XrmPutStringResourceは新しいデータベースを生成し、それを指すポインタを返す。 XrmPutStringResourceは、指定された値を持つリソースを指定されたデータベースに追加する。 XrmPutStringResourceは簡易関数である。 この動作としては、まず指定した specifier について XrmStringToBindingQuarkListを呼び、次に ``String'' 表現型を用いて XrmQPutResourceを呼ぶ。 specifier のエンコーディングがホストポータブル文字エンコーディングでな い場合、結果は実装依存である。 引き数 value は変更されることなくデータベースに格納される。
- database
- リソースデータベースを指定する。
- specifier
- リソースの完全あるいは部分的な指示を指定する。
- value
- リソースの値を指定する。これは文字列として指定する。
クォークを指定として使っている文字列リソースを追加するには XrmQPutStringResourceを使う。
void XrmQPutStringResource(database, bindings, quarks, value)
XrmDatabase *database;
XrmBindingList bindings;
XrmQuarkList quarks;
char *value;
引き数 database が NULL の場合、 XrmQPutStringResourceは新しいデータベースを生成し、それを指すポインタを返す。 XrmQPutStringResourceは簡易関数である。 その動作としては、まず value 文字列に対して XrmValueを作り(サイズを計算するために strlenを呼ぶ)、次に ``String'' 表現型を用いて XrmQPutResourceを呼び出す。 引き数 value は変更されることなくデータベースに格納される。
- database
- リソースデータベースを指定する。
- bindings
- 結合のリストを指定する。
- quarks
- リソースの名前あるいはクラスのリストを指定する。このクラスや名前は完全な場 合と部分的な場合がある。
- value
- リソースの値を指定する。これは文字列として指定する。
文字列として指定され、名前と値の両方を含む 1 つのリソースエントリを 追加するには XrmPutLineResourceを使う。
void XrmPutLineResource(database, line)
XrmDatabase *database;
char *line;
引き数 database が NULL の場合、 XrmPutLineResourceは新しいデータベースを生成し、それを指すポインタを返す。 XrmPutLineResourceは、指定したデータベースにリソースのエントリーを1つ追加する。 引き数 line は、改行か NULL 文字で終わる有効な ResoureLine 形式(15.1 節を参照)でなければならない。 文法的に誤っている文字列を用いた結果のデータベースは実装依存である。 文字列はデータベースのロケールで展開される。 ResourceNameのエンコーディングがホストポータブル文字エンコーディングでない場合、結 果は実装依存である。 コメント行は格納されない点に注意すること。
- database
- リソースデータベースを指定する。
- line
- リソース名と値の組を 1 つの文字列として指定する。
データベースのエントリを列挙するには XrmEnumerateDatabaseを使う。
#define XrmEnumAllLevels 0 #define XrmEnumOneLevel 1
Bool XrmEnumerateDatabase(database, name_prefix, class_prefix, mode, proc, arg)
XrmDatabase database;
XrmNameList name_prefix;
XrmClassList class_prefix;
int mode;
Bool (*proc)();
XPointer arg;
関数 XrmEnumerateDatabaseは、データベースの与えられた名前/クラスのリソースのプレフィックスを補 完したものにマッチする各リソースに対して、指定した手続きを呼び出す。 リソースが見つかる順序は実装依存である。 モードが XrmEnumOneLevelならば、リソースは与えられた名前/クラスのプレフィックスで、1つだけの名 前とクラスが追加されているものにマッチしなければならない。モードが XrmEnumAllLevelsならば、リソースは与えられた名前/クラスのプレフィックスで、1つ以上の名 前とクラスが追加されているものにマッチしなければならない。 手続きが Trueを返した場合に列挙は終了し、関数は Trueを返す。 手続きが常に Falseを返す場合、マッチする全てのリソースは列挙され、関数は Falseを返す。
- database
- リソースデータベースを指定する。
- name_prefix
- リソース名のプレフィックスを指定する。
- class_prefix
- リソースクラスのプレフィックスを指定する。
- mode
- 列挙するレベルの数を指定する。
- proc
- マッチしたエントリーのそれぞれに対して呼ばれる手続きを指定する。
- arg
- 手続きに渡される、ユーザ指定の引き数を指定する。
手続きは次の引き数を使って呼び出される:
(*proc)(database, bindings, quarks, type, value, arg) XrmDatabase *database; XrmBindingList bindings; XrmQuarkList quarks; XrmRepresentation *type; XrmValue *value; XPointer arg;
引き数の bindings リストと quarks リストは、 NULLQUARKで終わる。 手続きにはデータベースへのポインタと型が渡されるが、これらの値を変更し てはならない点に注意すること。
この手続きはデータベースを変更してはならない。 Xlib がスレッドを初期化した場合、手続きはロックされたデータベースを引き数 にして呼ばれる。このとき、手続きが同一のデータベースを使って Xlib 関 数を呼び出した場合の結果は未定義である。
関数 XrmParseCommandを使うとコマンド行引き数を解析してプログラムに渡すことや、 コマンド行から選んだエントリを使ってリソースデータベースを修正する ことができる。
typedef enum { XrmoptionNoArg, /* 値は XrmOptionDescRec.value で指定 */ XrmoptionIsArg, /* 値はオプション文字列そのもの */ XrmoptionStickyArg, /* 値はオプション直後の文字 */ XrmoptionSepArg, /* 値は argv 中の次の引き数 */ XrmoptionResArg, /* argv 中の次の引き数のリソースと値 */ XrmoptionSkipArg, /* このオプションと argv 中の次の引き数を無視 */ XrmoptionSkipLine, /* このオプションと残りの argv を無視 */ XrmoptionSkipNArgs /* このオプションと argv 中の次の引き数 \ \ \ XrmOptionDescRec.value を無視 */ } XrmOptionKind;
XrmoptionSkipArgは、 XrmOptionDescRec.valueフィールドに 1 を設定して XrmoptionSkipNArgsを呼ぶことと等価である点に注意すること。 XrmoptionSkipNArgsに 0 を設定することは、そのオプション指定だけを飛ばすという意味である 点にも注意すること。
typedef struct { char *option; /* argv 中のオプション指定文字列 */ char *specifier; /* 結合文字とリソース名(アプリケーション名は含まない) */ XrmOptionKind argKind; /* オプションの形式 */ XPointer value; /* XrmoptionNoArg あるいは XrmoptionSkipNArgs */ } XrmOptionDescRec, *XrmOptionDescList;
C のコマンド行からリソースデータベースをロードするには XrmParseCommandを使う。
void XrmParseCommand(database, table, table_count, name, argc_in_out, argv_in_out)
XrmDatabase *database;
XrmOptionDescList table;
int table_count;
char *name;
int *argc_in_out;
char **argv_in_out;
関数 XrmParseCommandは、指定されたオプションテーブルに従って(argv, argc) の組を展開し、認 識したオプションを ``String'' 型で指定されたデータベースにロードし、 (argc, argv) の組から認識したオプションを全て取り除く。 引き数 databaseが NULL ならば、新しいデータベースが作成され、それを指す ポインタが返される。 そうでない場合には、エントリーが指定されたデータベースに追加される。 データベースを生成する場合には現在のロケールを使う。
- database
- リソースデータベースを指定する。
- table
- 展開されるコマンド行の引き数のテーブルを指定する。
- table_count
- テーブルが持つエントリーの数を指定する。
- name
- アプリケーション名を指定する。
- argc_in_out
- 引き数の数を指定する。また、残っている引き数の数が返される。
- argv_in_out
- コマンド行の引き数を指定する。 また、残っている引き数が返される。
指定されたテーブルはコマンド行の展開に使われる。 テーブル中で認識されたオプションは argv から取り除かれ、argv 中に現わ れた順でエントリーが指定されたリソースデータベースに追加される。 オプションの種類が XrmoptionNoArgならば、テーブルのエントリはオプション文字列、オプション名、オプション の形式、与える値の情報を持つ。 オプション名は argv が持つ引き数とバイトごとの比較を行う。 これはいずれのロケールからも独立である。 テーブルで与えられるリソース値は、変更されずにリソースデータベースに格 納される。 全てのリソースデータベースのエントリーは、表現型 ``String'' を用いて 生成される。 引き数 argc は、argv が持つ引き数の数を指定する。関数が返ってきた際には、 展開されずに残った引き数の数が設定されている。 引き数 name はデータベースのエントリーを構築する際に用いられるアプリケー ションの名前を設定しなければならない。 引き数 name は、データベースのエントリーの格納の前に、オプション表で resourceName の先頭に付けられる。 途中にピリオドを含む場合であっても、引き数 name は単独のコンポーネントと して扱われる。 区切り(結合)文字が含まれていなければ、 テーブルはピリオド(.)かアスタリスク(*)を各 resourceName エントリーの先 頭の文字として含んでいなければならない。 より細かく限定したリソース名を指定するため、resourceName エントリーに 複数のコンポーネントを含めてもよい。 引き数 name と resourceName のエンコーディングがホストポータブル文字エ ンコーディングでない場合の実行結果は実装依存である。
オプションテーブルの例を以下に示す:
static XrmOptionDescRec opTable[] = { {"-background", "*background", XrmoptionSepArg, (XPointer) NULL}, {"-bd", "*borderColor", XrmoptionSepArg, (XPointer) NULL}, {"-bg", "*background", XrmoptionSepArg, (XPointer) NULL}, {"-borderwidth", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL}, {"-bordercolor", "*borderColor", XrmoptionSepArg, (XPointer) NULL}, {"-bw", "*TopLevelShell.borderWidth", XrmoptionSepArg, (XPointer) NULL}, {"-display", ".display", XrmoptionSepArg, (XPointer) NULL}, {"-fg", "*foreground", XrmoptionSepArg, (XPointer) NULL}, {"-fn", "*font", XrmoptionSepArg, (XPointer) NULL}, {"-font", "*font", XrmoptionSepArg, (XPointer) NULL}, {"-foreground", "*foreground", XrmoptionSepArg, (XPointer) NULL}, {"-geometry", ".TopLevelShell.geometry", XrmoptionSepArg, (XPointer) NULL}, {"-iconic", ".TopLevelShell.iconic", XrmoptionNoArg, (XPointer) "on"}, {"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, {"-reverse", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"}, {"-rv", "*reverseVideo", XrmoptionNoArg, (XPointer) "on"}, {"-synchronous", "*synchronous", XrmoptionNoArg, (XPointer) "on"}, {"-title", ".TopLevelShell.title", XrmoptionSepArg, (XPointer) NULL}, {"-xrm", NULL, XrmoptionResArg, (XPointer) NULL}, };
このテーブルの場合、背景色を設定するために -background (または -bg) オプションが使われると、格納されているリソース指定子は背景の属性を持つ 全てのリソースにマッチする。 -borderwidth オプションが使われると、格納されているリソース指定子は クラス TopLevelShell (つまり最も外側のウィンドウ。 ポップアップウィンドウも含まれる)の境界幅属性だけに適用される。 -title オプションを使ってウィンドウ名を設定すると、最上位にある アプリケーションウィンドウだけがこのリソースを受け取る。
コマンド行の解析の際には、テーブル内で一意に決まるオプションの省略名は そのオプションにマッチするものとして扱われる。 大文字と小文字は区別される点に注意すること。