ToolTalk ユーザーズガイド

アプリケーションへの ToolTalk コードの追加

この節では、ToolTalk コードがどのように Xedit および Xfontsel アプリケーションに追加されたかを説明します。

 #include <desktop/tt_c.h> 
/* ToolTalk のヘッダー */

Xedit ファイルへの ToolTalk コードの追加

Xedit ファイルに対する変更は、Xedit アプリケーションの変更で説明します。


例 B–1 Xedit.h ファイルの変更

 /*
 *	rcs_id[] = “$XConsortium: xedit.h,v 1.18 89/07/21 19:52:58 kit Exp $”;
 */

...

 #include <X11/Xaw/Viewport.h>
 #include <X11/Xaw/Cardinals.h>

 /*
 * ToolTalk のデモンストレーション用に、以下のインクルード行を追加する
 */
 #include <desktop/tt_c.h>	
 /* ToolTalk のヘッダ */

 extern struct _app_resources {
 Boolean enableBackups;
 char *backupNamePrefix;
 char *backupNameSuffix;

...

 /* xedit.c に外部宣言 */

 extern void Feep();
 /*
 * ToolTalk のデモンストレーション用に、以下の外部宣言を追加する
 */
 extern void processToolTalkMessage(); /* ToolTalk メッセージの処理 */
 extern void dieFromToolTalkError(); 
		/* エラーが発生した場合は異常終了する */
 extern Display *CurDpy;
  /* 表示 */

...

  /* commands.c に外部宣言 */

...

 extern void DoChangeFont();
 		/* フォントを変更する */ 


例 B–2 変更された Xedit.c ファイル

#if (!defined(lint) && !defined(SABER)) \
 static char Xrcsid[] = “$XConsortium: \
 xedit.c,v 1.23 89/12/07 \
 19:19:17 kit Exp $”;
 #endif 			/* lint && SABER */

...

 void main(argc, argv)
 int argc;
 char **argv;
 {
 Widget top;
 String filename = NULL;
 static void makeButtonsAndBoxes();

 /*
  * ToolTalk のデモンストレーション用に、
  * 以下の行を追加する
  */
 int ttmark;
/* ToolTalk のマーク */
 int ttfd;
/* ToolTalk のファイル記述子 */
 char *procid;	
/* プロセス識別子 */
 Tt_status ttrc;
/* ToolTalk の状態 */

 top = XtInitialize( “xedit”, \ 
“Xedit”, NULL, 0, &argc, argv);

...

XtRealizeWidget(top);
XDefineCursor(XtDisplay(top),XtWindow(top), \
XCreateFontCursor( XtDisplay(top), \ 
XC_left_ptr));
 /*
  * ToolTalk のデモンストレーション用に、
  * ToolTalk セッションをスタックの最初に
  * 作成して、デフォルトセッションとして
  * 設定するために、以下の行を追加する
  */
 ttmark = tt_mark();
 ttrc = tt_default_session_set( 
	/* 最上位ウィンドウを表示している .. */
 tt_X_session( 	
 /* .. X サーバーの .. */
 DisplayString( 
 /* .. X セッションに ..*/
 XtDisplay(top))));
 /* .. デフォルトセッションを設定する ... */
 /*
  * デフォルトセッションがない場合は異常終了する
  */
 dieFromToolTalkError( \
 “tt_default_session_set”,ttrc);  
 procid = tt_open();	
 	/* ToolTalk の初期化 */
		/*
		 * プロセス識別子がない場合は異常終了する
 	 */
 dieFromToolTalkError(“tt_open” \
,tt_ptr_error(procid));
 ttfd = tt_fd();	
		/* ToolTalk のファイル記述子 */
 	/*
		 * ファイル記述子がない場合は異常終了する
		 */
dieFromToolTalkError(“tt_fd”, \
tt_int_error(ttfd)); 
		/*
		 * ファイル記述子を起動する
 	 */
XtAddInput(ttfd, (XtPointer)XtInputReadMask, \
 processToolTalkMessage, 0);

 XtMainLoop();
 }

...

 MakeCommandButton(b_row, “load”, DoLoad);
 /*
  * ToolTalk のデモンストレーション用に、
  * フォント変更用コマンドのボタンを作成するために、* 
  * 次の行を追加する
  */
 MakeCommandButton(b_row, “changefont”, \ 
 DoChangeFont);	
 filenamewindow = MakeStringBox(b_row, \ 
“filename”, filename);
 }
 XtCreateManagedWidget(“bc_label”, 
 labelWidgetClass, outer, NULL, ZERO);

...

 void Feep()
 {
 XBell(CurDpy, 0);
 /*
  * ToolTalk のデモンストレーション用に、
  * 着信メッセージを受信して処理するために、
  * 以下の行を追加する
  */
 }


 void processToolTalkMessage()
		/* ToolTalk メッセージを処理する */
 {
 	int ttmark;	 		
  /* ToolTalk のマーク */
 	Tt_message incoming;						
		/* 着信メッセージ */

 	ttmark = tt_mark(); 				
		/* ToolTalk のマーク */

 	incoming = tt_message_receive();
		/* 着信メッセージを受信 */
 	/*
 	 * コールバックがメッセージを処理しなければならないので、
 	 * 返されたメッセージを取得してはならない
 	 */
 	if (incoming == 0) return;	
		/* 着信メッセージを戻す */

	if (tt_is_err(tt_ptr_error(incoming))) {
 		dieFromToolTalkError(“tt_message_receive”,
 				 tt_ptr_error(incoming));
 	}
 
 	/*
 	 * これは、認識していないメッセージである。
 	 * 開始の要求または通知があった場合に、異常終了する
 	 */

 	if (tt_message_class(incoming) == TT_REQUEST ||
 	 tt_message_status(incoming) ==
   TT_WRN_START_MESSAGE) {
 		tt_message_fail(incoming);
 	}
 	tt_message_destroy(incoming);
			/* メッセージの削除 */
 	tt_release(ttmark);	
 		/* 領域の解放 */
 }

 void dieFromToolTalkError(procname, errid)
 char *procname;
 Tt_status errid;
 	/* エラーが発生した場合は異常終了する */
 {
 	/*
 	 * 警告または TT_OK を無視してはならない
 	 */

  if (tt_is_err(errid)) {
 		fprintf(stderr,”%s returned ToolTalk 
   error: %s\n”,
 			procname, tt_status_message(errid));
 		exit(1);
 	}
 }


例 B–3 変更された commands.c ファイル

#if (!defined(lint) && !defined(SABER))
static char Xrcsid[] = “$XConsortium: 
commands.c,v 1.27 89/12/10
 				17:08:26 rws Exp $”;
#endif /* lint && SABER */

...

#ifdef USG
int rename (from, to)
 char *from, *to;
{
 (void) unlink (to);
 if (link (from, to) == 0) {
 unlink (from);
 return 0;
 } else {
 return -1;
 }
}
#endif

/*
 * ToolTalk のデモンストレーション用に、
 * 操作が成功したか失敗したかについて
 * Xfontsel がコールバックを送信するよう
 * 以下の行を追加する
 */
static Tt_callback_action FinishChangeFont(m,p)
/* ToolTalk メッセージコールバック */
 Tt_message m;
 	/* ToolTalk メッセージ */
 Tt_pattern p;	
 	/* ToolTalk パターン */
{
	static XFontStruct *fs;
			/* フォントの構造体 */
	int ttmark;	
			/* ToolTalk のマーク */
	
	ttmark = tt_mark();	
			/* ToolTalk のマーク */
 	/*
		 * 操作に失敗すると、ユーザーに通知する
		 */
 if (TT_FAILED==tt_message_state(m)) {
		XeditPrintf(“Font change failed\n”);
		tt_message_destroy(m);	 
			/* メッセージの削除 */
	} else if (TT_HANDLED==tt_message_state(m)) {
		XFontStruct *newfs;
		/* 新しいフォントを読み込む */
 	newfs = 
XLoadQueryFont(CurDpy,tt_message_arg_val(m,0));
 	/* 新しいフォントが正常の場合、古いフォントがあれば
		 * 読み込みを解除して、新しいフォントを使用する
 	 */
		if (newfs) {
			if (fs) {
 			XUnloadFont(CurDpy, fs->fid);
			}
			XtVaSetValues(textwindow, XtNfont, newfs, 0);
			fs = newfs;
		}
		tt_message_destroy(m);	
			/* メッセージの削除 */
 }
	tt_release(ttmark);	
 			/* マークの解放 */
		/*
		 * 送信側に操作の終了を通知するために、
 	 * コールバックを処理する
		 */
	return TT_CALLBACK_PROCESSED; 	
}

void
DoChangeFont()		
/* フォントの変更 */
{
	Tt_message m;
		/* ToolTalk のメッセージ */
	Tt_status ttrc;			
		/* ToolTalk の状態 */

	 /*
		 * 要求を作成
		 */
	m = tt_prequest_create(TT_SESSION, 
  “GetFontName”); 
		/*
		 * メッセージに引数を追加
 	 */
	tt_message_arg_add(m,TT_OUT,”string”,
   (char *)NULL);
		/*
		 * 変更の終了を通知するため、コールバックを追加する
 	 */
	tt_message_callback_add(m,FinishChangeFont);
 	/*
		 * メッセージの送信
		 */
	ttrc = tt_message_send(m);
		/*
		 * エラーが発生した場合は異常終了する
 	 */
	dieFromToolTalkError(“tt_message_send”,ttrc);
}



void DoSave()
{

Xfontsel ファイルへの ToolTalk コードの追加

Xfontsel ファイルに対する変更は、Xfontsel アプリケーションの変更で説明しています。


例 B–4 変更された Xfontsel.c ファイル

#ifndef lint
static char Xrcsid[] = “$XConsortium:
 xfontsel.c,v 1.16 89/12/12 14:10:48 rws
 Exp $”;
#endif

...

#include <X11/Xaw/Viewport.h>
#include <X11/Xmu/Atoms.h>

/*
 * ToolTalk のデモンストレーション用に、ToolTalk
 * のヘッダーファイルをインクルードするために  
 * 以下の行を追加する
 */
#include <desktop/tt_c.h>	
/* ToolTalk のヘッダーファイル */

#define MIN_APP_DEFAULTS_VERSION 1

...

void SetCurrentFont();
Boolean IsXLFDFontName();

/*
 * ToolTalk のデモンストレーション用に、
 * Xfontsel に ToolTalk メッセージの処理方法を
 * 通知するために、以下の行を追加する
 */
void dieFromToolTalkError(); 
 /* エラーが発生した場合は異常終了する */
void processToolTalkMessage();
 /* ToolTalk メッセージの処理 */
void ReplyToMessage();	
 	/* ToolTalk メッセージへの応答 */
Tt_message replymsg; 										

typedef void (*XtProc)();

...

int matchingFontCount;
static Boolean anyDisabled = False;
Widget ownButton;
/*
 * ToolTalk のデモンストレーション用に、
 * フォントを変更する適用ボタンを追加するために、
 * 次の行を追加する
 */
Widget applyButton;
		/* 適用ボタンを追加 */
Widget fieldBox;
/*
 * ToolTalk のデモンストレーション用に、
 * フォントを変更するコマンドボックスを追加するために、
 * 次の行を追加する
 */
Widget commandBox;		
		/* commandBox を拡大 */
Widget countLabel;

...

void main(argc, argv)
 unsigned int argc;
 char **argv;
{
 Widget topLevel, pane;

/*
 * ToolTalk のデモンストレーション用に、
 * 以下の行を追加する
 */
 int ttmark, ttfd;
		/* ToolTalk マークと ToolTalk ファイル記述子 */
 char *procid;	
 	/* プロセス識別子 */
 Tt_status ttrc;
 	/* ToolTalk の状態 */

 topLevel = XtInitialize( NULL, 
 “XFontSel”, options, XtNumber(options),
 		 &argc, argv );

...

 pane = XtCreateManagedWidget(“pane”
,panedWidgetClass,topLevel,NZ);
 {
/*
 * ToolTalk のデモンストレーション用に、  
 * コマンドボックスのウィジェットを拡大して、
 * Widget commandBox、fieldBox、
 * currentFontName、viewPort の行を
 * 以下のように変更する 
 */
	Widget
 /* commandBox, fieldBox, currentFontName,*/ viewPort;

	commandBox = XtCreateManagedWidget(“commandBox
 ”,formWidgetClass,pane,NZ);
 {

...

	 ownButton =
		XtCreateManagedWidget(“ownButton”
,toggleWidgetClass,commandBox,NZ);
/*
 * ToolTalk のデモンストレーション用に、
 * フォントを変更する適用ボタンを以下の行に追加する
 */
	 applyButton =		
	 XtVaCreateManagedWidget(“applyButton”,
 				commandWidgetClass,
					commandBox,
		 		XtNlabel, “apply”,
					XtNfromHoriz, ownButton,
 				XtNleft, XtChainLeft,
					XtNright, XtChainLeft,
 				0);

	 countLabel =
		XtCreateManagedWidget(“countLabel”
,labelWidgetClass,commandBox,NZ);

	 XtAddCallback(quitButton, XtNcallback, Quit,
 NULL);
  XtAddCallback(ownButton,XtNcallback,
  OwnSelection,(XtPointer)True);
/*
 * ToolTalk のデモンストレーション用に、
 * 適用ボタンが押されたことを Xedit に通知するために
 * 以下の行を追加する
 */
	 XtAddCallback(applyButton, 
  XtNcallback,ReplyToMessage, NULL);
	}

	fieldBox = XtCreateManagedWidget(“fieldBox”,
 boxWidgetClass, pane, NZ);

...

 {
 int f;
	for (f = 0; f < FIELD_COUNT; f++) 
currentFont.value_index[f] = -1;
 }

 /*
  * ToolTalk のデモンストレーション用に、
  * ToolTalk セッションをスタックの最初に
  * 作成して、デフォルトセッションとして設定するために、
  * 以下の行を追加する
  */
 ttmark = tt_mark();
 ttrc = tt_default_session_set( 
		/* 最上位ウィンドウを表示している */
 tt_X_session(
		 /* X サーバーの */
 DisplayString(
 		/* X セッションに */
 XtDisplay(top))));
 		/* デフォルトセッションを設定 */
	  /*
	   * デフォルトセッションがない場合は異常終了する
    */
 dieFromToolTalkError(“tt_default_session_set”
,ttrc);
 procid = tt_open();
	/*
	 * プロセス識別子がない場合は異常終了する
  */
 dieFromToolTalkError(“tt_open”
,tt_ptr_error(procid));
 ttfd = tt_fd();
	/*
	 * ToolTalk ファイル記述子がない場合は異常終了する
  */
 dieFromToolTalkError(“tt_fd”
,tt_int_error(ttfd));
 ttrc = tt_ptype_declare(“xfontsel”);
	/*
  * ptype が宣言されていない場合は異常終了する
	 */
 dieFromToolTalkError(“tt_ptype_declare”
,tt_int_error(ttfd));
 ttrc = tt_session_join(tt_default_session());
	/*
  * セッションを結合できない場合は異常終了する
	 */
 dieFromToolTalkError(“tt_session_join”,ttrc);
 /*
	  * 入力の追加
	 */
 XtAddInput(ttfd, (XtPointer)XtInputReadMask,
 processToolTalkMessage, 0);

 XtAppMainLoop(appCtx);							

 tt_close();	 				
			/* ToolTalk セッションを終了する */
 tt_release(ttmark);									
			/* 領域の解放 */
}

...
 	Boolean field_bits[FIELD_COUNT];
		int max_field;
 	if (*fontName == DELIM) field++;
/*
 * ToolTalk のデモンストレーション用に、
 * BSD の代わりに標準ルーチンを使用して
 * bzero 以下のように読み込むために
 * bzero( field_bits, sizeof(field_bits) );
 * の行を変更する
 */
		memset( field_bits, 0, sizeof(field_bits) );
		if (Matches(pattern, fontName++, field_bits, 
   &max_field)) {

...

	 XtDisownSelection(w, XA_PRIMARY, time);
	XtSetSensitive(currentFontName, False);
 }

/*
 * ToolTalk のデモンストレーション用に、
 * 以下の行を追加する
 */
}

void dieFromToolTalkError(procname, errid)
/* エラーが発生した場合は異常終了する */
 char *procname;
 	/* プロセス名 */
 Tt_status errid;
 	/* エラー識別子 */
{
	/*
	 * 警告または TT_OK を無視してはならない
	 */

	if (tt_is_err(errid)) {
		fprintf(stderr,”%s returned ToolTalk error:
 %s\n”,
			procname, tt_status_message(errid));
 	exit(1);
	}
}

void processToolTalkMessage()
	/* プロセスメッセージ */
{
	int ttmark;	
		/* ToolTalk マーク */
	Tt_message incoming;				
			/* 着信メッセージ */

	ttmark = tt_mark();

	incoming = tt_message_receive(); 
	/* メッセージを受信 */
 /*
  * ファイル記述子が使用可能であっても、
	 * 実際には ToolTalk のメッセージがない場合も
  * あり得る
	 */
	if (incoming == 0) return;

	if (tt_is_err(tt_ptr_error(incoming))) {
		dieFromToolTalkError(“tt_message_receive”,
 			 tt_ptr_error(incoming));
	}
	
 if (0==strcmp(tt_message_op(incoming),”
  GetFontName”)) {
		/*
		 * これは、予想していたメッセージである。
 	 * すでに使用中の場合はそのメッセージを拒否する。
		 * そうでない場合は、適用ボタンを有効にする
 	 */
		if (replymsg) {
			tt_message_reject(incoming);
 		tt_message_destroy(incoming);
			tt_release(ttmark);
 		return;
		}
		XtVaSetValues(applyButton, XtNsensitive, 
   TRUE, 0);
		replymsg = incoming;
		tt_release(ttmark);
 	return;
	}

	/*
  * これは認識していないメッセージである。
	 * 開始の要求または通知があった場合に異常終了する
  */

	if (tt_message_class(incoming) == TT_REQUEST ||
	 tt_message_status(incoming) == 
  TT_WRN_START_MESSAGE) {
		tt_message_fail(incoming);
	}
	tt_message_destroy(incoming);
	tt_release(ttmark);
}

/*
 * 適用ボタンが押されると呼び出される。
 * 未応答のメッセージに応答して、適用ボタンをオフにする
 */

/* 使用済み引数 */
void ReplyToMessage(w, msg, wdata)
 Widget w;
 caddr_t msg;
 caddr_t wdata;
{

	tt_message_arg_val_set(replymsg, 0, 
currentFontNameString);
	tt_message_reply(replymsg);
	tt_message_destroy(replymsg);
	replymsg = 0;
	XtVaSetValues(applyButton, XtNsensitive, FALSE,
 0);
}