この章では、Motif における国際化対応に関連する作業について説明します。
言語環境という用語は、アプリケーションがユーザの指定したロケールで正しく実行するために必要な、ローカライズされたデータのセットを言います。言語環境は、特定の言語に関連する規則を提供します。また、言語環境は、外部に格納されたすべてのデータから成ります。このデータは、アプリケーションが使用するローカライズされた文字列やテキストなどです。たとえば、アプリケーションが表示するメニュー項目は、アプリケーションがサポートする言語別に、別ファイルに格納されている可能性があります。この型のデータは、リソース・ファイル、UID (ユーザ・インタフェース定義) ファイル、(XPG3 準拠システムの) メッセージ・カタログに格納できます。
1 つの言語環境は、1 つのアプリケーションが動作するときに確立されます。アプリケーションが実行される言語環境は、アプリケーション・ユーザによって、環境変数 (POSIX システムの LANG または LC_*) か xnlLanguage リソースのいずれかにより設定されます。その後アプリケーションはユーザの指定に基づいて言語環境を設定します。アプリケーションはこの設定を、XtSetLanguageProc() 関数に確立された言語プロシージャの setlocale() 関数を使って行うこともできます。これにより Xt は、XtResolvePathname() 関数がリソース、ビットマップ、UIL (ユーザ・インタフェース言語) ファイルを見つけるのに使用するディスプレイごとの指定言語文字列をキャッシュします。
言語プロシージャを提供するアプリケーションは、独自のプロシージャを提供するか、あるいは Xt デフォルト・プロシージャを使用することができます。どちらの場合も、アプリケーションは、ツールキットを初期化する前、また (XtAppInitialize() 関数を呼び出すなどして) リソース・データベースを読み込む前に XtSetLanguageProc() を呼び出すことにより、言語プロシージャを確立します。言語プロシージャがインストールされると、Xt は初期リソース・データベースの構築中にその言語プロシージャを呼び出します。Xt は言語プロシージャが返す値をディスプレイごとの指定言語文字列に使用します。
デフォルトの言語プロシージャは次のタスクを実行します。
次のようにしてロケールを設定します。
setlocale(LC_ALL, language);
language は xnlLanguage リソースの値です。または、xnlLanguage リソースが設定されていない場合は空の文字列 (“”) です。xnlLanguage リソースが設定されていない場合、一般的にロケールは環境変数 (POSIX システムの LANG) から得られます。
設定されたロケールがサポートされているかを確認するために、XSupportsLocale()関数を呼び出します。サポートされていない場合、警告メッセージが発行されロケールは C に設定されます。
空の文字列を指定する XSetLocaleModifiers() 関数を呼び出します。
現在のロケールの値を返します。ANSI C に基づくシステムでは、その値は次の呼び出しの結果です。
setlocale(LC_ALL, NULL);
アプリケーションは、次のように XtSetLanguageProc() 関数を呼び出すことにより、デフォルト言語プロシージャを使用できます。
XtSetLanguageProc(NULL, NULL, NULL); . . toplevel = XtAppInitialize(...);
デフォルトでは、Xt は言語プロシージャを何もインストールしません。アプリケーションが XtSetLanguageProc() 関数を呼び出さないと、Xt はディスプレイごとの指定言語文字列に xnlLanguage リソースが設定されている場合は、その値を使用します。xnlLanguage リソースが設定されていない場合は、Xt は言語文字列を LANG 環境変数から獲得します。
このプロセスから得られるディスプレイごとの指定言語文字列は実装に依存します。また、いったん言語文字列が確立されると、Xt は言語文字列を調べる公共の手段を提供しません。
独自の言語プロシージャを提供することにより、アプリケーションは言語文字列を設定する際にどんなプロシージャでも使用できます。
デスクトップは、テキストを表示するためにフォント・リストを使用します。フォントは、指定された文字セットの文字を表現するグリフのセットを定義します。フォント・セットは、指定されたロケールまたは言語のテキストを表示するのに必要なフォントの集まりです。フォント・リストは、使用されるフォントか、フォント・セットか、その両方のリストです。Motif にはフォント・リストを作成する簡易関数があります。
デスクトップには、テキスト表示用にフォント・リストが必要です。フォント・リストは、フォント構造体か、フォント・セットか、その両方のリストであり、それぞれに識別のためのタグがあります。フォント・セットは、現在の言語のすべての文字が確実に表示できるようにします。フォント構造体により、すべての文字が確実に表示できるようにするのは、(ロケールのコード・セットからグリフ索引への変換を含めて) プログラマの責任です。
フォント・リストの各エントリの形式は、{tag, element } の組み合わせです。element は単一のフォントかフォント・セットのいずれかです。アプリケーションは、単一のフォントとフォント・セットのどちらからでもフォント・リスト・エントリを作成できます。たとえば、次のコード・セグメントはフォント・セットのフォント・リスト・エントリを作成します。
char font1[] = "-adobe-courier-medium-r-normal--10-100-75-75-M-60"; font_list_entry = XmFontListEntryLoad (displayID, font1, XmFONT_IS_FONTSET, "font_tag");
XmFontListEntryLoad() 関数は、フォントを読み込むか、またはフォント・セットを作成して読み込みます。この関数の 4 つの引き数は次のとおりです。
フォント・リストが使用されるディスプレイ
フォント名かベース・フォント名リストのいずれか (nametype 引き数による) を表す文字列
fontname 引き数がフォント名とベース・フォント名リストのどちらを表すかを指定する値
そのフォント・リスト・エントリのタグを表す文字列
nametype 引き数が XmFONT_IS_FONTSET の場合、XmFontListEntryLoad() 関数は fontname 引き数の値からフォント・セットを現在のロケールに作成します。フォント・セットに指定されたフォントの文字セットは、ロケールに依存します。nametype が XmFONT_IS_FONT の場合、XmFontListEntryLoad() 関数は fontname にあるフォントをオープンします。どちらの場合も、フォントまたはフォント・セットがフォント・リスト・エントリに置かれます。
次のコード例は、新しいフォント・リストを作成し、そこにエントリfont_list_entry を追加します。
XmFontList font_list; XmFontListEntry font_list_entry; . . font_list = XmFontListAppendEntry (NULL, font_list_entry); XmFontListEntryFree (font_list_entry);
フォント・リストが作成されると、XmFontListAppendEntry() 関数がそこに新しいエントリを追加します。次の例は、XmFontListEntryCreate() 関数を使用して既存のフォント・リストに新しいフォント・リスト・エントリを作成します。
XFontSet font2; char *font_tag; XmFontListEntry font_list_entry2; . . font_list_entry2 = XmFontListEntryCreate (font_tag, XmFONT_IS_FONTSET, (XtPointer)font2);
font2 パラメータは XCreateFontSet() 関数に返された XFontSet を指定します。XmFontListEntryCreate() 関数の引き数は font_tag、XmFONT_IS_FONTSET、font2 であり、それぞれタグ、型、フォントです。タグおよびフォント・セットは、フォント・リスト・エントリの {tag, element} の組み合わせです。
このエントリをフォント・リストに追加するには、XmFontListAppendEntry() 関数を再度使用します。このときのみ最初のパラメータが既存のフォント・リストを指定します。
font_list = XmFontListAppendEntry(font_list, font_list_entry2); XmFontListEntryFree(font_list_entry2);
リソース・ファイルにフォント・リストを指定する形式は、リストに含まれるものがフォントか、フォント・セットか、その両方かによって異なります。
フォントを獲得するには、フォントとオプションのフォント・リスト要素タグを指定します。
タグがある場合は、その前に = (等号記号) を付けます。
タグがない場合は、= (等号記号) を使用しないでください。
複数のフォントを指定するエントリは、, (カンマ) で区切られます。
フォント・セットを獲得するには、ベース・フォント・リストとオプションのフォント・リスト要素タグを指定します。
タグがある場合は、その前に = (等号記号) ではなく : (コロン) を付けます。
タグがない場合でも、コロンは必ず付けなければなりません。コロンはリソース宣言においてフォントをフォント・セットと区別するからです。
ベース・フォント・リストに指定された複数のフォントは ; (セミコロン) で区切られます。複数のフォント・セットを指定するエントリは , (カンマ) で区切られます。
フォント・リスト要素タグがない場合、デフォルトの XmFONTLIST_DEFAULT_TAG が使用されます。次に例をいくつか示します。
デフォルトのフォント・リスト要素タグを使用してフォントを指定します。
*fontList: fixed *fontList: \ -adobe-courier-medium-r-normal--10-100-75-75-M-60-iso8859-1
フォント・リスト要素タグを指定します。
*fontList: fixed=ROMAN, 8x13bold=BOLD
デフォルトのフォント・リスト要素タグと明示タグで 2 つのフォントを指定します。
*fontList: fixed, 8x13bold=BOLD
フォント・リスト要素タグがない場合、デフォルトの XmFONTLIST_DEFAULT_TAG が使用されます。次にフォント・セット指定の例をいくつか示します。
フォント・リスト要素タグを指定せずに、Xlib にフォントを選択させます。
*fontList: -dt-application-medium-r-normal-*-m*-*-*-*-m-*
Xlib にフォントを選択させ、フォント・リスト要素タグに MY_TAG を指定させます。
*fontList: -dt-application-medium-r-normal-*-m*-*-*-*-m*:MY_TAG
Xlib にフォントを選択させ、フォント・リスト要素タグにボールド指定させ、その他に関してはデフォルトのフォント・リスト要素タグを使用させます。
*fontList: -dt-application-medium-r-normal-*-m*-*-*-*-m-*:,\ -dt-application-medium-r-normal-style2-m*-*-*-*-m-*:BOLD
XmFontList() データ型は次の要素に関連付けられた 1 つ以上のエントリを含むことができます。
フォントの charset でエンコードされたテキスト (フォント・エンコード・テキスト) を描画するのに使用できる X フォント
ロケールでエンコードされたテキスト (ローカライズされたテキスト) を描画するのに使用できる XFontStruct フォントの集まり
次の形式は、文字列から XmFontList へのコンバータによって使用されます。
XmFontList := <fontentry> {', 'fontentry} fontentry := <fontname><fontid> | <baselist><fontsetid> baselist := <fontname>{';'<fontname>} fontsetid := ':'<string> | <defaultfontset> fontname := <XLFD string> fontid := '='<string> | <defaultfont> XLFD string := XLFD 仕様を参照 defaultfont := NULL defaultfontset:= ':'NULL string := 改行をのぞく ISO646IRV のすべての文字
XmFontList が指定された fontentry は、フォントかフォント・セットのいずれかを指定できます。どちらの場合も、コンパウンド・ストリング (XmString) 内のセグメントにより ID (fontid または fontsetid) が参照できます。
defaultfont と defaultfontset はいずれもデフォルトの fontentry を定義できますが、XmFontList 単位にデフォルトは 1 つだけしかありません。
XmFONTLIST_DEFAULT_TAG 識別子は、XmString が描画されるときに、常にデフォルトの fontentry を参照します。デフォルトの fontentry が指定されない場合は、最初の fontentry が描画に使用されます。
リソース・コンバータは、作成されたすべてのフォント・セットが同じロケールに関連付けられるように、単一のロケールで動作します。
実装によっては、ロケールのコード・セット名を、特別な charset ID (fontid または fontsetid) として XmFontList 文字列の中に確保します。このためアプリケーション開発者は、プラットフォーム間でポータブルなアプリケーションを作成したい場合は、コード・セット名を使用しないように注意してください。
コンパウンド・ストリングは、プログラムを変更しなくても数多くのフォントでテキストを表示できるようにテキストをエンコーディングする手段です。デスクトップは、Text ウィジェットと TextField ウィジェット以外のすべてのテキストを表示するのにコンパウンド・ストリングを使用します。この節は、コンパウンド・ストリングの構造、コンパウンド・ストリングとフォント・リスト間の対話を説明し (コンパウンド・ストリングの表示方法を決定する)、国際化対応プロセスにとって重要な点にフォーカスをあてます。
コンパウンド・ストリングは、タグ長値のセグメントから成る内部のエンコーディングです。意味上では、コンパウンド・ストリングには、表示されるテキスト、フォント・リストの要素に一致するタグ (フォント・リスト要素タグ)、表示する方向を示すインジケータなどのコンポーネントがあります。
コンパウンド・ストリングのコンポーネントは、次の 4 つのいずれかの型になります。
フォント・リスト要素タグ
フォント・リスト要素タグ XmFONTLIST_DEFAULT_TAG は、テキストが現在のロケールのコード・セットでエンコードされることを示します。
その他のフォント・リスト要素タグは、あとでテキストをフォント・リストの特定のエントリに一致させるために使用されます。
方向識別子
文字列のテキスト
国際化対応アプリケーションでは、テキストは大きく 2 種類に分けられます。ローカライズされた処理が必要なテキストと、そうでないテキストです。
セパレータ
コンパウンド・ストリングのテキスト・コンポーネントをフォント・リストのフォントまたはフォント・セットに相関させる文字列の値を示します。
文字がキーボードに入力される順序と、その文字が画面に表示される順序の関係を示します。たとえば、英語、フランス語、ドイツ語、イタリア語の表示順序は左から右であり、ヘブライ語とアラビア語の表示順序は右から左です。
表示されるテキストを示します。
値がない特殊な形式のコンパウンド・ストリングのコンポーネントを示します。セパレータは他のセグメントを区切るのに使用されます。
共通デスクトップ環境では、コンパウンド・ストリングを表示するために、テキスト・コンポーネントで識別される指定されたフォント・リスト要素タグを使用します。指定されたフォント・リスト要素タグは、新しいフォント・リスト要素タグが見つかるまで使用します。共通デスクトップ環境は、現在のコード・セットに対して正しいフォントに一致する特別なフォント・リスト要素タグ XmFONTLIST_DEFAULT_TAG を提供します。XmFONTLIST_DEFAULT_TAG はフォント・リストのデフォルト・エントリを識別します。詳細は、コンパウンド・ストリングとフォント・リストを参照してください。
コンパウンド・ストリングの方向セグメントは、テキストが表示される方向を指定します。方向は左から右または右から左です。
コンパウンド・ストリングは、Text ウィジェットと TextField ウィジェット以外のすべてのテキストを表示するのに使用されます。コンパウンド・ストリングは、表示できるように適切なウィジェット・リソースに設定されます。たとえば、PushButton ウィジェットのラベルは Label ウィジェットから引き継がれ、リソースは XmNlabelString で型は XmString です。このことは、リソースがコンパウンド・ストリングの値を予想していることを意味します。コンパウンド・ストリングはプログラムで作成したり、リソース・ファイルで定義することが可能です。
アプリケーションは、XmStringCreateLocalized() コンパウンド・ストリング簡易関数を使用してコンパウンド・ストリングを作成することで、このリソースをプログラムで設定できます。
この関数は、現在のロケールのエンコーディングでコンパウンド・ストリングを作成し、自動的に XmFONTLIST_DEFAULT_TAG をフォント・リスト・エントリ・タグに設定します。
次のコードの一部分は、プログラムを使用してプッシュ・ボタンに XmNlabelString リソースを設定するための 1 つの方法を示します。
#include <nl_types.h> Widget button; Args args[10]; int n; XmString button_label; nl_msg my_catd; (void)XtSetLanguageProc(NULL,NULL,NULL); . . button_label = XmStringCreateLocalized (catgets(my_catd, 1, 1, "default label"), XmFONTLIST_DEFAULT_TAG); /* Create an argument list for the button */ n = 0; XtSetArg (args[n], XmNlabelString, button_label); n++; /* Create and manage the button */ button = XmCreatePushButton (toplevel, "button”, args, n); XtManageChild (button); XmStringFree (button_label);
国際化対応プログラムでは、ボタン・ラベル用のラベル文字列は外部リソースから獲得してください。たとえば、ボタン・ラベルはプログラムではなくリソース・ファイルから得られます。次の例では、プッシュ・ボタンは form1 と呼ばれる Form ウィジェットの子であると想定します。
*form1.button.labelString: Push Here
ここで、デスクトップの文字列からコンパウンド・ストリングへのコンバータは、リソース・ファイル・テキストからコンパウンド・ストリングを生成します。このコンバータは常に XmFONTLIST_DEFAULT_TAG を使用します。
デスクトップがコンパウンド・ストリングを表示する場合、デスクトップはセグメントのフォント・リスト要素タグを使用して、各セグメントをフォントまたはフォント・セットに関連付けます。アプリケーションは希望するフォントまたはフォント・セットを読み込んで、そのフォントまたはフォント・セットと、それに関連付けられたフォント・リスト要素タグを含むフォント・リストを作成し、同じタグでコンパウンド・ストリング・セグメントを作成していなければなりません。
デスクトップは、コンパウンド・ストリングをフォント・リスト・エントリに割り当てるとき、次のように設定された検索プロシージャに従います。
デスクトップは、フォント・リストで、コンパウンド・ストリングに指定されたフォント・リスト要素タグと厳密に一致するものを検索します。一致点が見つかると、コンパウンド・ストリングはそのフォント・リスト・エントリに割り当てられます。
コンパウンド・ストリングとフォント・リスト間の一致点が見つからない場合は、デスクトップは、コンパウンド・ストリングをフォント・リスト要素タグに関係なくフォント・リストの最初の要素に割り当てます。
後方互換を保つため、厳密な一致点が見つからない場合は、コンパウンド・ストリングまたはフォント・リストの XmFONTLIST_DEFAULT_TAG の値が、XmSTRING_DEFAULT_CHARSET のタグでコンパウンド・ストリングまたはフォント・リストのエントリを作成した結果のタグに一致します。
図 4–1 は、フォント・リスト要素タグが XmFONTLIST_DEFAULT_TAG 以外に設定される場合の、コンパウンド・ストリング、フォント・セット、フォント・リスト間の関係を示しています。
次の例は、tagb と呼ばれるタグの使用方法を示しています。
XFontSet *font1; XmFontListEntry font_list_entry; XmFontList font_list; XmString label_text; char **missing; int missing_cnt; char *del_string; char *tagb; /* Font list element tag */ char *fontx; /* Initialize to XLFD or font alias */ char *button_label; /* Contains button label text */ . . font1 = XCreateFontSet (XtDisplay(toplevel), fontx, & missing, & missing_cnt, & def_string); font_list_entry = XmFontListEntryCreate (tagb, XmFONT_IS_FONTSET, (XtPointer)font1); font_list = XmFontListAppendEntry (NULL, font_list_entry); XmFontListEntryFree (font_list_entry); label_text = XmStringCreate (button_label, tagb);
XCreateFontSet() 関数はフォント・セットを読み込み、XmFontListEntryCreate() 関数はフォント・リスト・エントリを作成します。アプリケーションは、エントリを作成してそれを既存のフォント・リストに追加するか、または新しいフォント・リストを作成しなければなりません。どちらの場合も XmFontListAppendEntry() 関数を使用します。適切な場所にフォント・リストがないので、前述のコード例ではフォント・リスト引き数が NULL の値になっています。XmFontListAppendEntry() 関数は、単一のエントリ font_list_entry を持つ font_list という新しいフォント・リストを作成します。font_list に新しいエントリを追加するには、同じプロシージャに従い、ヌルでないフォント・リスト引き数を提供してください。
図 4–2 は、フォント・リスト要素タグが XmFONTLIST_DEFAULT_TAG に設定される場合の、コンパウンド・ストリング、フォント・セット、フォント・リストの関係を示しています。この場合、値のフィールドはロケール・テキストです。
ここで、デフォルト・タグは Font_Set_C を指しています。Font_Set_C は、その言語で文字を表示するのに必要なフォントを識別します。
Text ウィジェットと TextField ウィジェットは、テキスト情報を表示します。そのためには、ウィジェットは、情報を表示するのに使う正しいフォントを選択できなければなりません。Text ウィジェットと TextField ウィジェットは、正しいフォントを見つけるために、次のように設定された検索パターンに従います。
ウィジェットは、フォント・リストでフォント・リスト要素タグ XmFONTLIST_DEFAULT_TAG を持つフォント・セットであるエントリを検索します。一致点が見つかった場合は、そのフォント・リスト・エントリを使用します。それ以上の検索は行われません。
一致点が見つからなければ、ウィジェットは、フォント・リストでフォント・セットを指定するエントリを検索します。ウィジェットは最初に見つかったフォント・セットを使用します。
フォント・セットが見つからない場合は、ウィジェットはフォント・リストの 1 番目のフォントを使用します。
フォント・セットを使用すると、ロケール内のどの文字に対してもグリフが確実に存在します。
システム環境では、VendorShell ウィジェット・クラスは入力メソッドへのインタフェースを提供するために拡張されます。VendorShell クラスは、ジオメトリ管理で 1 つの子ウィジェットだけをコントロールする一方、入力メソッドへのインタフェースに必要なすべてのコンポーネントが管理できるように、VendorShell クラスに拡張が追加されます。これらのコンポーネントにはステータス領域、プリエディット領域、メイン・ウィンドウ領域があります。
入力メソッドが、ステータス領域かプリエディット領域あるいはその両方を必要とするとき、VendorShell ウィジェットは自動的にステータス領域とプリエディット領域のインスタンスを生成し、それらのジオメトリ・レイアウトを管理します。ステータス領域もプリエディット領域もすべて VendorShell ウィジェットにより内部で管理され、クライアントからはアクセスできません。VendorShell ウィジェットの子としてインスタンスを生成されたウィジェットは、メイン・ウィンドウ領域と呼ばれます。
VendorShell ウィジェットが使用する入力メソッドは XmNinputMethod リソース (たとえば @im=alt) により決定されます。デフォルト値ヌルは、VendorShell が作成されたときに、ロケールに関連付けられたデフォルトの入力メソッドを選択することを示します。このように、ユーザはロケールを設定するか、XmNinputMethod リソースを設定するか、あるいは両方設定することにより、どの入力メソッドが選択されるかに影響を与えることができます。入力メソッド名を決定するために、ロケール名は XmNinputMethod リソースと連結されます。ロケール名はこのリソースに指定してはなりません。XmNinputMethod リソースのモディファイアの名前を @im=modifier 形式の中に指定しなければなりません。modifier は、どの入力メソッドが選択されているかを修飾するのに使う文字列です。
VendorShell ウィジェットは、入力メソッドを共用する複数のウィジェットをサポートできます。しかし、どんな時でもキーボードのフォーカスを持てる (たとえば、キー・プレスのイベントを受信してそれを入力メソッドに送信する) ウィジェットは 1 つだけです。複数のウィジェット (Text ウィジェットなど) をサポートするには、それらのウィジェットが VendorShell ウィジェットの子孫でなければなりません。
VendorShell ウィジェット・クラスは、TransientShell および TopLevelShell ウィジェット・クラスのスーパークラスです。このように、TopLevelShell または Diagshell のインスタンスの生成は、本質的に VendorShell ウィジェット・クラスのインスタンスの生成です。
VendorShell ウィジェットは、子孫の 1 つが XmText[Field] インスタンスである場合のみ入力マネージャとして動作します。XmText[Field] インスタンスが VendorShell ウィジェットの子孫として作成されるとすぐに、VendorShell は現在のロケールによって指示される特定の入力メソッドに必要な領域を作成します。XmText[Field] インスタンスがマップされずにただ作成された場合でも、VendorShell は前述のようなジオメトリ管理の動作を行います。
システムにインストールされたロケールがサポートしているマルチバイト文字の入力および出力を、アプリケーションが処理できるようにします。
入力メソッドのインスタンスを、XmIm 参照関数に定義されたとおりに管理します。
OffTheSpot、OverTheSpot、Root、None のいずれかのモードで、プリエディット領域でのプリエディットをサポートします。ローカライズされたテキストは、フォーカスを変更することにより、複数の Text 子ウィジェット・ツリー内のどの Text 子ウィジェットにも入力できます。
子孫ウィジェットのジオメトリ管理を提供します。
VendorShell ウィジェットは、入力メソッドのユーザ・インタフェース・コンポーネントのジオメトリ管理とフォーカス管理を必要に応じて提供します。ロケールがそれを保証する場合 (たとえばロケールが日本語の EUC (拡張 UNIX コード) ロケールの場合)、VendorShell ウィジェットは、必要なプリエディット領域かステータス領域あるいはその両方のジオメトリを自動的に割り当てて管理します。
現在行われているプリエディットによっては補助領域が必要になります。補助領域が必要な場合は、VendorShell ウィジェットは補助領域の手続きを生成して管理します。通常、VendorShell ウィジェットの子は複数の Text および TextField ウィジェットを管理できるコンテナ・ウィジェット (XmBulletinBoard ウィジェットまたは XmRowColumn ウィジェットなど) であり、ユーザからのマルチバイト文字の入力ができます。このシナリオでは、すべての Text ウィジェットは同一の入力メソッドを共用します。
ステータス領域、プリエディット領域、補助領域にはアプリケーションのプログラマはアクセスできません。たとえば、アプリケーションのプログラマがステータス領域のウィンドウ ID にアクセスすることは想定されていません。それらのコンポーネントは必要に応じて VendorShell ウィジェット・クラスが管理するので、ユーザはそれらのコンポーネントのインスタンスの生成や管理について考える必要はありません。
アプリケーションのプログラマは、VendorShell ウィジェット・クラスの XmNpreedetType リソースを介して、入力メソッドのユーザ・インタフェース・コンポーネントの動作をいくらかコントロールできます。OffTheSpot モードと OverTheSpot モードについては、入力メソッドを参照してください。
ジオメトリ管理は、すべての入力メソッドのユーザ・インタフェースのコンポーネントに及びます。アプリケーション・プログラム・ウィンドウ (TopLevelShell ウィジェット) がサイズ変更されると、入力メソッドのユーザ・インタフェースのコンポーネントもそれに応じてサイズ変更され、その中のプリエディットされた文字列は必要に応じて再配置されます。もちろん、シェル・ウィンドウのサイズ変更ポリシーが true であることを想定しています。
VendorShell ウィジェットが作成されるとき、特定の入力メソッドがステータス領域、プリエディット領域、あるいはその両方を必要とする場合、VendorShell のサイズはそれらのコンポーネントが必要とする領域を考慮します。プリエディット領域とステータス領域が必要とする特別な領域は、VendorShell ウィジェットの領域の一部です。それらの領域も、サイズ変更する必要がある場合は VendorShell ウィジェットに管理されます。
それらの領域 (ステータス領域およびプリエディット領域) の潜在的な手続きの作成のために、現在使用されている入力メソッドによって、VendorShell ウィジェット領域のサイズは必ずしも子のサイズにぴったり合うように伸縮する必要はありません。VendorShell ウィジェット領域のサイズは、子のジオメトリとこれらの入力メソッドのユーザ・インタフェース領域のジオメトリの両方が入るように伸縮します。VendorShell ウィジェットと子ウィジェット (メイン・ウィンドウ領域) 間の高さには差があるかもしれません (たとえば 20 ピクセル)。幅のジオメトリは、入力メソッドのユーザ・インタフェースのコンポーネントに影響されません。
まとめると、子に要求されたサイズは可能であれば受け付けられます。VendorShell の実際のサイズは子よりも大きい場合もあります。
VendorShell ウィジェットと子のジオメトリを指定する要求は、互いに矛盾しない限り、または VendorShell ウィジェットのサイズ変更能力の制約内であれば行われます。矛盾する場合は、子のウィジェット・ジオメトリ要求が優先します。たとえば、子ウィジェットのサイズが 100 × 100 に指定された場合、VendorShell のサイズも 100 × 100 に指定されます。子ウィジェットのサイズが 100 × 100 になるのに対して、VendorShell のサイズは結果的に 100 × 120 になります。子ウィジェットのサイズが指定されない場合、独自のサイズ指定を使用する必要があれば VendorShell は子ウィジェットを縮小します。たとえば、VendorShell のサイズが 100 × 100 に指定され、子のサイズは指定されない場合、子ウィジェットのサイズは 100 × 80 になります。VendorShell ウィジェットがサイズ変更を禁止されている場合は、子のジオメトリ要求がどうであっても VendorShell ウィジェットは独自のジオメトリ指定を使用します。
多数の文字を使用する言語 (日本語や中国語など) には、ユーザがその言語で対話的に文字を構成できる入力メソッドが必要です。このような言語には、端末のキーボードに適正にマップできる数をはるかに超える文字が存在するからです。
そのような言語で文字を構成する対話的なプロセスをプリエディットといいます。プリエディット自体は入力メソッドによって処理されます。しかし、プリエディットのユーザ・インタフェースはシステム環境により決定されます。入力メソッドとシステム環境の間にインタフェースが存在する必要があります。これは、システム環境の VendorShell ウィジェットを介して実行できます。
図 4–3 は日本語のプリエディットの例を示しています。反転表示された文字列がプリエディット中の文字列です。この文字列は、特定のウィンドウへのフォーカスを与えることにより、異なるウィンドウに移動できます。しかし、プリエディット・セッションは一度に 1 つだけです。
フォーカス管理の例として、TopLevelShell ウィジェット (VendorShell ウィジェットのサブクラス) が、5 つの XmText ウィジェットを子に持つ XmBulletinBoard ウィジェットの子 (メイン・ウィンドウ領域) を持っていると想定します。そのロケールにはプリエディット領域が必要で、OverTheSpot モードが指定されていると想定します。VendorShell ウィジェットは入力メソッドの手続きを 1 つだけ管理するので、プリエディット領域は TopLevelShell ウィジェットの内部で一度に 1 つだけしか実行できません。フォーカスがある Text ウィジェットから他の Text ウィジェットへ移動される場合は、処理中の現在のプリエディット文字列も、現在フォーカスを持っている Text ウィジェットのトップに移動されます。以前の Text ウィジェットへのキー処理は一時的に中断されます。以降の入力メソッドのインタフェース (プリエディット完了時の文字列の送信等) は、フォーカスされた新しい Text ウィジェットに対して行われます。
プリエディットされている文字列は、マウスをクリックするなどの動作でフォーカスの位置に移動できます。
エンド・ユーザがプリエディットを終えてすでに確定した文字列は再変換できません。いったん文字列が構成されると、それは確定されます。文字列を確定するというのは、その文字列がプリエディット領域からクライアントのフォーカス・ポイントへ移動することです。
マルチバイト文字の文字列を文字列リテラルとして解析する機能が UIL (ユーザ・インタフェース言語) に追加されました。UIL ファイルの作成は、目的の言語の特徴を使って UID (ユーザ・インタフェース定義) ファイルを記述することで実行できます。
UIL コンパイラは、標準にはない charset をロケール・テキストとして解析します。そのためには、UIL コンパイラがどのロケール・テキストとも同じロケールで実行する必要があります。
ウィジェットのロケール・テキストにフォント・セット (複数のフォント) が必要な場合、フォント・セットがリソース・ファイル内に指定されなければなりません。font パラメータはフォント・セットをサポートしません。
UIL に特定の言語を使用するために、UIL ファイルが目的の言語の特徴に応じて記述され、UID ファイルにコンパイルされます。ローカライズされたテキストを格納している UIL ファイルは、それを実行するロケールにコンパイルする必要があります。
文字列リテラルの例を次に示します。cur_charset の値は常に default_charset の値に設定されており、それによって文字列リテラルがロケール・テキストを格納できます。
default_charset の値でロケール・テキストを文字列リテラルに設定するには、次のように入力します。
XmNlabelString = 'XXXXXX';
または、次のように入力します。
XmNlabelString = #default_charset“XXXXXX”;
ロケール・テキストのエンコーディングに一致する LANG 環境変数で UIL ファイルをコンパイルしてください。そうでない場合、文字列リテラルは正しくコンパイルされません。
フォント・セットは UIL ソース・プログラミングを介して設定することはできません。フォント・セットが必要な場合は、次の例のように必ずリソース・ファイルにフォント・セットを設定してください。
*fontList: -*-r-*-20-*:
UIL はフォント・リストの作成に使用する 3 つの関数 (FONT 、FONTSET 、FONT_TABLE) を持っています。FONT 関数と FONTSET 関数はフォント・リスト・エントリを作成します。FONT_TABLE 関数はそれらのフォント・リスト・エントリからフォント・リストを作成します。
FONT 関数はフォント指定を含むフォント・リスト・エントリを作成します。引き数は XLFD フォント名を表す文字列です。FONTSET 関数は、フォント・セット指定を含むフォント・リスト・エントリを作成します。引き数は、ベース名フォント・リストを表すカンマで区切られた XLFD フォント名のリストです。
FONT と FONTSET には両方とも、フォント・リスト・エントリのフォント・リスト要素タグを指定するオプションの CHARACTER_SET 宣言パラメータがあります。どちらの場合も、CHARACTER_SET 宣言パラメータが指定されない場合は、UIL が次のようにフォント・リスト要素タグを決定します。
モジュールに CHARACTER_SET 宣言がなく、uil コマンドが -s オプションと共に呼び出されたか、あるいは Uil() 関数が use_setlocale_flag セットで開始された場合、フォント・リスト要素タグは XmFONTLIST_DEFAULT_TAG です。
それ以外の場合、UIL コンパイル環境にフォント・リスト要素タグが設定されている場合は、フォント・リスト要素タグは LANG 環境変数のコード・セット・コンポーネントです。LANG 環境変数が設定されていない、またはコード・セットがない場合は、フォント・リスト要素タグは XmFALLBACK_CHARSET の値です。
FONT_TABLE 関数は、FONT または FONTSET により作成された、カンマで区切られたフォント・リスト・エントリのリストからフォント・リストを作成します。その結果のフォント・リストは、フォント・リスト・リソースの値として使用できます。そのようなリソースの値として単一のフォント・リスト・エントリが提供される場合は、UIL はそのエントリをフォント・リストに変換します。
必要であれば、次の例のように入力メソッド関連リソースをリソース・ファイルに設定してください。
*preeditType: OverTheSpot、OffTheSpot、Root、または None
ロケールを区別するアプリケーションの場合は、UID ファイルを適切なディレクトリに設定してください。UIDPATH または XAPPLRESDIR 環境変数を適切な値に設定してください。
たとえば、英語環境で uil_sample プログラムを実行するには (LANG 環境変数は en_US) 、$HOME/en_US ディレクトリにラテン文字で uil_sample.uid を設定するか、またはあるディレクトリに uil_sample.uid を設定して UIDPATH 環境変数に uil_sample.uid ファイルの完全パス名を設定してください。
uil_sample プログラムを日本語環境で実行するには (LANG 環境変数は ja_JP)、$HOME/ja_JP ディレクトリに日本語の (マルチバイト) 文字で uil_sample.uid ファイルを作成するか、または uil_sample.uid を一意のディレクトリに配置して UIDPATH 環境変数に uil_sample.uid ファイルの完全パス名を設定してください。次のリストは可能な変数を指定します。
UID ファイル文字列を指定します。
アプリケーションのクラス名を指定します。
xnlLanguage リソースか LC_CTYPE カテゴリの値を指定します。
xnlLanguage リソースか LC_CTYPE カテゴリの言語コンポーネントを指定します。
XAPPLRESDIR 環境変数が設定されている場合、MrmOpenHierarchy() 関数が次の順番で UID ファイルを検索します。
UID ファイル・パス名
$UIDPATH
%U
$XAPPLRESDIR/%L/uid/%N/%U
$XAPPLRESDIR/%l/uid/%N/%U
$XAPPLRESDIR/uid/%N/%U
$XAPPLRESDIR/%L/uid/%U
$XAPPLRESDIR/%l/uid/%U
$XAPPLRESDIR/uid/%U
$HOME/uid/%U
$HOME/%U
/usr/lib/X11/%L/uid/%N/%U
/usr/lib/X11/%l/uid/%N/%U
/usr/lib/X11/uid/%N/%U
/usr/lib/X11/%L/uid/%U
/usr/lib/X11/%l/uid/%U
/usr/lib/X11/uid/%U
/usr/include/X11/uid/%U
XAPPLRESDIR 環境変数が設定されていない場合は、MrmOpenHierarchy() 関数は XAPPLRESDIR 環境変数の代わりに $HOME を使用します。
default_charset 文字列リテラルについては、どんな文字でも有効な文字列リテラルとして設定できます。たとえば、LANG 環境変数が el_GR の場合は、default_charset の文字列リテラルにはギリシャ文字が入ります。LANG 環境変数が ja_JP の場合は、default_charset の文字列リテラルには日本語の EUC でエンコードされたすべての日本語の文字が入ります。
文字列リテラルに文字セットが設定されていない場合、文字列リテラルの文字セットは cur_charset に設定されます。また、システム環境では、cur_charset の値は常に default_charset に設定されています。
図 4–4 は、英語と日本語の環境での UIL のプログラム例を示します。
次のプログラム例で LLL はロケール・テキストを示します。LLL には日本語、韓国語、中国語 (繁体字)、ギリシャ語、フランス語、その他の言語が入ります。
uil_sample.uil ! ! sample uil file - uil_sample.uil ! ! C source file - uil_sample.c ! ! Resource file - uil-sample.resource ! module Test version = 'v1.0' names = case_sensitive objects = { XmPushButton = gadget; } !************************************ ! declare callback procedure !************************************ procedure exit_CB ; !*************************************************************** ! declare BulletinBoard as parent of PushButton and Text !*************************************************************** object bb : XmBulletinBoard { arguments{ XmNwidth = 500; XmNheight = 200; }; controls{ XmPushButton pb1; XmText text1; }; }; !**************************** ! declare PushButton !**************************** object pb1 : XmPushButton { arguments{ XmNlabelString = #Normal “LLLexit buttonLLL”; XmNx = 50; XmNy = 50; }; callbacks{ XmNactivateCallback = procedure exit_CB; }; }; !********************* ! declare Text !********************* text1 : XmText { arguments{ XmNx = 50; XmNy = 150; }; }; end module; /* * C source file - uil_sample.c * */ #include <Mrm/MrmAppl.h> #include <locale.h> void exit_CB(); static MrmHierarchy hierarchy; static MrmType *class; /******************************************/ /* specify the UID hierarchy list */ /******************************************/ static char *aray_file[] = {“uil_sample.uid”}; static int num_file = (sizeof aray_file / sizeof aray_file[0]); /******************************************************/ /* define the mapping between UIL procedure names*/ /* and their addresses */ /******************************************************/ static MRMRegisterArg reglist[]={ {“exit_CB”,(caddr_t) exit_CB }
UIL ファイルに文字列を指定する方式は 3 つあります。
文字列リテラルとして指定
文字列リテラルは、ヌルで終了する文字列またはコンパウンド・ストリングのいずれかとして UID ファイルに格納される可能性があります。
コンパウンド・ストリングとして指定
ワイド文字の文字列として指定
文字列リテラルとコンパウンド・ストリングは両方とも、テキスト、文字セット、描画方向から成ります。方向が明示されていない文字列リテラルとコンパウンド・ストリングについては、UIL は文字セットから描画方向を推定します。UIL 連結演算子 (&) は、文字列リテラルとコンパウンド・ストリングの両方を連結します。
UIL が文字列リテラルを UID ファイルにヌルで終了する文字列として格納するかコンパウンド・ストリングとして格納するかに関係なく、UIL は各文字列の文字セットと描画方向に関する情報をテキストと共に格納します。一般に、次のような場合に、UIL は文字列リテラルまたは文字列表現をコンパウンド・ストリングとして UID ファイルに格納します。
文字列表現が異なる文字セットまたは描画方向の 2 つ以上のリテラルから成る場合
リテラルまたは文字列表現がコンパウンド・ストリングのデータ型を持つ値 (データ型がコンパウンド・ストリングであるリソースの値など) として使用される場合
UIL は、文字セットを指定する数多くのキーワードを認識します。UIL は、解析方向と文字が 8 ビットと 16 ビットのいずれかなどの解析規則を、認識する文字セットのそれぞれに関連付けます。UIL の CHARACTER_SET を使用して文字セットを定義することも可能です。
文字列リテラルの形式は次のいずれかです。
'[character_string]'
[#char_set]
“[character_string]”
各形式において、文字列の文字セットは次のように決定されます。
'character_string' として宣言された文字列の場合、UIL コンパイル環境に LANG 環境変数が設定されていれば、文字セットは LANG 環境変数のコード・セット・コンポーネントです。あるいは、LANG 環境変数が設定されていないかコード・セットがない場合は、文字セットは XmFALLBACK_CHARSET の値です。デフォルトでは XmFALLBACK_CHARSET の値は ISO8859-1 ですが、ベンダが別の値を供給する場合もあります。
#char_set “string” として宣言された文字列の場合、文字セットは char_set です。
“character_string” として宣言された文字列の場合、文字セットはモジュールに CHARACTER_SET 節があるかどうか、また UIL コンパイラの use_setlocale_flag が設定されているかどうかに依存します。
モジュールに CHARACTER_SET 節がある場合は、文字セットはその節に指定されたものになります。
モジュールに CHARACTER_SET 節がないが uil コマンドが -s オプションで開始された場合、または Uil() 関数が use_setlocale_flag が設定された状態で開始された場合は、UIL は setlocale() 関数を呼び出して現在のロケールの文字列を解析します。結果となる文字列の文字セットは、 XmFONTLIST_DEFAULT_TAG です。
モジュールに CHARACTER_SET 節がなく、uil コマンドが -s オプションなしで実行された場合、または Uil() 関数が use_setlocale_flag なしで実行された場合は、UIL コンパイル環境に LANG 環境変数が設定されていれば、文字セットは LANG 環境変数のコード・セット・コンポーネントです。あるいは、LANG 環境変数が設定されていないかコード・セットがない場合は、文字セットは XmFALLBACK_CHARSET の値です。
UIL は常に、COMPOUND_STRING 関数を使用して指定された文字列をコンパウンド・ストリングとして格納します。この関数は、文字セットの文字列表現とオプション指定、方向、文字列にセパレータを追加するかどうかについてを引き数に取ります。文字セットまたは方向が指定されない場合、前の部分で説明したように UIL はその値を文字列表現から獲得します。
\ (バックスラッシュ) で始まるあらかじめ定義された特定のエスケープ・シーケンスは、次の例外を除いて文字列リテラルに表示できます。
単一引用符に囲まれた文字列は、複数の行にわたることが可能です。各改行文字はバックスラッシュでエスケープされます。二重引用符に囲まれた文字列は、複数の行に渡ることはできません。
エスケープ・シーケンスは、現在のロケールで解析された文字列 (ローカライズされた文字列) の中で逐語的に処理されます。