共通デスクトップ環境 プログラマーズ・ガイド (国際化対応編)

第 5 章 Xt 依存性と Xlib 依存性

この章では、Xt および Xlib における国際化対応に関連する作業について説明します。

ロケール管理

この節では、すべてのロケール依存の Xlib 関数と共通デスクトップ環境関数をコントロールするロケール機構のサポートを定義します。

X ロケール管理

X ロケールは、ホスト環境に定義された 1 つ以上のロケールをサポートします。Xlib は ANSI (米国規格協会) C ライブラリに準拠しており、ロケール通知は setlocale() 関数で行います。setlocale() 関数は、ホスト C ライブラリと Xlib の両方のロケール・オペレーションを構成します。Xlib のオペレーションは LC_CTYPE カテゴリに管理されます。これを現在のロケールと言います。

XSupportsLocale() 関数は、現在のロケールが X によってサポートされているかどうかを判別するのに使用します。

クライアントは、ロケールと X モディファイアを選択する責任があります。クライアントは、ユーザがクライアントの起動時のロケール選択を無効にできる手段を提供すべきです。ほとんどのシングル・ディスプレイ X クライアントは、X とホストの処理環境の両方で、単一のロケールでオペレーションを行います。単一ディスプレイ X クライアントは、setlocale()XSupportsLocale()XSetLocaleModifiers() の 3 つの関数を呼び出すことによりロケールを構成します。

X 国際化対応機能の特定のカテゴリのセマンティクスは、モディファイアを設定することで構成できます。モディファイアは実装に依存するロケール固有の文字列で命名されます。この機能の現在の唯一の標準使用方法は、キーボード入力メソッドのいくつかのスタイルの中から 1 つを選択することです。

XSetLocaleModifiers() 関数は、現在のロケールの Xlib ロケール・モディファイアを構成するために使用されます。

ロケールとモディファイアを初期化するクライアントの推薦するプロシージャが、ロケールとモディファイアを通知する方法を、以下のソースのうちの 1 つから別々に取得します (数字は優先順位を示します)。

  1. コマンド行オプション

  2. リソース

  3. 空の文字列 (" ")

定義された最初のものが使用されます。


注 -

ロケール・コマンド行オプション、またはロケール・リソースが定義された場合、その影響として、ローカル・ホスト環境のカテゴリ固有の設定をすべて無効にして、指定したロケールにすべてのカテゴリを設定するべきです。


ロケール依存性とモディファイア依存性

国際化対応の Xlib 関数は、ホスト環境により構成された現在のロケールで、XSetLocaleModifiers() 関数により設定された X ロケール・モディファイアにおいて機能するか、その関数に供給される何らかのオブジェクトの作成時に構成されたロケールとモディファイアにおいて機能します。表 5-1 では、それぞれのロケール依存の関数についてロケール依存性とモディファイア依存性を示しています。

表 5-1 ロケール依存性とモディファイア依存性

ロケール 

影響を受ける関数 

対象 

 

ロケール照会 / 構成

 

setlocale

XSupportsLocale

XSetLocaleModifiers

照会されたロケール 

変更されたロケール 

 

リソース

 

setlocale

XrmGetFileDatabase

XrmGetStringDatabase

Xrm データベースのロケール 

XrmDatabase 

XrmPutFileDatabase

XrmLocaleOfDatabase

Xrm データベースのロケール 

 

標準属性の設定

 

setlocale

XmbSetWMProperties

供給されて返されたテキスト 

(環境ロケールの WM_property テキストのいずれか) のエンコーディング

setlocale

XmbTextPropertyToTextList

XwcTextPropertyToTextList

XmbTextListToTextProperty

XwcTextListToTextProperty

供給された / 返されたテキストのエンコーディング 

 

テキスト入力

 

setlocale

XOpenIM

XIM 入力メソッド. 

XIM 

XCreateIC

XLocaleOfIM など

XIC 入力メソッド構成 

照会されたロケール 

XIC 

XmbLookupText

XwcLookupText

キーボード配置 

返されたテキストのエンコーディング 

 

テキスト描画 

 

setlocale

XCreateFontSet

XFontSet のフォントの Charset 

XFontSet  

XmbDrawText,

XwcDrawText など

XExtentsOfFontSet など

XmbTextExtents,

XwcTextExtents など

Xlib エラー

供給されたテキストのロケール 

供給されたテキストのロケール 

ロケール依存メトリクス 

setlocale

XGetErrorDatabaseText 

XGetErrorText 

エラー・メッセージのロケール 

クライアントは、X の関数と C ライブラリ関数の呼び出しのロケールが同じである場合は、X の関数に返されたロケール・エンコード・テキスト文字列が C ライブラリ関数に渡されることが可能である、または C ライブラリ関数の結果の文字列が X の関数に渡されることが可能であると想定しています。

ロケールのエンコーディングが状態に依存する場合は、国際化対応 Xlib の関数によって処理されるすべてのテキスト文字列は、ロケールのエンコーディングの初期状態で開始すると見なされます。Xlib の関数はすべて、現在のロケールや X モディファイアの設定を変更しないかのように動作します (これはつまり、Xlib またはアプリケーションのいずれかによってライブラリ内で提供され、ロケールを変更するか XSetLocaleModifiers() 関数をヌルでない引き数で呼び出す関数はすべて、入力時と終了時に現在のロケール状態を保存および復元しなければならないという意味です)。また、ANSI C ライブラリに準拠する実装の Xlib の関数は、ANSI C の関数 mblen()mbtowc()wctomb()strtok() に関連付けられたグローバルな状態を変更しません。

Xt ロケール管理

Xt ロケール管理には次の 2 つの関数が含まれます。

XtSetLanguageProc

Xt ツールキットの初期化前に、アプリケーションは通常 XtSetLanguageProc() 関数を次のうちどれか 1 つの形式で呼び出します。

XtSetLanguageProc (NULL, NULL, NULL)

注 -

ロケールは、(たとえば XtAppInitialize() 関数を介して) ツールキットが初期化されるまでは、実際には設定されません。したがって、XtSetLanguageProc() 関数と、ツールキットの初期化の後に (たとえば catopen() 関数を呼び出す場合)、setlocale() 関数が必要になるかもしれません。


リソース・データベースは現在のプロセスのロケールに作成されます。画面ごとのリソース・データベースを作成する前のディスプレイ初期化の間に、イントリンシクス関数は、コマンド行かディスプレイごとのリソース指定にあるオプションに応じてロケールを設定するために、指定されたアプリケーション・プロシージャを呼び出します。

アプリケーションにより提供されるコールアウト・プロシージャの型は XtLanguageProc で、形式は次のとおりです。

typedef String(*XtLanguageProc)(displayID,languageID, clientdata);  
Display *displayID;  
String languageID;  
XtPointer clientdata;
displayID

ディスプレイを渡します。

languageID

コマンド行またはサーバのディスプレイごとのリソース指定から取得される初期言語値を渡します。

clientdata

XtSetLanguageProc() 関数への呼び出しで指定された追加のクライアント・データを渡します。

言語プロシージャにより、アプリケーションは、ロケールを XtDisplayInitialize() 関数で決定された言語リソースの値に設定できます。この関数は、以降にリソース・ファイルを読み込むために XtDisplayInitialize() 関数が使用する新しい言語文字列を返します。

最初は、イントリンシクス関数によって言語プロシージャは設定されていません。XtDisplayInitialize() 関数によって使用されるように言語プロシージャを設定するには、XtSetLanguageProc() 関数を使用してください。

XtLanguageProc XtSetLanguageProc(applicationcontext, procedure, clientdata) 
XtAppContext applicationcontext;  
XtLanguageProc procedure;  
XtPointer clientdata;
applicationcontext

言語プロシージャが使用されるアプリケーション・コンテキストか、またはヌルの値を指定します。

procedure

言語プロシージャを指定します。

clientdata

言語プロシージャが呼び出されたときに言語プロシージャに渡される追加のクライアント・データを指定します。

XtSetLanguageProc() 関数は、XtDisplayInitialize() 関数から呼び出される言語プロシージャを、指定されたアプリケーション・コンテキストで初期化される以降のすべてのディスプレイのために設定します。applicationcontext パラメータがヌルの場合、指定された言語プロシージャは、呼び出しプロセスによって作成されたすべてのアプリケーション・コンテキスト (将来作成されるかもしれないアプリケーション・コンテキストも含みます) に登録されます。procedure パラメータがヌルの場合、デフォルトの言語プロシージャが登録されます。XtSetLanguageProc() 関数は、前に登録されていた言語プロシージャを返します。言語プロシージャが登録されていなかった場合の戻り値は不定です。しかし、その戻り値が XtSetLanguageProc() 関数以降の呼び出しに使用される場合は、デフォルトの言語プロシージャが登録されることになります。

デフォルトの言語プロシージャは次のことを行います。

クライアントはこの機構を利用して、次の例のように XtDisplayInitialize() 関数の前に XtSetLanguageProc() 関数を呼び出すことにより、ロケールを確立できます。

Widget top; 
XtSetLanguageProc(NULL, NULL, NULL);  
top = XtAppInitialize( ... ); 
...

XtDisplayInitialize

XtDisplayInitialize() 関数は、まず指定されたディスプレイに使用される言語文字列を決定し、ディスプレイとホストとアプリケーションの組み合わせのためのアプリケーションのリソース・データベースを、次のソースから読み込みます (数字は優先順位を示します)。

  1. アプリケーション・コマンド行 (argv)

  2. ローカル・ホストのホストごとのユーザ環境リソース・ファイル

  3. サーバのリソース属性またはローカル・ホストのユーザ選択リソース・ファイル

  4. ローカル・ホストのアプリケーション固有ユーザ・リソース・ファイル

  5. ローカル・ホストのアプリケーション固有クラス・リソース・ファイル

XtDisplayInitialize() 関数は、指定された各 display パラメータに対して固有のリソース・データベースを作成します。データベースが作成されると、display パラメータの言語文字列が以下のアクションのシーケンスと同じ方法で決定されます。

XtDisplayInitialize() 関数は、まず一時的なデータベースを 2 つ作成します。1 番目のデータベースはコマンド行を解析することにより構築されます。2 番目のデータベースは XResourceManagerString() 関数が返す文字列から構築されるか、あるいは XResourceManagerString() 関数がヌルの値を返す場合は、ユーザのホーム・ディレクトリのリソース・ファイルの内容から構築されます。このようなユーザ選択リソース・ファイルの名前は $HOME/.Xdefaults です。

コマンド行から構築されるデータベースが、リソース name.xnlLanguage とクラス class.XnlLanguage で照会されます。この nameclass は指定されたアプリケーション名とアプリケーション・クラスです。このデータベース照会が失敗した場合、サーバのリソース・データベースが照会されます。この照会も失敗した場合は、言語は環境から決定されます。環境からの言語の決定は、LANG 環境変数の値を取り出すことで実行されます。言語文字列が見つからない場合は、空の文字列が使用されます。

アプリケーション固有のクラス・リソース・ファイル名は、アプリケーションのクラス名から構築されます。アプリケーションのクラス名は、アプリケーションのインストール時に通常サイト・マネージャによってインストールされるローカライズされたリソース・ファイルを指します。このファイルは、XtResolvePathname() 関数をパラメータ (displayID, applicationdefaults, NULL, NULL, NULL, NULL, 0, NULL) で呼び出すと見つけられます。このファイルはアプリケーションが正しく機能するのに必要な場合があるので、アプリケーション開発者が提供すべきです。クラス・リソース・ファイルがないときにリソースのセットを最小限しか必要としないシンプルなアプリケーションは、XtAppSetFallbackResources() 関数でフォールバック・リソース指定を宣言できます。

アプリケーション固有のユーザ・リソース・ファイル名はユーザ固有のリソース・ファイルを指し、アプリケーションのクラス名から構築されます。このファイルは、アプリケーションによって所有され、ふつうユーザのカスタマイズを格納しています。このファイルは、XtResolvePathname() 関数をパラメータ (displayID, NULL, NULL, NULL, path, NULL, 0, NULL) で呼び出すと見つけられます。この path はオペレーティング・システム固有の方法で定義されます。path 変数は、XUSERFILESEARCHPATH 環境変数が設定されている場合は、その値に定義されます。そうでない場合は、デフォルトはベンダの定義した値です。

結果のリソース・ファイルが存在する場合は、そのファイルはリソース・データベースにマージされます。このファイルはアプリケーションと共に提供されるか、またはユーザによって作成されます。

言語の決定の間にサーバのリソース属性かユーザ・リソース・ファイルから作成される一時的なデータベースが、リソース・データベースにマージされます。サーバのリソース・ファイルは完全にユーザによって作成されるので、ディスプレイに依存しないユーザ選択とディスプレイ固有のユーザ選択が含まれています。

ユーザの環境リソース・ファイルが存在する場合は、それがリソース・データベースに読み込まれ、マージされます。このファイル名はユーザおよびホスト固有です。ユーザの環境リソース・ファイル名は、絶対パス名としてユーザの XENVIRONMENT 環境変数の値から構築されます。この環境変数が存在しない場合、XtDisplayInitialize() 関数はユーザのディレクトリで .Xdefaults-host ファイルを検索します。この host はアプリケーションが実行されるマシン名です。結果のリソース・ファイルが存在する場合は、リソース・データベースにマージされます。環境リソース・ファイルには、サーバのリソース・ファイルでそれらのユーザ選択指定を補足するプロセス固有のリソース仕様が指定されることが予想されます。

フォント管理

国際化対応テキストの描画は、テキストのロケールの必要に応じて、1 つ以上のフォントのセットを使用して行われます。

システム環境内の国際化対応描画の方法は 2 つあり、それによりクライアントは静的な出力ウィジェット (たとえば XmLabel) の中から 1 つを選択したり、またはその他のプリミティブ関数で描画を行うために DrawingArea ウィジェットを選択することができます。

静的な出力ウィジェットは、テキストの XmString への変換を必要とします。

次に、Xlib ルーチンと Xlib 関数を使用してフォントを管理する機構を説明します。

フォント・セットの作成および解放

Xlib 国際化対応テキストの描画は、テキストのロケールの必要に応じて、1 つ以上のフォントのセットを使用して行われます。フォントは、クライアントとロケールに必要な charset によって供給されるベース・フォント名のリストにしたがって読み込まれます。XFontSet はオペーク型です。

フォント・セット・メトリクスの取得

国際化対応テキスト描画関数のメトリクスは、標準描画方向によって定義されます。標準描画方向とは、文字列の起点にある文字が次の文字へと進んでいくデフォルトの方向です。現在 Xlib インタフェースは、左から右の標準描画方向だけをサポートするよう定義されています。描画の起点は、テキストを描画するときに描画関数へ渡される位置です。ベースラインは、描画の起点を通って標準描画方向と並行に描画される線です。文字インクは、フォアグラウンド・カラーに塗られるピクセルであり、行間または文字間のスペースやイメージ・テキストのバックグラウンド・ピクセルは含みません。

描画関数によりテキスト方向の暗示的なコントロールが許されており、ロケール固有の文字列の字句的な分析に応じて標準描画方向に沿って文字が受け渡しされる順序を逆にすることができます。

文字の受け渡し順に関係なく、すべての文字の起点は、描画の起点の標準描画方向側にあります。特定の文字イメージの画面位置は、XmbTextPerCharExtents() 関数または XwcTextPerCharExtents() 関数で決定されます。

描画関数は、コンテキストに依存した受け渡しを実現できます。コンテキストに依存した受け渡しにおいて、文字列のために描画されるグリフは、単に個々の文字を表すグリフの組み合わせではありません。XmbDrawString() 関数で描画される 2 文字の文字列は、その 2 文字が XmbDrawString() 関数への別々の呼び出しで描画された場合とは異なる受け渡しの方法を取ります。クライアントが以前に描画された文字列に文字を追加または挿入する場合、正しい受け渡しを得るために、クライアントは隣接する文字をいくつか再描画する必要があるかもしれません。

描画関数は、改行文字、タブその他の制御文字を認識しません。非印刷文字 (スペースを除く) の描画時の動作は実装に依存します。テキストの流れの中で制御文字を解釈するのはクライアントの責任です。

コンテキストに依存した受け渡しを見つけ出すには、XContextDependentDrawing() 関数を使用します。XExtentsOfFontSet() 関数は、XFontSet を指定された最大エクステント構造体を取得します。XmbTextEscapement() 関数と XwcTextEscapement() 関数は、値として指定されたテキストのピクセル単位のエスケープを取得します。XmbTextExtents() 関数と XwcTextExtents() 関数は、文字列のイメージの総合割り当てボックスとロジック割り当てボックスを取得します (それぞれの引き数は overall_ink_returnoverall_logical_return)。XmbTextPerCharExtents() 関数と XwcTextPerCharExtents() 関数は、指定されたフォント・セットに読み込まれたフォントを使用して、指定されたテキストの各文字の寸法を返します。

ローカライズされたテキストの描画

この節で定義される関数は、描画範囲内の指定された位置にテキストを描画します。そのような関数は、単一のフォントではなくフォント・セットと共に動作する点と、文字列のバイトを直接フォント索引として処理するのではなくフォント・セットのロケールに基づいてテキストを解釈する点を除いて、XDrawText()XDrawString()XDrawImageString() 関数に似ています。BadFont エラーが生成された場合、障害になっている文字の前の文字までが描画されています。

テキストは、指定されたフォント・セットにロードされたフォントを使用して描画されます。グラフィック・コンテキスト (GC) のフォントは無視され、関数によって変更されることがあります。すべてのフォントが、ある幅の規則に準拠するかどうかの妥当性検査は行われません。

指定内で描画可能な複数のフォント・セットを使ってテキストを描画するには、XmbDrawText() 関数か XwcDrawText() 関数を使用してください。指定された drawable 内で単一のフォント・セットを使ってテキストを描画するには、XmbDrawString() 関数か XwcDrawString() 関数を使用してください。指定された drawable 内で単一のフォント・セットを使ってイメージ・テキストを描画するには、XmbDrawImageString() 関数か XwcDrawImageString() 関数を使用します。

ローカライズされたテキストの入力

次に、国際化対応テキストの入力に使用する Xlib とデスクトップの機構について説明します。Motif の Text[Field] ウィジェットを使用している場合、またはテキスト入力に XmIm API を使用している場合は、この節でバックグラウンド情報が提供されます。しかし、この節の説明はアプリケーションの設計やコードの実行には影響しません。文字入力が低レベルの Xlib 呼び出しでキーボードからどのように処理されるかに興味がない場合は、「ローカライズされたテキストのクライアント間通信規約」に進んでください。

Xlib 入力メソッドの概要

この節は、国際化対応テキスト入力に関して使用される用語と概念の定義、また Xlib が提供する機構の、想定されている使用方法の簡単な概要を提供します。

世界の多数の言語が、語を形成するために、記号 (文字) の小規模なセットから成るアルファベットを使用します。アルファベット言語でテキストをコンピュータに入力するために、ユーザは通常アルファベットに対応するキー記号の付いたキーボードを持っています。場合によっては、アルファベット言語のうち少数の文字がキーボードにないことがあります。ラテンアルファベットに基づく言語を話す多くのコンピュータ・ユーザは、英語ベースのキーボードしか持っていません。キーボード上に直接存在しない文字を入力するには、複数のキーを組み合わせて押す必要があります。そのような文字を入力するために、ヨーロッパの入力メソッド、構成入力メソッド、デッドキー入力メソッドなどで知られる多数のアルゴリズムが開発されました。

日本語は、音声記号のセットを持つ言語の一例です。各音声記号は特定の音を表します。日本語には音声記号のセットが 2 つあります (カタカナひらがな)。一般に、カタカナは外来語の表記に使用し、ひらがなは通常の日本語の表記に使用します。この 2 つのシステムはまとめて仮名と呼ばれます。ひらがなは 83 文字、カタカナは 86 文字あります。

韓国語にも、ハングルと呼ばれる音声記号のセットがあります。基礎となる 24 の音声記号 (子音 14、母音 10) は、それぞれが特定の音を表します。1 つの音節は 2 〜 3 の部分から成ります (最初の子音、母音、任意で最後の子音)。ハングルでは、音節をテキスト処理の基本単位として使用することが可能です。たとえば、削除操作は音声記号または音節単位に行うことができます。韓国語のコード・セットにはこのような音節が数千あります。ユーザは、入力したい語の音節を形成する音声記号を入力します。ディスプレイは各音声記号が入力されるにつれて変化するかもしれません。たとえば、ある音節の 2 番目の音声記号が入力されると、1 番目の音声記号の形とサイズが変わることがあります。同様に、3 番目の音声記号が入力されると、前の 2 つの音声記号の形とサイズが変わることがあります。

すべての言語がアルファベットか音声システムだけに頼っているわけではありません。日本語と韓国語を含む一部の言語は、表意文字による記述システムを採用しています。表意文字システムでは、記号の小規模なセットを使用してそれらの記号を組み替えて複数の語を作成するのではなく、それぞれの語が 1 つ (または複数) の一意の記号から成ります。そのような記号は非常に多く、中国語の表意文字システムである漢字では約 50,000 が識別されます。

コンピュータでの表意文字システムの使用には主に 2 つの考慮しなければならない点があります。第一に、日本、中華人民共和国、韓国の標準コンピュータ文字セットには約 8,000 の文字があり、台湾の場合は 15,000 〜 30,000 の文字があり、そのような文字は、1 文字を表現するのに 2 バイト以上が必要だということです。第 2 に、指定された言語のすべての表意文字を網羅するキーボードを用意することは明らかに不可能であり、したがって、適正な数のキーを持つキーボードを使用できるような文字入力の機構が必要になるということです。通常、そのような入力メソッドは音声体系に基づきますが、文字のグラフィカル属性に基づく方法もあります。

日本では仮名と漢字の両方を使用します。韓国ではハングルと時々ハンジャを使用します。これから、日本、韓国、中華人民共和国、台湾での表意文字の入力について考察します。

日本では、仮名か英文字のいずれかを入力し、漢字に変換するための範囲を (時には自動的に) 選択します。複数の漢字が同じ音声表現を持つ場合もあります。そのような場合は、文字列を入力すると文字のメニューが表示され、ユーザは適切な候補を選択しなければなりません。選択の必要がない場合やすでに希望する表現である場合は、入力メソッドはただちに置換を実行します。ラテン文字が仮名または漢字に変換されることをローマ字変換と呼びます。

韓国では、通常は韓国語のテキストをハングル形式だけにすることが可能ですが、ハンジャ起源の語はハングルでなくハンジャで記述することを選ぶ人々もいます。ハングルからハンジャへ変換するには、変換の範囲を選択し、そのあとユーザは日本語のところで説明したのと同じ基本的な方法を取ります。

日本と韓国には広く普及した音声学上の記述システムがあるため、それらの国々で表意文字をコンピュータに入力する方法はかなり標準化されています。キーボード・キーには英文字と音声記号が書いてあり、ユーザはその 2 つのセットを切り替えることができます。

中国語の場合は状況が異なります。当局が奨励するピンインと呼ばれる音声システムがありますが、中国語のテキスト入力メソッドには統一されたものがありません。中国語の音声学的な分解 (ピンインその他) を使用するベンダもあれば表意的な分解を使用するベンダもあり、さまざまな処理系とキーボード配列が存在します。知られている手法は約 16 種類ありますが、どれも明確な標準ではありません。

また実際には、繁体字 (伝統的な中国文字) と簡体字という 2 種類の表意文字セットが使用されています。数年前、中華人民共和国は一部の表意文字を簡素化して全体的に無駄を排除するキャンペーンに着手しました。この方針の下に、文字は 5 年ごとに簡素化されます。文字はすでに何回か改訂されており、その結果として規模が縮小して単純になったセットが簡体字を形成しています。

入力メソッドのアーキテクチャ

前の節に示したとおり、数多くの異なる入力メソッドが今日使用されており、それぞれは言語、文化、歴史によって変化します。多くの入力メソッドで共通する機能は、ユーザは複数のキーストロークを入力して 1 つの文字 (または文字のセット) を構成できるということです。キーストロークから文字を構成するプロセスをプリエディットといいます。プリエディットには、複雑なアルゴリズムと、実質的なリソースを含む大規模な辞書が必要です。

入力メソッドには、ユーザに候補を示したり、辞書を表示したりするために、実際のキーストロークをフィードバックする 1 つ以上の領域が必要なことがあります。次に、該当する入力メソッド領域を示します。

ステータス領域

物理的なキーボード上にある発光ダイオード (LED) の論理的な拡張部として使用されます。ユーザにとって重要な入力メソッドの初期状態を表示するためのウィンドウです。ステータス領域は、テキスト・データおよびビットマップまたは、それらの組み合わせから成ります。

プリエディット領域

クライアントがデータを処理する前に使用されている言語のための中間テキストを表示するために使用されます。

補助領域

ポップアップ・メニューと、入力メソッドに必要なダイアログ・ボックスのカスタマイズに使用されます。どの入力メソッドにも複数の補助領域が存在する可能性があります。補助領域は入力メソッドにより、クライアントに依存しないで管理されます。複数の補助領域は、入力メソッドによって管理される別々のダイアログだと見なされます。

プリエディットには、さまざまなユーザの対話形式があります。次に、Xlib がサポートするプリエディット形式を示します。

OnTheSpot

データは直接アプリケーション・ウィンドウに表示されます。アプリケーション・データは、プリエディット・データが挿入点に表示されるように移動されます。

OverTheSpot

データは挿入点上に置かれたプリエディット・ウィンドウに表示されます。

OffTheSpot

プリエディット・ウィンドウはアプリケーション・ウィンドウの内側に表示されますが、挿入点ではありません。しばしば、この型のウィンドウはアプリケーション・ウィンドウの底部に置かれます。

Root

プリエディット・ウィンドウは RootWindow の子です。

移植性の高いアプリケーションには世界中のすべての言語の入力メソッドが必要だとすると、多くのコンピューティング・リソースが必要になります。それを避けるために、Xlib の設計目標は、アプリケーションが別々のプロセスに位置する入力メソッドと通信できるようにすることです。そのようなプロセスを入力サーバといいます。アプリケーションが接続するサーバは、アプリケーション起動時の環境、ユーザの言語、実際に使用されるエンコーディングに依存します。入力メソッドとの接続はロケール依存であると言われます。同様にユーザ依存でもあります。たとえば、ある言語が指定されると、ユーザは入力メソッドのユーザ・インタフェースの形式をある程度選択できます (選択肢がある場合)。

入力サーバの使用は通信のオーバヘッドを暗に意味しますが、アプリケーションは再リンクなしでマイグレーションできます。入力メソッドは、入力サーバへ通信するトークンとして、またはローカルなライブラリとして実現できます。

クライアントが入力メソッドと通信するために使用するアブストラクトは、XIM のデータ型で表されるオペーク・データ構造体です。このデータ構造体は、指定されたディスプレイに入力メソッドを開く XOpenIM() 関数によって返されます。このデータ構造体の以降のオペレーションは、クライアントと入力メソッドの間のすべての通信をカプセル化します。X クライアントが、入力メソッドを使用するためにネットワーキング・ライブラリや自然言語パッケージを使用する必要はありません。

1 つの入力サーバは、1 つ以上のエンコーディング・スキーマをサポートし、1 つ以上の言語に使用することができます。しかし、1 つの入力メソッドから返された複数の文字列は、常に XIM オブジェクトに関連付けられた (単一の) ロケールでエンコードされています。

入力コンテキスト

Xlib は、テキスト入力のマルチスレッド状態を管理する機能を提供します。クライアントが複数のウィンドウを使用していて、各ウィンドウには複数のテキスト入力領域があり、ユーザはそれらをいつでも切り替えられるという可能性もあります。特定の入力スレッドの状態を表すアブストラクトを入力コンテキストといいます。入力コンテキストは Xlib では XIC で表されます。図 5-1 を参照してください。

図 5-1 入力メソッドと入力コンテキスト

Graphic

入力コンテキストは、クライアントと入力メソッドの間の状態、属性、通信のセマンティクスを保存するアブストラクトです。入力コンテキストは、入力メソッド、返される文字列のエンコーディングを指定するロケール、クライアント・ウィンドウ、内部状態の情報、さまざまな配置や表示の特徴の組み合わせです。入力コンテキストの概念は、グラフィック出力用にグラフィック・コンテキスト・アブストラクトが定義した入力にいくらか一致します。

1 つの入力コンテキストは、1 つの入力メソッドに属します。異なる入力コンテキストは、たぶん同じクライアント・ウィンドウで、同一の入力メソッドに関連付けることが可能です。XIC は、XCreateIC() 関数によって作成され、XIM 引き数を指定してそれが存在する間は入力コンテキストを入力メソッドに密接に関連付けます。入力メソッドが XCloseIM() 関数で閉じられる場合、密接に関連付けられていたどの入力コンテキストも再使用できません (入力メソッドを閉じる前に削除されることが望ましいです)。

複数のテキスト入力領域を持つクライアント・ウィンドウの例を考慮し、アプリケーションのプログラマは次の事項を選択できます。

アプリケーション設計者は、アプリケーションのニーズに応じて、入力コンテキストの範囲を単一か複数か選択できます。

キーボード入力

入力メソッドから文字を取得するには、クライアントはその入力メソッドから作成された入力コンテキストと共に XmbLookupString() 関数か XwcLookupString() 関数を呼び出さなければなりません。ロケールとディスプレイの両方とも、開かれたときに入力メソッドに割り当てられ、入力コンテキストはこのロケールとディスプレイを引き継ぎます。XmbLookupString() 関数または XwcLookupString() 関数によって返されるすべての文字列は、そのロケールでエンコードされます。

Xlib フォーカス管理

XmbLookupString() 関数または XwcLookupString() 関数が使用される各テキスト入力領域には、関連付けられた入力コンテキストがあります。

アプリケーションのフォーカスがテキスト入力領域に移動するとき、アプリケーションは、その領域に関連付けられた入力コンテキストに、入力コンテキストのフォーカスを設定しなければなりません。入力コンテキストのフォーカスは、XSetICFocus() 関数を適切な入力コンテキストと共に呼び出すことで設定されます。

また、アプリケーションのフォーカスがテキスト入力領域の外側へ移動するときは、アプリケーションは XUnsetICFocus() 関数を呼び出して、関連付けられた入力コンテキストのフォーカスを設定解除すべきです。最適化のために、XSetICFocus() 関数が 2 つの異なる入力コンテキストで続けて呼び出された場合、2 回目のフォーカス設定の時点で自動的に 1 回目のフォーカスが設定解除されます。


注 -

入力コンテキストの設定と設定解除を正しく行うためには、アプリケーション・レベルのフォーカスの変更を追跡する必要があります。そのようなフォーカスの変更は、必ずしも X サーバのフォーカスの変更に対応しません。


単一の入力コンテキストが複数のテキスト入力領域への入力に使用される場合は、フォーカス・ウィンドウが変更されるたびに、その入力コンテキストのフォーカス・ウィンドウを設定する必要があります。

Xlib ジオメトリ管理

ほとんどの入力メソッドのアーキテクチャにおいて (OnTheSpot は著しい例外ですが)、入力メソッドは自身のデータの表示を行います。より見やすい位置においておくために、入力メソッド領域をクライアント内に埋め込むことが望ましい場合が多くあります。このためには、クライアントが入力メソッドにスペースを割り当てる必要があるかもしれません。Xlib は、クライアントが入力メソッド領域のサイズと位置を提供できるようサポートします。ジオメトリ管理のためにサポートされている入力メソッド領域は、ステータス領域とプリエディット領域です。

入力メソッドウィンドウのジオメトリ管理の元となる基本概念は、クライアント (またはツールキット) と入力メソッドの間で責任を適切に分割することです。責任の分割は次のとおりです。

入力メソッドはクライアントにサイズを提案することはできますが、位置を提案することはできません。入力メソッドがサイズを決定することはなく、指定されたサイズを受け入れなければなりません。

クライアントは、入力メソッドのジオメトリ管理を提供する前に、ジオメトリ管理が必要かどうかを判別しなければなりません。入力メソッドは、XGetIMValues() 関数によって返された XIMStyles 値に XIMPreeditArea() 関数か XIMStatusArea() 関数を設定することにより、ジオメトリ管理の必要性を示します。クライアントは、入力メソッドへジオメトリ管理を提供することを決定するとき、XNInputStyle 値を XIC に設定することにより、その決定を示します。

クライアントが入力メソッドでジオメトリ管理を行うことを確立した後、クライアントはジオメトリを入力メソッドと交渉しなければなりません。ジオメトリは次の手順で交渉されます。

ジオメトリ管理を実行するクライアントは、別の IC 値を設定すると、入力メソッドが希望するジオメトリに影響が出るかもしれないことを知っておく必要があります。たとえば、XNFontSet 値と XNLineSpacing 値は、入力メソッドが希望するジオメトリを変更する可能性があります。クライアントは、必要に応じて入力メソッドのウィンドウのジオメトリを再度ネゴシエートする責任があります。

さらに、入力メソッドがジオメトリ変更を起動するための、ジオメトリ管理コールバックが提供されます。

イベント・フィルタリング

フィルタリング機構により、入力メソッドが、クライアントに透過的に X イベントを取り込めるようになっています。XmbLookupString() 関数または XwcLookupString() 関数を使用しているツールキット (またはクライアント) は、イベント処理機構のある時点で、入力メソッドに必要なイベントが確実に入力メソッドによってフィルタリングされるように、フィルタを呼び出すことになっています。フィルタがない場合、クライアントは、入力メソッドが正しく機能するために必要なイベントを受け取って破棄できます。そのようなイベントの例を次に示します。

クライアントは、XIC の XNFilterEvents 値を取得し、イベント・マスクを持つクライアント・ウィンドウのイベント・マスクに追加することを期待されます。このマスクは 0 である可能性があります。

コールバック

OnTheSpot 入力メソッドが実現される場合、クライアントだけがプリエディット・データを挿入または削除でき、場合により既存のテキストをスクロールできます。つまり、キーストロークのエコーは、入力メソッドのロジックと密接に結合され、クライアント自身によって達成されなければなりません。

キーストロークが入力されると、クライアントは XmbLookupString() 関数か XwcLookupString() 関数を呼び出します。この時点で、OnTheSpot の場合は、プリエディットでのキーストロークのエコーはまだ行われていません。入力文字を処理するクライアントのロジックに戻る前に、検索関数が、新しいキーストロークを挿入するためのエコーを行うロジックを呼び出さなければなりません。これまでに入力されたキーストロークが文字を形成する場合は、入力されたキーストロークは削除される必要があり、構成された文字が返されます。結果として、クライアント・コードによって呼び出されている間、入力メソッドのロジックは戻る前にクライアントにコールバックしなければなりません。クライアント・コード、つまりコールバック・ルーチンは、入力メソッドのロジックから呼び出されます。

入力メソッドのロジックがクライアントにコールバックしなければならない場合が数多くあります。その 1 つ 1 つの場合が、定義済みコールバック・アクションに関連付けられています。クライアントが、各入力コンテキスト別に、どのコールバックがどのアクションで呼び出されるかを指定することが可能です。

また、ステータス情報をフィードバックするためのコールバックと、入力メソッドへのジオメトリ要求を開始するコールバックも提供されます。

X サーバ・キーボード・プロトコル

この節では、サーバとキーボードのグループについて説明します。

keysym は、キーキャップ上の記号のエンコーディングです。サーバの keysym マッピングの目標は、物理的なキーボードの実際のキーキャップを反映することです。ユーザは、xmodmap コマンドを希望する新しいマッピングで実行することにより、キーボードを再定義することができます。

X Version 11 Release 4 (X11R4) では、サーバでのバイリンガル・キーボードの定義が可能です。その機能は次のとおりです。

keysym のリストは、各キー・コードに関連付けられています。対応するキーの記号のセットを説明します。

明示的 void 要素がリストで希望されているときには VoidSymbol 値が使用できます。

リストの最初の 4 つの要素は、2 つの keysym のグループに分かれます。グループ 1 には 1 番目と 2 番目の keysym が含まれ、グループ 2 には 3 番目と 4 番目の keysym が含まれます。各グループ内の 2 番目の要素が NoSymbol の場合は、そのグループは 2 番目の要素が 1 番目の要素と同じであるかのように処理されます。ただし、1 番目の要素が、小文字と大文字両方の形式が定義されたアルファベット keysym K である場合は例外です。そのような場合、グループは、1 番目の要素が小文字形式の K で 2 番目の要素が大文字形式の K であるかのように処理されます。

イベントから keysym を取得するための標準的な規則は、グループ 1 とグループ 2 の keysym しか使用しません。リストのその他の keysym の解釈はここでは指定されません。どのグループを使用するかはモディファイアの状態が決定します。グループ間の切り替えは、MODE SWITCH という名前の keysym でコントロールされ、その keysym をあるキー・コードに接続し、そのキー・コードを Mod1 〜 Mod5 のモディファイアのうちのいずれかに接続することで実行されます。このようなモディファイアを「グループモディファイア」と呼びます。どのキー・コードに対しても、グループ 1 はグループ・モディファイアがオフの時に使用され、グループ 2 はグループモディファイアがオンの時に使用されます。

グループ内で、使用する keysym もやはりモディファイアの状態により決定されます。1 番目の keysym は、Shift モディファイアと Lock モディファイアがオフの時に使用されます。2 番目の keysym は、Shift モディファイアがオンの時、Lock モディファイアがオンの時、2 番目の keysym が大文字のアルファベットの時、または Lock モディファイアがオンで ShiftLock と解釈される時に使用されます。そうでない場合は、Lock モディファイアがオンで CapsLock と解釈される時に、Shift モディファイアの状態は初めて keysym 選択のために適用されます。keysym が小文字のアルファベットの場合は、対応する大文字の keysym が代わりに使用されます。

ジオメトリはベンダ固有の方法で定義されるかもしれませんが、キー上の記号の空間的なジオメトリは、keysym リスト順には定義されません。サーバはキー・コードと keysym 間のマッピングを使用しません。むしろ、サーバはクライアントによる読み書きのためにだけ、マッピングを格納します。

Lock という名前の KeyMask モディファイアは、CapsLock キーか ShiftLock キーのいずれかにマップされますが、どちらにマップされるかは、アプリケーション固有の決定か、ユーザ固有の決定か、あるいはその両方に委ねられます。しかし、対応するキー・コードに関連付けられた keysym に応じて、ユーザがマッピングを決定することをお勧めします。

ローカライズされたテキストのクライアント間通信規約

次の情報は、コンポーネントがテキスト・データと通信するために ICCC (クライアント間通信規約) を使用する方法を説明し、ICCC 選択が実行される方法を理解するためのガイドラインを示します。XmText ウィジェット、XmTextField ウィジェット、dtterm コマンドはこのガイドラインを厳守しています。

ツールキットは国際化対応 ICCC 準拠のために拡張されています。XmTextXmTextField、およびdtterm の選択機構は、どの選択トランザクションでもデータとデータ・エンコーディングが確実に適切に一致するように拡張されています。これには標準的なカット・アンド・ペースト操作が含まれます。

アプリケーションの記述にツールキットを使用する開発者に対して、ツールキットはアプリケーションを ICCC 準拠にすることができます。しかし、ツールキット・ベースのアプリケーションと通信するアプリケーションを開発するためにその他の ICCC に準拠していないツールキットを使用する可能性のある開発者に対しては、以下の説明が役に立ちます。

所有側の選択

どんな所有側でも、XA_TARGETS がローカライズされたテキストで要求された場合、少なくとも次のアトム・リストを返します。

XA_TEXT が要求されると、所有側はテキストを属性セットのエンコーディング型と共に現在のロケールのコード・セットへそのまま返します (データ変換は行われません)。ロケールのコード・セットの名前を表すアトムが作成されます。

COMPOUND_TEXT が要求されると、所有側はローカライズされたテキストをコンパウンド・テキストに変換し、それを属性型 COMPOUND_TEXT で渡します。

XA_STRING が要求されると、所有側はローカライズされたテキストを XA_STRING に変換しようとします。テキスト文字列の中に XA_STRING に変換できない文字がある場合は、このオペレーションは失敗します。


注 -

XA_STRING は ISO8859-1 であるように定義されています。


選択の要求側

要求側は、テキスト・データが選択の所有側と通信されるとき、まず XA_TARGET を要求します。

次に、要求側は次のうち 1 つのアトムを次の優先順位で検索します。

要求側のロケールのコード・セットがターゲットの 1 つに一致する場合は、要求側はそのコード・セットを表すアトムを使用して要求を実行します。XA_TEXT アトムは、その他のアトムが見つからない場合にだけ使用されます。所有側が自分のエンコーディングを表す型と共に属性を返すので、要求側は自分のロケールのコード・セットに変換しようとします。

COMPOUND_TEXT または XA_STRING の型が要求された場合、要求側は XmbTextPropertyToTextList() 関数か XwcTextPropertyToTextList() 関数を使用して、テキストを要求側の現在のロケールのコード・セットに正しく変換しようとします。このような関数は、所有側クライアントと要求側クライアントが異なるコード・セットの下で実行しているときに使用されます。

COMPOUND_TEXT または XA_STRING から変換する場合、すべてのテキスト・データが変換を保証されるわけではありません。所有側と要求側の間で共通の文字だけが変換されます。

XmClipboard

XmClipboard も、XmText ウィジェットと XmTextField ウィジェットと共に、ICCC 準拠になるよう拡張されています。XmText ウィジェットと XmTextField ウィジェットを介してテキストがクリップボード上に置かれるとき、次の ICCC プロトコルが実行されます。

XmText ウィジェットと XmTextField ウィジェットを介してテキストがクリップボードから取り出されるとき、そのテキストは COMPOUND_TEXT または XA_STRING から現在のロケールのエンコーディングに変換されます。クリップボードのすべてのテキストは、コンパウンド・テキスト形式か文字列形式のいずれかであると想定されます。


注 -

テキストがクリップボード上に直接置かれるとき、アプリケーションは、形式またはアトム形式のエンコーディング型を、クリップボードに置くテキストと共に指定する必要があります。同様に、テキストがクリップボードから直接取り出される場合も、取り出す側のアプリケーションは、クリップボードのデータがどのようにエンコードされているかを見るために形式を確認して、適切なアクションを取る必要があります。


ウィンドウ・マネージャへウィンドウのタイトルとアイコン名を渡す

VendorShell クラスの XtNtitleEncoding リソースと XtNiconNameEncoding リソースのデフォルトは、None に設定されます。これは libXm.a ライブラリ使用時にのみ実行されます。libXt.a ライブラリはリソースのデフォルトとして XA_STRING を維持します。

これは、テキスト (タイトルとアイコン名) がローカライズされているという前提のもと、デフォルトで XmNtitle リソースと XmNiconName リソースがコンパウンド・テキストのような標準 ICCC 形式に変換されるように実行されます。

ユーザは XtNtitleEncoding リソースと XtNiconNameEncoding リソースを設定しない方が良いと思われます。その代わりに、XtNtitle リソースと XtNiconName リソースが、必ず実行中のクライアントの現在アクティブなロケールのエンコーディングでエンコードされた文字列であるようにしてください。None 値が使用される場合は、ツールキットはローカライズされたテキストを標準の ICCC 形式に変換します (通信されるエンコーディングは COMPOUND_TEXT または XA_STRING です)。 XtNtitleEncoding リソースと XtNiconNameEncoding リソースが設定されている場合は、 XtNtitle リソースと XtNiconName リソースはどんな方法でも変換されず、指定されたエンコーディングでウィンドウ・マネージャに通信されます。

通信されているウィンドウ・マネージャが ICCC 準拠だと想定すると、そのウィンドウ・マネージャはエンコーディング型 COMPOUND_TEXT か、XA_STRING か、あるいはその両方を使用できます。

XmBulletinBoard ウィジェット・クラスの XmNdialogTitle リソースを設定するとき、charset セグメントに制限があることに注意してください。X コンソーシアムの標準コンパウンド・テキスト・エンコーディングではない charset か、XmFONTLIST_DEFAULT_TAG に関連付けられていない charset の場合、テキスト・セグメントはローカライズされたテキストとして処理されます。ローカライズされたテキストは、ウィンドウ・マネージャに通信される前に、コンパウンド・テキストか、ISO8859-1 に変換されます。

ウィンドウ・マネージャは、クライアントから渡されたクライアントのタイトルとアイコン名を、現在のロケールのエンコーディングに常に変換できるように拡張されています。XmStringXmFONTLIST_DEFAULT_TAG 識別子を使用して作成されます。このように、クライアントのタイトルとアイコン名は、常にウィンドウ・マネージャのフォント・リストのデフォルトのフォント・リスト・エントリで描画されます。


注 -

これにより、コード・セットは異なるが文字セットが似ているクライアントが、タイトルをウィンドウ・マネージャに通信することが可能になります。たとえば、PC コード・クライアントと ISO8859-1 クライアントの両方が、ウィンドウ・マネージャのコード・セットに関係なくタイトルを表示できます。


メッセージ

システム環境ツールキットに基づくアプリケーションを国際化対応にする作業で、アプリケーションのソース内にハードコードされたロケール固有のデータがないことが重要な場合があります。一般的なロケール固有の項目の 1 つに、標準 I/O (入出力) のアプリケーションによって返される (エラーおよび警告) メッセージがあります。

一般的に、システム環境ツールキット・ウィジェットまたはガジェットを介してユーザに表示されるエラーおよび警告メッセージの場合、メッセージはすべてメッセージ・カタログを介して外側に置く必要があります。

ツールキットのコンポーネントを介して表示されるダイアログ・メッセージの場合、メッセージはすべてローカライズされたリソース・ファイルを介して外側に置く必要があります。これは、XmLabel クラスと XmPushbutton クラスの XmNlabelString リソースまたはウィンドウのタイトルのようなリソースをローカライズするのと同じ方法で実行されます。

たとえば、警告メッセージが XmMessageBox ウィジェット・クラスを介して表示される場合、XmNmessageString リソースをアプリケーションのソースコード内でハードコードすることはできません。代わりに、このリソースの値はメッセージ・カタログから取り出す必要があります。異なる複数のロケールで実行すると想定された国際化対応アプリケーションの場合、サポートされる各ロケールに対して、ローカライズされた個別のカタログが存在しなければなりません。このように、アプリケーションは再構築の必要はありません。

ローカライズされたリソース・ファイルは、/etc/dt/app-defaults/%L サブディレクトリに入れるか、または XENVIRONMENT 環境変数が指すようにすることができます。%L 変数は、実行時に使用されるロケールを示します。

前述の 2 点の選択は、設計時に決定するものとしてアプリケーション開発者に任されています。