ToolTalk サービスは、アプリケーション統合用の完全な関数セットを提供します。ToolTalk メッセージ・ツールキットが提供する機能を使用して、アプリケーションは ToolTalk 準拠の他のアプリケーションと「通信」できます。この節では、同じプロトコルに基づく他の ToolTalk 対応アプリケーションと通信できるように、アプリケーションに組み込む必要がある ToolTalk 関数の追加方法について説明します。
ToolTalk 型機構は、ToolTalk サービス・ルート・メッセージに役立つように設計されています。ツールが ptype を宣言すると、そこにリストされているメッセージ・パターンが自動的に登録されます。ToolTalk サービスは、受信するメッセージとこれらの登録されたパターンを一致させます。これらの静的メッセージ・パターンは、ツールが ToolTalk サービスとの通信を終了するまで有効です。
ToolTalk 型データベースは、本リリースに付いているツール用の ptype をすでにインストールしてあります。次のようにして、ToolTalk 型データベースからインストールされた ptype のリストを取り出すことができます。
% tt_type_comp -d user|system|network -P
ptype の名前は、ソース形式で出力されます。
他のツールすべて (つまり、本リリースには含まれていないツール) に対して、最初に ptype ファイルを作成してアプリケーションの ptype を定義し、ToolTalk 型コンパイラ tt_type_comp で、ptype をコンパイルする必要があります。ptype を定義するには、次の情報をファイルに入れる必要があります。
ptype ファイルを作成するには、どのテキスト・エディタ (vi、emacs、dtpad など) でも使用できます。例 2-2 は、CoEd アプリケーション用の ptype ファイルからの一部分です。
ptype DT_CoEd { /* Process type identifier */ start "CoEd"; /* Start string */ handle: /* Receiving process */ /* * Display ISO_Latin_1 */ session Display( in ISO_Latin_1 contents) => start opnum = 1; /* Signature */ /* NOTE: A signature is divided * into two parts by the => as follows: * Part 1 specifies how the message is to be matched; * Part 2 specifies what is to be taken when * a match occurs. */ }
ptype ファイルを作成したら、ptype をインストールします。このためには、ToolTalk 型コンパイラを実行します。コマンド行に次のように入力してください。
% tt_type_comp CoEd.ptype
CoEd.ptype は、CoEd ptype ファイル名です。
ToolTalk サービスは、指定の ptype がすでに現在のセッションに登録されているかどうか、テストする単純関数を提供します。
// Test for existing ptype registered in current session tt_ptype_exists(const char *ptid)
ptid は登録用にテストするセッションの識別子です。
ToolTalk サービスは、コンパイルされた ToolTalk 型ファイルを現在実行中の ttsession にマージする関数を提供します。
// Merge new compiled ptypes into currently running ttsession tt_session_types_load(current_session, compiled_types_file)
上記の current_session は、現在のデフォルトの ToolTalk セッションです。compiled_types_file はコンパイルされた ToolTalk 型ファイル名です。この関数は、新しい型を追加し、同じ名前の既存の型と置換します。その他の既存の型は変更されません。
各 ToolTalk 対応アプリケーションが実行する必要があるタスクは多数あります。たとえば次のとおりです。
ツールキットの初期化
ToolTalk セッションへの参加とパターンの登録
ToolTalk サービスをそのイベント・ループへ追加
この節では、これらのタスクを実行できるようにアプリケーションに組み込む必要がある ToolTalk のコーディング例を取り上げます。
この節で使用されているコーディングの一部分は、CoEd.C ファイルから引用しています。このファイルには、アプリケーションが実行しなければならない一般コマンドが入っています。このコマンドは、特定のアプリケーションに固有のものではありません。詳細なソースコードについては、付録 B 「CoEd デモンストレーション・プログラム」を参照してください。
アプリケーションはツールキットを初期化し、ToolTalk の初期セッションに登録する必要があります。そのためには、最初にプロセス識別子 (procid) を取得します。次のコーディングの一部分は、procid の取得方法とツールキットの初期化方法を示します。
// Obtain process identifier int myTtFd; // Initialize toolkit and create a ToolTalk communication endpoint char *myProcID = ttdt_open( &myTtFd, ToolName, "SunSoft", "%I", 1 );
アプリケーションは、他の呼び出しが行われる前に必ず ttdt_open を呼び出さなければなりません。そうしない場合、エラーが発生します。
アプリケーションはメッセージを受信する前に、ToolTalk セッションに参加し、一致するメッセージ・パターンを登録する必要があります。
// Join a ToolTalk session and register patterns and default callbacks sessPats = ttdt_session_join( 0, 0, session_shell, this, 1 );
アプリケーションは、ToolTalk サービスをそのイベント・ループに追加することも行わなければなりません。
// Process ToolTalk events for Xt Clients XtAppAddInput( myContext, myTtFd, (XtPointer)XtInputReadMask, tk_Xt_input_handler, myProcID );
前述の 「各 ToolTalk 対応アプリケーションが実行する必要があるタスク」で説明しているタスクの他に、ToolTalk 対応エディタ・アプリケーションは次のタスクも実行する必要があります。
ptype の宣言
開始文字列メッセージの処理
メディア・コールバックのパス
メッセージの無視
要求完了時の応答
この節では、これらの追加タスクを実行できるようにエディタ・アプリケーションに組み込む必要がある ToolTalk のコーディング例を取り上げます。
この節で使用しているコーディングの一部分は、CoEditor.C ファイルから引用しています。このファイルには、エディタ・アプリケーション用の特定コマンドが入っています。詳細なソースコードについては、付録 B 「CoEd デモンストレーション・プログラム」を参照してください。
ToolTalk 関数を組み込むためにエディタ・アプリケーションをコーディングする前に、実行しなければならない手順が 1 つあります。この手順は、メディア・ロード・パターン・コールバック・ルーチンを記述する必要があるということです。たとえば、次のようになります。
Tt_message CoEditor::loadISOLatin1_( Tt_message msg, void *pWidget, Ttttk_op op, Tt_status diagnosis, unsigned char *contents, int len, char *file, char *docname )
このコールバックは、実行時にメディア・ロード関数に渡されます。
型情報は (アプリケーションのインストール時に) 1 回だけしか指定されないので、アプリケーションを起動するたびにその ptype を宣言する必要があります。
前述したメディア・ロード・パターン・コールバック・ルーチンは実行時に渡されます。コールバックは、アプリケーションがセッションに参加するときに登録されます。ツールが要求を処理することにすると、コールバック・メッセージが送信されます。ファイルが参加する、あるいはメッセージが無視される場合にも、コールバック・メッセージは送信されます。
// Join the session and register patterns and callbacks sessPats = ttdt_session_join( 0, 0, session_shell, this, 1 ); // Accept responsibility to handle a request _contractPats = ttdt_message_accept(msg, CoEditor::_contractCB_, shell, this, 1, 1 ); // Optional task: Join a file (Can be called recursively) if (_filePats == 0) {_filePats = ttdt_file_join( _file, TT_SCOPE_NONE, 1, CoEditor::_fileCB_, this ); } // Fail a message tttk_message_fail( msg, TT_DESKTOP_ENODATA, 0, 1 );
アプリケーションはオペレーションの要求を完了した後、送信側アプリケーションに応答しなければなりません。次のメッセージは、テキストの編集された内容を送信側に返します。
// Reply to media load pattern callback // with edited contents of text ttmedia_load_reply( _contract, (unsigned char *)contents, len, 1 );
前述の 「ToolTalk 対応エディタ・アプリケーションが実行する必要があるタスク」で説明しているタスクの他に、エディタ・アプリケーションはその他のオプションのタスクも実行できます。オプションのタスクには、他のエディタとの調整を取るためにデスクトップ・ファイル・インタフェースを使用するものなどがあります。この節では、これらのオプションのタスクを実行できるようにエディタ・アプリケーションに組み込む必要がある ToolTalk のコーディング例をいくつか取り上げています。
この節で使用しているコーディングの一部分は、CoEditor.C ファイルから引用しています。このファイルには、エディタ・アプリケーション用の特定コマンドが入っています。詳細なソースコードについては、付録 B 「CoEd デモンストレーション・プログラム」を参照してください。
次のコーディングの一部分は、保留中の変更があるかどうかファイルに尋ねているものです。
// Does the file have any changes pending? _modifiedByOther = ttdt_Get_Modified( _contract, _file, TT_BOTH, 10 * timeOutFactor );
次のコーディングの一部分は、ファイルを最後のバージョンの内容に復元します。
// Revert file to last version status = ttdt_Revert(_contract, _file, TT_BOTH, 10 * timeOutFactor );
次のコーディングの一部分は、ファイルに対して保留中の変更を保存します。
// Save pending changes status = ttdt_Save( _contract, _file, TT_BOTH, 10 * timeOutFactor );
次のコーディングの一部分は、アプリケーションがファイルに対して保留中の変更を持っていることを配信対象のツールに通知します。
// File has been modified ttdt_file_event( _contract, TTDT_MODIFIED, _filePats, 1 );
次のコーディングの一部分は、アプリケーションがファイルを最後に保存されたバージョンの内容に復元してあることを配信対象のツールに通知します。
// File has been reverted to last version ttdt_file_event( _contract, TTDT_REVERTED, _filePats, 1 );
次のコーディングの一部分は、アプリケーションがファイルに対して保留中の変更を保存してあることを配信対象のツールに通知します。
// File has been saved ttdt_file_event( _contract, TTDT_SAVED, _filePats, 1 );
次のコーディングの一部分は、ファイルに関する ToolTalk イベントの配信対象を登録解除し、パターンを破棄します。
// Unregister interest in ToolTalk events and destroy patterns status = ttdt_file_quit( _filePats, 1 ); _filePats = 0;