この節では、ToolTalk コードがどのように Xedit および Xfontsel アプリケーションに追加されたかを説明します。
省略記号 (. . .) は、コードがスキップされていることを表します。コード例は、挿入された ToolTalk コード行の前後数行だけを示します。
ファイルに追加する必要がある実際の ToolTalk コードは、ボールド体で示します。次にその例を示します。
#include <desktop/tt_c.h> /* ToolTalk のヘッダー */ |
Xedit ファイルに対する変更は、「Xedit アプリケーションの変更」で説明します。
/* * 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(); /* フォントを変更する */
#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); } }
#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 ファイルに対する変更は、「Xfontsel アプリケーションの変更」で説明しています。
#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); }