# ToolTalkメッセージの使用方法

この章のコーディング例は、`broadcast`とういう名前の ToolTalkデモ・プログラムの一部です。このプログラムのソース・コード、`Makefile`、や`README`ファイルについては、 `/usr/dt/examples/tt`ディレクトリを参照してください。

## ToolTalk機能のアプリケーションへの通知

アプリケーションは、ToolTalkサービスとメッセージ・ツールキットが提供する相互 運用機能を利用する前に、ToolTalkライブラリとツールキットがある場所を認識しておく 必要があります。

### メッセージ・ツールキットの使用とToolTalkコマンドの組み込み

ToolTalkサービスを使用するために、アプリケーションはToolTalkアプリケーション ・プログラミング・インタフェース(API)からToolTalk関数を呼び出します。メッセージ・ ツールキットは、ToolTalkサービスへの登録、メッセージ・パターンの作成、メッセージの 送信、メッセージの受信、およびメッセージ情報のチェックを行うための関数を提供 します。これらは、ToolTalk APIよりもハイレベルな関数です。ToolTalkサービスとツール キットを使用できるようにアプリケーションを変更するには、以下のヘッダ・ファイルを 組み込まなければなりません。

    #include <Tt/tt_c.h>    /* ToolTalk Header File */
    #include <Tt/tttk.h>    /* Messaging Toolkit Header File */

### ToolTalkライブラリの使用

ToolTalkライブラリは、以下のディレクトリにあります。

    /usr/dt/lib

ライブラリ名は、プラットフォームに依存しています（たとえば、Solarisでは `libtt.so`そしてHP-UXでは `libtt.sl`です)。

## コーディングを開始する前に

メッセージ・ツールキット機能をアプリケーションに組み込む前に、アプリケーショ ンのツールが他のツールと一緒に動作する方法を決定する必要があります。考慮すべき基本 的な内容は以下のとおりです。

- これらのツールはどのように同時に動作するか

- これらのツールはどのようなオペレーションを実行できるか

- 他のツールにどのようなオペレーションを実行するように要求できるか

- 他のツールを配信対象にできるこれらのツールはどのようなイベントを生成するか （これらのツールはどの型のメッセージを送信したいか）

- 他のツールによって生成されたイベントの中でこれらのツールの配信対象となるイベ ントはどれか（これらのツールはどの型のメッセージを受信したいか）

これらの質問に的確に答えるには、イベントとオペレーションの間の違いと、 ToolTalkサービスがお互いに関連のあるメッセージを処理する方法を理解する必要がありま す。

### イベントとオペレーションの違い

イベントは、何か起きたことを通知するものです。イベン は、簡単に言えばニュース速報です。送信側のプロセスは、他のプロセスがイベントが起き たことを聞くかどうかと、アクションがイベントの結果として起こるかどうかについての 正式な予想を持っていません。プロセスがToolTalkサービスを使用して、配信対象のプロ セスにイベントが発生したことを知らせる場合、通知を送信します 。送信側プロセスは応答を期待しないため、イベントは失敗できません。

オペレーションは、問い合わせまたはアクションです。要求 側プロセスは、オペレーションが実行されるように問い合わせまたは要求を行います。要求 側プロセスは結果が返されることを予想し、問い合わせまたはアクションのステータスを 通知するように要求します。プロセスがToolTalkサービスを使用して、他のツールにオペ レーションを実行するように依頼する場合、要求を送信します。 ToolTalkサービスは配信対象のプロセスに要求を配信し、送信側プロセスに要求のステー タスを通知します。

#### 通知の送信

アプリケーションがToolTalkの通知を送信する場合、応答は受信せず、ツールがその 通知に注意を払うかどうかについて通知を受けることもありません。通知をイベントの発生 に応じて正確なレポートにすることが重要です。たとえば、ツールがデスクトップ・サービ スのメッセージの`Modified`を送信する場合、聞き手側のツールを指定 の方法で反応させることができます。しかしツールは、他のツールがそのメッセージに反応 するかどうか気にしたり、通知を受ける必要はありません。次のイベントをレポートしたい だけです。 THE_USER_HAS_MADE_CHANGES_TO_THIS

#### 要求の送信

アプリケーションがToolTalkの要求を送信する場合、１つのツールが指示されたオ ペレーションを実行する、または問い合わせに答え、応答メッセージを返すことを期待しま す。たとえば、ツールがデスクトップ・サービス・メッセージの `Get_Modified`を送信する場合、メッセージが配信され、アクションが 実行されたという通知が期待できます。ToolTalkサービスでは必ず、プロセスの受信によっ て応答が返されるか、送信側に要求の失敗が通知されます。

次の３つの方法で要求を識別できます。

- 異常終了できるツールによって要求されるオペレーションを識別する

- 他のツール用に実行できるオペレーションを識別する

- 他のツールに実行させたいオペレーションを識別する

これらのオペレーションを識別するための良い方法は、ツールが実行するまたは 実行を完了したイベントおよびオペレーションの順序について概説するシナリオを開発する ことです。

### シナリオの開発

シナリオは、ツールが実行するおよび実行を完了したイベントおよびオペレーション の順序を概説しています。たとえば、次のシナリオは、一般的なエディタが実行するおよび 実行を完了したイベントについて概説しています。

1. ファイル・マネージャのドキュメント・アイコンをダブルクリックします。 ファイルはエディタで開きます。エディタを実行中でない場合はシステムによって起動され ます。ドキュメントに対して別のツールが保留中のテキストに変更を行うと、その別のツー ルが変更したテキストを保存するか、それとも最後に保存されたバージョンのドキュメント に戻るか尋ねられます。

2. テキストを挿入します。

3. ドキュメントを保存します。 別のツールがそのドキュメントに保留中の変更点を持っている場合、ドキュメントを変更 するか尋ねられます。

4. エディタを終了します。 テキストに保存されていない変更がある場合、ファイルを終了する前にその変更を保存する かそれとも破棄するか尋ねられます。

シナリオがいったん実行されると、基本的な質問に答えることができます。

#### ツールを同時に動作させる方法

- ファイル・マネージャは、編集用のドキュメントを開くように要求します。

- 各インスタンスは、その他の配信対象のインスタンスにドキュメントの状態に対して 行われる変更を通知します。

#### これらのツールはどのようなオペレーションを実行できるか

- 各インスタンスは、それ自身とその状態に関する質問 （「ステータスは？」など）に答えることができます。

- 各インスタンスには、次のようなオペレーションを実行する機能があります。

  - アイコン化とアイコン化解除

  - 重なり順の変更

  - ドキュメントの編集

  - ドキュメントの表示（読み取り専用）

  - 終了

#### 他のツールにどのようなオペレーションを実行するように要求できるか

- ファイル・マネージャは、エディタが編集用のドキュメントを開くように要求する 必要があります。

- エディタのインスタンスは、別のインスタンスに対し、開いているドキュメントの 変更を保存するように要求できます。

- エディタのインスタンスは、別のインスタンスに対し、開いているドキュメントの 最後のに保存されたバージョンに戻るように要求できます。

#### 他のツールを配信対象にできるこれらのツールはどのようなイベントを生成 するか

- ドキュメントを開いています。

- ドキュメントを変更しています。

- ドキュメントは最後に保存されたバージョンの内容に戻っています。

- ドキュメントを保存しています。

- エディタのインスタンスは終了しています。

#### 他のツールによって生成されたイベントの中でこれらのツールの配信対象となる イベントはどれか

- ドキュメントを開いています。

- ドキュメントを変更しています。

- ドキュメントは最後に保存されたバージョンの内容に戻っています。

- ドキュメントを保存しています。

- エディタのインスタンスは終了しています。

## 通信用アプリケーションの準備

ToolTalkサービスは、アプリケーション統合用の完全な関数セットを提供します。 ToolTalkメッセージ・ツールキットが提供する機能を使用して、アプリケーションは ToolTalk準拠のほかのアプリケーションと「通信」を行うことができます。この 節では、同じプロトコルに基づく他のToolTalk対応アプリケーションと通信できるように、 アプリケーションに組み込む必要があるToolTalk関数の追加方法について説明します。

### ptypeファイルの作成

ToolTalk型機構は、ToolTalkサービス・ルート・メッセージに役立つように設計され ています。ツールがptype（プロセス型）を宣言すると、そこにリストされているメッセー ジ・パターンが自動的に登録されます。ToolTalkサービスは、受信するメッセージとこれら の登録されたパターンを一致させます。これらの静的メッセージ・パターンは、ツールが ToolTalkサービスとの通信を終了するまで有効です。

ToolTalk型データベースは、本リリースに付いているツール用のptypeをすでにイン ストールしてあります。次のようにして、ToolTalk型データベースからインストールされた ptypeのリストを取り出すことができます。

    % tt_type_comp -d user | system | network -P

ptypeの名前は、ソース形式で出力されます。

次のようにして、シグニチャを含むインストールされたptypeのリストを生成します。

    % tt_type_comp -d user | system | network -p

他のツールすべて（つまり、本リリースには含まれていないツール）に対して、最初 にptypeファイルを作成してアプリケーションのptypeを定義し、ToolTalk型コンパイラ `tt_type_comp`で、ptypeをコンパイルする必要があります。ptypeを 定義するには、次の情報をファイルに入れる必要があります。

- プロセス型識別子(`ptid`)

- オプションの開始文字列 ToolTalkサービスは、必要に応じてこのコマンドを実行し、プログラムを実行する プロセスを開始します。

- シグニチャ プログラムが受信したいTT_PROCEDUREアドレス指定メッセージを記述 しています。監視されるメッセージは、処理されるメッセージと別々に記述します。

ptypeファイルを作成するには、どのテキスト・エディタ (`vi`、 `emacs`、`dtpad` など)でも使用できます。

ptypeファイルを作成したら、ptypeをインストールします。このためには、ToolTalk 型コンパイラを実行します。コマンド行に次のように入力してください。

    % tt_type_comp file_name.ptype

file_name.ptype は、ptypeファイルの名前です。

#### 現在のセッションにおける既存のptypeに対するテスト

ToolTalkサービスは、指定のptypeがすでに現在のセッションに登録されているかど うかテストする、次のような関数を提供します。

    tt_ptype_exists(const char *ptype_id)

ptype_idは、登録用にテストするセッションの 識別子です。

#### コンパイルされたptypeファイルと現在実行中のttsessionのマージ

ToolTalkサービスは、コンパイルされたToolTalk型ファイルを現在実行中 の`ttsession`にマージする、次のような関数を提供します。

    tt_session_types_load (
                const char  *session,
                const char  *compile_types_file)

sessionは現在のデフォルトのToolTalkセッショ ンで、compiled_types_fileはコンパイルされた ToolTalk型ファイルの名前です。この関数は、新しい型を追加し、同じ名前の既存の型と 置換します。その他の既存の型は変更されません。

### 各ToolTalk対応アプリケーションが実行する必要があるタスク

各ToolTalk対応アプリケーションが実行する必要があるタスクは、多数あります。 たとえば次のとおりです。

- ツールキットの初期化

- ToolTalkセッションへの参加とパターンの登録

- ToolTalkサービスをそのイベント・ループへ追加

この節では、これらのタスクを実行できるようにアプリケーションに組み込む必要 があるToolTalkのコーディング例を取り上げます。

#### ツールキットの初期化

アプリケーションはツールキットを初期化し、ToolTalkの初期セッションに登録する 必要があります。そのためには、最初にプロセス識別子(procid)を取得します。次のコー ディングの一部分は、procidの取得方法とツールキットの初期化方法を示します。

    char *procid = ttdt_open(
                int        *tt_fd,
                const char *ptype_name,
                const char *vendor_name,
                const char *version,
                int        send_started)

アプリケーションは、他のToolTalkの呼び出しが行われる前に必ず `ttdt_open`を呼び出さなければなりません。そうしない場合、エラー が発生します。

#### ToolTalkセッションへの参加とメッセージ・パターンの登録

アプリケーションはメッセージを受信する前に、ToolTalkセッションに参加し、一致 するメッセージ・パターンを登録する必要があります。ttdt_session_join関数は メッセージ・パターンと多くの標準デスクトップ・メッセージ・インタフェース用の デフォルト・コールバックを登録します。

    Tt_pattern *sess_patt = ttdt_session_join(
                const char        *session_id,
                Ttdt_contract_cb  cb,
                Widget            shell,
                void              *client_data,
                int               join)

ptypeがアプリケーションにインストールされていた場合、 `ttdt_session_join`が呼ばれる前に、通常`ttmedia_ptype_ declare`が呼ばれるので、注意してください。

#### イベント・ループへのToolTalkサービスの追加

アプリケーションは、ToolTalkサービスをそのイベント・ループに追加することも 行わなければなりません。アプリケーションがXtクライアントの場合、 `XtAppAddInput`を以下のように使用します。

    XtAppAddInput (app_context,
                tt_fd(),
                (XtPointer) XtInputReadMask,
                tttk_Xt_input_handler,
                client_data)

### ToolTalk対応エディタ・アプリケーションが実行する必要があるタスク

前述の「各ToolTalk対応アプリケーションが実行する必要があるタスク」 で説明しているタスクの他に、ToolTalk対応エディタ・アプリケーションは次のタスクも 実行する必要があります。

- ptypeの宣言

- メディア・ロード・コールバックの記述

- メッセージ処理の受け入れ

- 要求完了時の応答

この節では、これらの追加タスクを実行できるようにエディタ・アプリケーションに 組み込む必要があるToolTalkのコーディング例を取り上げます。

#### ptypeの宣言

ptypeファイルがすでにアプリケーションにインストールされている場合、ptype をアプリケーションに関連付ける必要があります。この関連付けの宣言には、関数 ttmedia_ptype_declareが便利です。

    Tt_status status = ttmedia_ptype_declare(
                char                 *ptype_name,
                int                  base_opnum,
                Ttmedia_load_pat_cb  cb,
                void                 *client_data,
                int                  declare)

アプリケーションにptype ptype_nameが サポートする要求を出すように依頼がいくと、コールバック`cb`が 起動します。

#### メディア・ロード・パターン・コールバックの記述

ToolTalk関数を組み込むためのエディタ・アプリケーションをコーディングする前 に、メディア・ロード・コールバック・ルーチンを記述する必要があります。このコール バックは、`ttmedia_load`を呼び出すアプリケーションに別の アプリケーションが応答した時に起動します。

#### メッセージ処理の受け入れ

アプリケーションが`ttmedia_ptype_declare`ハンドラでメッ セージを受信した場合、要求の処理を受け入れるため次の関数を呼ぶ必要がある。

    Tt_pattern *desktop_patts = ttdt_message_accept (
                Tt_message        contract,
                Ttdt_contract_cb  cb,
                Widget            shell,
                void              *client_data,
                int               accept,
                int               send_status)

#### 要求完了時の応答

アプリケーションはオペレーションの要求を完了した後（たとえば、ドキュメント の編集）、送信側アプリケーションに応答しなければなりません。次の関数を使用して 応答およびテキストの編集された内容を送信側に返します。

    Tt_message msg = ttmedia_load_reply (
                Tt_message           contract,
                const unsigned char  *new_contents,
                int                  new_length,
                int                  reply_and_destroy)

### ToolTalk対応エディタ・アプリケーションが実行できるオプションのタスク

前述の「ToolTalk対応エディタ・アプリケーションが実行する必要のある タスク」で説明しているタスクの他に、エディタ・アプリケーションはその他の オプションのタスクも実行できます。オプションのタスクには、他のエディタとの調整を 取るためにデスクトップ・ファイル・インタフェースを使用するものなどがあります。この 節では、これらのオプションのタスクを実行できるようにエディタ・アプリケーションに 組み込む必要があるToolTalk関数をいくつか取り上げています。

#### オペレーションの変更、復元、または保存の要求

オペレーションの変更、復元、または保存を要求する時に次の関数を使用します。

- `ttdt_Get_Modified`

- `ttdt_Revert`

- `ttdt_Save`

#### ファイルの変更、復元、または保存時の通知

アプリケーションのファイルの変更、復元、または保存を他のToolTalk アプリケーションに通知する時に`ttdt_file_event`関数を使用しま す。

#### ファイルの終了

`ttdt_file_quit`関数は、ファイルに関するToolTalkイベント の配信対象を登録解除し、関連パターンを破棄します。