以下の例は X-Designer 再現機能のソースに対するのものです。この例はウィジェットのクラス (ここでは Motif XmList ウィジェットクラス) 用のコンバータを登録する方法を示したものです。XmList ウィジェットでのクリックが、そのリスト内の要素の特定インスタンスの選択に変換される様子を示しています。これは、 X-Designer 再現機能が XmList ウィジェットに対して実際に使用する機能です。この機能の使用例を以下のスクリプトに示します。
in my_shell push my_list_widget(`this line',1)
このスクリプトが再現されると、ウィジェット内の適切な (x,y) 座標でクリックがシミュレートされます。
この例を実習すると、以下の 3 点が可能になります。
この例のソースファイルは、Makefile とともに $ XDROOT/src/examples/replay/cvtXm ディレクトリに用意されています。$ XDROOT は、 X-Designer のインストールディレクトリです。
このディレクトリの内容は、以下のとおりです。
サポートファイルは、共有オブジェクトが X-Designer 再現機構と通信するための枠組みを提供します。これらのファイルを変更する必要はありません。
この例では、XmList コンバータを含む motif2.c およびこれらのコンバータを登録するためのコードを組み込んでいる register.c をについて学習します。
この例では、 X-Designer 再現のウィジェットセットを拡張する方法を 3 段階で説明します。
関連する 3 つのルーチンは以下のとおりです。
ウィジェットおよび関連するコンバータを X-Designer 再現に登録します。重要なことは、コンバータコードの構造およびコンバータの登録方法であり、XmList コンバータの実装方法ではありません。
この関数は motif2.c にあり、(x,y) 座標を名前/属性対に変換します。ここでは、xdsXyToNameProc インタフェース定義の構造体を説明しています。この関数は X-Designer 再現が記録モードのときに使用されます。
int xdsListXyToName( widget, x, y, namep, attrp) Widget widget; int x, y; char ** namep; char ** attrp; { extern Boolean XmStringCompare(); extern char * xdsCvtXmStringToString(); extern Boolean xdsCvtSetListError(); extern int xdsCvtListFailure(); extern Boolean xdsCvtGetXmListEntries(); extern int XmListYToPos(); static char name[255]; static char count[20]; int pos; int len = 0; int n; int instance = 1; XmString * list = (XmString*)0; XmString item; /* 要素を取得する */ if (!xdsGetXmListEntries( widget,&list, &len)) { return xdsListFailure(); } /* XmListYToPos() を使用してリスト要素を取得する */ pos = XmListYToPos( widget, (Position)y); if (pos < 0 || pos > len) { xdsCvtSetListError(LIST_OUT_OF_BOUNDS); return xdsCvtListFailure(); } item = list[--pos]; for (n = 0; n < pos; n++) { if (XmStringCompare( item, list[n]) == True) instance++; } /* 記述を作成する */ (void) sprintf ( count, "%d", instance); (void) strcpy ( name, xdsXmStringToString(item)); *namep = name; *attrp = count; return 1; }
この関数は motif2.c にあり、(x,y) 座標を名前/属性対に変換します。ここでは、xdsXyToNameProc インタフェース定義の構造体を説明しています。この関数は X-Designer 再現が記録モードのときに使用されます。
int xdsListNameToXy( widget, name, attr, xp, yp) Widget widget; char * name; char * attr; int * xp; int * yp; { extern char * xdsCvtXmStringToString(); extern Boolean xdsCvtSetListError(); extern int xdsCvtListFailure(); extern int xdsCvtSetListItem(); extern Boolean xdsCvtGetXmListEntries(); Position x, y; Dimension w, h; int pos; int len = 0; int n; char * s; int instance = 1; XmString * list = (XmString*)0; XmString item; if ((instance = atoi(attr)) == 0) { xdsCvtSetListError(LIST_BAD_INSTANCE); return xdsCvtListFailure(); } instance--; if (!xdsCvtGetXmListEntries( widget, &list, &len)) { xdsCvtSetListError(LIST_EMPTY_LIST); return xdsCvtListFailure(); } for ( n = 0; n < len; n++) { s = xdsCvtXmStringToString(list[n]); if (strcmp( name, s) != 0) continue; if (instance--) continue; break; } if (n == len) { xdsCvtSetListError(LIST_ELEMENT_NOT_FOUND); return xdsCvtListFailure(); } (void) xdsCvtSetListItem( widget, n+1); if (!XmListPosToBounds( widget, n+1, &x, &y, &w, &h)) { xdsCvtSetListError(LIST_OUT_OF_BOUNDS); return xdsCvtListFailure(); } *xp = x + (w/2); *yp = y + (h/2); return 1; }
この関数は、register.c と呼ばれています。motif2.c の 2 つのコンバータおよび XmScrollBar、XmScale、XmDrawingArea の各ウィジェット用のコンバータを登録します。
void RegisterWidgets() { extern Boolean xdsRegister(); extern int xdsListNameToXy(); extern int xdsListXyToName(); extern int xdsScrollBarNameToXy(); extern int xdsScrollBarXyToName(); extern int xdsScaleNameToXy(); extern int xdsScaleXyToName(); extern int xdsDaNameToXy(); extern int xdsDaXyToName(); (void) xdsRegister( "XmList", xdsListNameToXy, xdsListXyToName); (void) xdsRegister( "XmScrollBar", xdsScrollBarNameToXy, xdsScrollBarXyToName); (void) xdsRegister( "XmScale", xdsScaleNameToXy, xdsScaleXyToName); (void) xdsRegister( "XmDrawingArea", xdsDaNameToXy, xdsDaXyToName); } void RegisterThisListWidget( Widget w; { xdsRegisterContextHandler(w, xdsListNameToXy, xdsListXyToName); }
この関数は xdsSetup.h に定義されています。ここでは、xdsRegisterContextHandler インタフェース定義の構造体を説明しています。
Boolean xdsRegister( classname, name2xy, xy2name) char * classname; int_f name2xy; int_f xy2name; { bool_f bf = xdsGetRegisterFunction(); if (!bf) return False; return (*bf)( classname, name2xy, xy2name); }
提供されている Makefile は、共有オブジェクトを構築するよう構成されています。多数のオペレーティングシステムがサポートされています。これらのシステムをリストするには、次のように入力します。
% make
共有オブジェクトは、Makefile の OBJECT 行を次のように変更するだけで構築することができます。
OBJECT = cvt<classname>
クラス名には、ウィジェットクラスの接頭辞を指定します。この例では、ウィジェットクラスは XmList なので、次のように Xm 接頭辞を入力します。
OBJECT=cvtXm
共有オブジェクトを構築するには、make <システム名> と入力します。たとえば、Solaris マシンの場合は、make solaris と入力します。これで、libcvtXm.so という共有オブジェクトが構築されます。
共有オブジェクトが構築されたら、そのオブジェクトを $ XDROOT/lib/xds というディレクトリにコピーまたはリンクします。これで、 X-Designer 再現が必要に応じてこのオブジェクトを読み込むことができます。
前述の例は、ウィジェットクラスに関するものです。カスタマイズ可能なウィジェット (すなわち、Motif XmDrawingArea などのウィジェットの特定のインスタンス) の場合は、変換ルーチンを登録するための機能が X-Designer とともに提供されています。この機能を使用すると、 X-Designer 再現機能がウィジェットのインスタンス (Motif であるかどうかに関わらず) の中で行なったユーザーアクションアを記録および再現できるように、 X-Designer 再現機能の動作をカスタマイズすることができます。
コンバータ登録コードは、以下のとおりです。
int_f _xdsRegisterFunction = (int_f)0; Boolean xdsRegisterContextHandler( widget, name2xy, xy2name) Widget widget; int_f name2xy; int_f xy2name; { if (!_xdsRegisterFunction) return False; return (*_xdsRegisterFunction)( widget, name2xy, xy2name, True); }
コンバータを登録するルーチンについては、以下で説明します。
xdsRegisterContextHandler - コンバータの登録に使用する関数のインタフェース
Boolean xdsRegisterContextHandler( Widget widget, xdsNameToXYProc name2xy, xdsXYToNameProc xy2name) Boolean xdsRemoveContextHandler( Widget widget)
このルーチンは、ウィジェットにおけるイベントの独自解釈を登録するためのものです。以下の例に示すように、ウィジェットをコード内に作成した後は、いつでも xdsRegisterContextHandler を呼び出すことができます。
button1 = XmCreatePushButton ( shell1, "button1", al, ac ); xdsRegisterContextHandler(shell1, func1, func2)
X-Designer 再現は、再現時は func1 ルーチンを呼び出し、記録時は func2 ルーチンを呼び出します。
この機能は、ソースファイル (client.c) として、またはコンパイル済みライブラリモジュール (libxdsclient.a) として使用することができます。ソースファイルの場合はアプリケーションとともにコンパイルし、ライブラリモジュールの場合はアプリケーションと再リンクします。
この機能はアプリケーション自体には影響せず、アプリケーション内に残しても悪影響はありません。
X-Designer 再現ウィジェットセットを拡張するには、以下の作業を行います。
ウィジェットクラスの場合は、以下の作業を行います。
個々のウィジェットには、以下の作業を行います。
提供されている examples ディレクトリの内容を参考にして、コンバータの記述、登録、構築を行なってください。
関連項目: