Using ToolTalk Messaging
messagesgeneral information
Some code fragments shown in this chapter are taken from a
ToolTalk demo program called broadcast. See the directory
/usr/dt/examples/tt for the source code, Makefile
and README file.
Telling Your Application about ToolTalk Functionality
Before your application can use the inter-operability functionality
provided by the ToolTalk service and the Messaging Toolkit, it needs to
know where the ToolTalk libraries and toolkit reside.
Using the Messaging Toolkit and Including ToolTalk Commands
To use the ToolTalk service, an application calls ToolTalk functions
from the ToolTalk application programming interface (API). The Messaging
Toolkit provides higher-level functions than the ToolTalk API, such as
functions to register with the ToolTalk service, to create message
patterns, to send messages, to receive messages, and to examine message
information. To modify your application to use the ToolTalk service and
toolkit, you must include the following header files:
header files
#include <Tt/tt_c.h> /* ToolTalk Header File */
#include <Tt/tttk.h> /* Messaging Toolkit Header File */
Using the ToolTalk Library
library, ToolTalk
The ToolTalk library is located in the directory:
/usr/dt/lib
The library name is platform-dependent (for example, on Solaris it is named
libtt.so and on HP-UX is its named
libtt.sl).
Before You Start Coding
Before you can incorporate the Messaging Toolkit functionality into your
application, you need to determine the way that your tool will work with
other tools. There are several basic questions you need to ask:
How will these tools work together?
What kinds of operations can these tools perform?
What kinds of operations can these tools ask other tools to perform?
What events will these tools generate that may interest other tools?
(What types of messages will these tools want to send?)
What events generated by other tools will be of interest to these
tools? (What types of messages will these tools want to receive?)
To best answer these questions, you need to understand the difference
between events and operations, and how the ToolTalk service handles
messages regarding each of these.
What Is the Difference Between an Event and an Operation?
event defined
operation defined
An event is an announcement that something has happened. An event is
simply a news bulletin. The sending process has no formal expectations
as to whether any other process will hear about the event, or whether an
action is taken as a consequence of the event. When a process uses the
ToolTalk service to inform interested processes that an event has
occurred, it sends a notice. Since the sending process does not expect a
reply, an event cannot fail.
An operation is an inquiry or an action. The requesting process makes an
inquiry or requests that an operation be performed. The requesting
process expects a result to be returned and needs to be informed of the
status of the inquiry or action. When a process uses the ToolTalk
service to ask another tool to perform an operation, it sends a request.
The ToolTalk service delivers the request to interested processes and
informs the sending process of the status of the request.
Sending Notices
When your application sends a ToolTalk notice, it will not receive a
reply or be informed about whether or not any tool pays attention to the
notice. It is important to make the notice an impartial report of the
event as it happens. For example, if your tool sends the Desktop
Services message Modified, it may expect any listening tools to react in
a given way. Your tool, however, should not care, and does not need to
be informed about whether any or no other tool reacts to the message; it
only wants to report the event, THE_USER_HAS_MADE_CHANGES_TO_THIS.
Sending Requests
When your application sends a ToolTalk request, it expects one tool to
perform the indicated operation, or to answer the inquiry, and return a
reply message. For example, if your tool sends the Desktop Services
message Get_Modified, it should expect notification that the message was
delivered and the action performed. The ToolTalk service guarantees that
either a reply will be returned by the receiving process or the sender
will be informed of the request's failure.
You can identify requests in three ways:
By identifying the operations requested by your tool that can fail.
By identifying the operations your tool can perform for other tools.
By identifying the operations your tool will want other tools to perform.
A good method to use to identify these operations is to develop a
scenario that outlines the order of events and operations that you
expect your tool to perform and have performed.
Developing a Scenario
A scenario outlines the order of the events and operations that a tool
will expect to perform and to have performed. For example, the following
scenario outlines the events a generic editor could expect to perform
and to have performed:
User double-clicks on a document icon in the File Manager.
The file opens in the editor, which is started by the system if one is
not already running. (If another tool has modifications to the text
pending for the document, the user is asked whether the other tool
should save the text changes or revert to the last saved version of the
document.)
User inserts text.
User saves the document. (If another tool has modifications pending
for the document, the user is asked whether to modify the document.)
User exits the editor. (If text has unsaved changes, the user is
asked whether to save or discard the changes before quitting the file.)
Once the scenario is done, you can answer your basic questions.
How Will the Tools Work Together?
The File Manager requests that an editor open a document for
editing.
Each instance of the editor notifies other interested instances of
changes it makes to the state of the document.
What Kinds of Operations Do the Tools Perform?
Each instance of the editor can answer questions about itself and
its state, such as “What is your status?”
Each instance of the editor has the capability of performing
operations such as:
Iconifying and de-iconifying
Raising to front and lowering to back
Editing a document
Displaying a document (read-only)
Quitting
What Kinds of Operations Can the Tools Ask Other Tools to Perform?
The File Manager must request that the editor open a document for editing.
An instance of the editor can ask another instance of the editor to save changes to the open document.
An instance of the editor can ask another instance of the editor to revert to the last saved version of the open document.
What Events Will the Tools Generate that May Interest Other Tools?
The document has been opened.
The document has been modified.
The document has been reverted to last saved version.
The document has been saved.
An instance of the editor has been exited.
What Events Generated by Other Tools Will Be of Interest to This Tool?
The document has been opened.
The document has been modified.
The document has been reverted to last saved version.
The document has been saved.
An instance of the editor has been exited.
Preparing Your Application for Communication
The ToolTalk service provides you with a complete set of functions for
application integration. Using the functionality provided with the
ToolTalk Messaging Toolkit, your applications can be made to “speak” to
other applications that are ToolTalk-compliant. This section describes
how to add the kinds of ToolTalk functions you need to include in your
application so that it can communicate with other ToolTalk-aware
applications that follow the same protocols.
Creating a Ptype File
ptype file, creating
The ToolTalk types mechanism is designed to help the ToolTalk service
route messages. When your tool declares a ptype (process type), the message patterns
listed in it are automatically registered. The ToolTalk service then
matches messages it receives to these registered patterns. These static
message patterns remain in effect until the tool closes communication
with the ToolTalk service.
The ToolTalk Types Database already has installed ptypes for tools
bundled with this release. You can extract a list of the installed
ptypes from the ToolTalk Types Database, as follows:
% tt_type_comp -d user | system | network -P
The names of the ptypes are printed out in source format.
To generate a list of the installed ptypes including their signatures:
% tt_type_comp -d user | system | network -p
For all other tools (that is, tools that are not included in this
release), you need to first create a ptype file to define the ptype for
your application, and then compile the ptype with the ToolTalk type
compiler, tt_type_comp. To define a ptype, you need to include the
following information in a file:
A process-type identifier (ptid).
An optional start string — The ToolTalk service executes this command, if necessary, to start a process running the program.
Signatures — Describes the TT_PROCEDURE-addressed messages that the
program wants to receive. Messages to be observed are described
separately from messages to be handled.
To create a ptype file, you can use any text editor
(such as vi, emacs, or dtpad).
After you have created a ptype file, you need to install the ptype by
running the ToolTalk type compiler. On the command line, type:
% tt_type_comp file_name.ptype
where file_name.ptype
is the name of the ptype file.
Testing for Existing Ptypes in Current Session
ptypes, testing for existence of
The ToolTalk service provides the following function to test if a given
ptype is already registered in the current session:
tt_ptype_exists(const char *ptype_id)
where ptype_id is the identifier of the session to test for registration.
Merging a Compiled Ptype File into a Currently Running ttsession
The ToolTalk service provides the following function to merge a compiled
ToolTalk type file into the currently running ttsession:
tt_session_types_load (
const char *session,
const char *compile_types_file)
where session is the current default ToolTalk session and
compiled_types_file is the name of the compiled ToolTalk types file.
This function adds new types and replaces existing types of the same
name; other existing types remain unchanged.
Tasks Every ToolTalk-aware Application Needs to Perform
There are a number of tasks every ToolTalk-aware application needs to
perform, including:
Initializing the toolkit.
Joining a ToolTalk session and registering patterns.
Adding the ToolTalk service to its event loop.
This section provides examples of the ToolTalk code you need to include
in your application so that it can perform these tasks.
Initializing the Toolkit
toolkit initialization
Your application needs to initialize and register with the initial
ToolTalk session. To do so, it first needs to obtain a process
identifier (procid). The following code fragment shows how to obtain a
procid and how to initialize the toolkit.
char *procid = ttdt_open(
int *tt_fd,
const char *ptype_name,
const char *vendor_name,
const char *version,
int send_started)
Your application must call ttdt_open before any other ToolTalk
calls are made; otherwise, errors may occur.
Joining the ToolTalk Session and Registering Message Patterns
message patterns, registering
Before your application can receive messages, it must join a ToolTalk
session and register the message patterns that are to be matched. The
ttdt_session_join function registers patterns and default callbacks for
many standard desktop message interfaces.
Tt_pattern *sess_patt = ttdt_session_join(
const char *session_id,
Ttdt_contract_cb cb,
Widget shell,
void *client_data,
int join)
Note that if an application has ptypes installed, it will normally call
the function ttmedia_ptype_declare before calling ttdt_session_join.
Adding the ToolTalk Service to Event Loop
Your application also needs to add the ToolTalk service to its event
loop. If the application is an Xt client, it would use XtAppAddInput as
follows:
XtAppAddInput (app_context,
tt_fd(),
(XtPointer) XtInputReadMask,
tttk_Xt_input_handler,
client_data)
Tasks ToolTalk-aware Editor Applications Need to Perform
In addition to the duties described in the section “Tasks Every
ToolTalk-aware Application Needs to Perform” in this chapter,
ToolTalk-aware editor applications may also need to perform other tasks,
including:
Declaring a ptype.
Writing a media load callback.
Accepting a contract to handle a message.
Replying when a request has been completed.
This section provides examples of the ToolTalk code you need to include
in your editor application so that it can perform these additional
tasks.
Declaring a Ptype
ptype, declaring
If an application has a ptype file that has been installed, the ptypes
need to be associated with the application. The convenience function for
declaring this association is 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)
The callback cb is invoked when the application is asked to service
a request supported by the ptype ptype_name.
Writing a Media Load Pattern Callback
Before coding an editor application to include any ToolTalk functions,
you need to write a media load callback routine. This callback is
invoked when another application responds to your application's
ttmedia_load call.
Accepting a Contract to Handle a Message
When an application receives a message in its ttmedia_ptype_declare
handler, it should call the following function to accept a contract to
handle the request.
Tt_pattern *desktop_patts = ttdt_message_accept (
Tt_message contract,
Ttdt_contract_cb cb,
Widget shell,
void *client_data,
int accept,
int send_status)
Replying When Request Is Completed
After your application has completed the operation requested (for
example to edit a document), it must reply to the sending application.
The following function can be used to do the reply and to return the
edited contents of the text to the sender.
Tt_message msg = ttmedia_load_reply (
Tt_message contract,
const unsigned char *new_contents,
int new_length,
int reply_and_destroy)
Optional Tasks ToolTalk-aware Editor Applications Can Perform
In addition to the tasks described in the section “Tasks ToolTalk-aware
Editor Applications Need to Perform” in this chapter, editor
applications can also perform other optional tasks such as tasks that
use desktop file interfaces to coordinate with other editors. This
section mentions some of the ToolTalk functions you need to include in
your editor application so that it can perform these optional tasks.
Requesting Modify, Revert, or Save Operations
The following functions can be used to request modify, revert, or save
operations:
ttdt_Get_Modified
ttdt_Revert
ttdt_Save
Notifying When a File Is Modified, Reverted, or Saved
The function ttdt_file_event can be used to notify other ToolTalk
applications that your application's file has been modified, has
reverted, or has been saved.
Quitting a File
The function ttdt_file_quit unregisters interest in ToolTalk events
about a file and destroys the associated pattern.