This chapter describes how to provide static message pattern information to the ToolTalk service. The ToolTalk service uses message patterns to determine message recipients. After receiving a message, the ToolTalk service compares the message to all current message patterns to find a matching pattern. Once a match is made, the message is delivered to the application listed in the message pattern.
You can provide message pattern information to the ToolTalk service using either dynamic or static methods, or both. The method you choose depends on the type of messages you want to receive.
If the types of messages you want to receive will vary while your application is running, the dynamic method allows you to add, change, or remove message pattern information after your application has started. See Chapter 3, “Dynamic Message Patterns,” for more information.
If you want to receive a defined set of messages, the static method provides an easy way to specify the message pattern information.
Regardless of the method you choose to provide message patterns to the ToolTalk service, you will want to update these patterns with each current session and file information so that you receive all messages that refer to the session or file in which you are interested.
The attributes in your message pattern specify the type of messages you want to receive and, to some extent, the number of messages you receive. You can supply multiple values for each attribute you add to a pattern. However, some attributes are set and have only one value.
Table 4-1 provides a complete list of attributes you can put in your message patterns.
Table 4-1. ToolTalk Static Message Pattern Attributes
Pattern Attribute | Value | Description |
---|---|---|
Category | TT_OBSERVE, TT_HANDLE, | Declares whether you want to perform the operation listed in a message or only view a message. |
Scope | TT_SESSION, TT_FILE, TT_BOTH, TT_FILE_IN_SESSIO N | Declares interest in messages about a session or a file, or both; Join a session or file after the message pattern is registered to update the sessid and filename. |
Arguments | arguments or results | Declares the arguments for the operation in which you are interested. |
Class | TT_NOTICE, TT_REQUEST | Declares whether you want to receive notices or requests, or both. |
File | char *pathname | Declares the files in which you are interested. |
Object | char *objid | Declares what objects in which you are interested. |
Operation | char *opname | Declares what operations in which you are interested. |
Otype | char *otype | Declares the type of objects in which you are interested. |
address | TT_PROCEDURE, TT_OBJECT, TT_HANDLER, TT_OTYPE | Declares what type of address in which you are interested. |
disposition | TT_DISCARD, TT_QUEUE, TT_START | Instructs the ToolTalk service how to handle undeliverable messages to your application. |
sender | char *procid | Declares the sender in which you are interested. |
sender_ptype | char *ptype | Declares the type of sending process in which you are interested. |
session | char *sessid | Declares the session in which you are interested. |
state | TT_CREATED, TT_SENT, TT_HANDLED, TT_FAILED, TT_QUEUED, TT_STARTED, TT_REJECTED | Declares the state of the message in which you are interested. |
All your message patterns must minimally specify:
Scope — Whether the application is interested in messages about a particular session or file.
Use TT_SESSION to receive messages from other processes in your session.
Use TT_FILE to receive messages about the file you have joined.
Use TT_FILE_IN_SESSION to receive messages for the file you have joined while in this session.
![]() | Note: Messages that have a TT_BOTH scope will match your pattern if it has either TT_FILE or TT_SESSION. |
Category — Whether the application wants to perform operations listed in messages or only view messages.
Use TT_OBSERVE if you only want to view messages.
Use TT_HANDLE to if you want to perform operations listed in the message.
The ToolTalk service compares message attributes to pattern attributes as follows:
If no pattern attribute is specified, the ToolTalk service counts the message attribute as matched. The fewer pattern attributes you specify, the more messages you become eligible to receive.
If there are multiple values specified for a pattern attribute, one of the values must match the message attribute value. If no value matches, the ToolTalk service will not consider your application as a receiver.
This chapter describes how to provide process and object type information to Static Message Patterns.
The static messaging method provides an easy way to specify the message pattern information if you want to receive a defined set of messages.
To use the static method, you define your process types and object types and compile them with the ToolTalk type compiler, tt_type_comp. When you declare your type information, the ToolTalk service creates message patterns based on the information. These static message patterns remain in effect until you close communication with the ToolTalk service.
Your application can still be considered a potential message receiver even when no process is running the application. To do this, you provide message patterns and instructions on how to start the application in a process type (ptype) file. These instructions tell the ToolTalk service to perform one of the following actions when a message is available for an application but the application is not running:
Start the application and deliver the message
Queue the message until the application is running
Discard the message
To make the information available to the ToolTalk service, the ptype file is compiled with the ToolTalk type compiler, tt_type_comp, at application installation time.
When an application registers a ptype file with the ToolTalk service, the message patterns listed in it are automatically registered, too.
The ptype provides application information that the ToolTalk service can use when the application is not running. This information is used to start your processes if necessary, to receive a message, queue messages until the process starts, or deliver TT_PROCEDURE-addressed messages to your process.
A ptype begins with a process-type identifier (ptid). Following the ptid are:
An optional start string — the ToolTalk service will execute this command, if necessary, to start a process running the program.
Signatures — Describes the procedure and process messages that the program wants to receive. Messages to be observed are described separately from messages to be handled.
Signatures describe the procedure and process messages that the program wants to receive. A signature is divided by an arrow (=>) into two parts. The first part of a signature specifies matching attribute values. The more attribute values specified in a signature, the fewer messages the signature will match. The second part of a signature specifies receiver values that the ToolTalk service will copy into messages that match the first part of the signature.
A ptype signature can contain values for disposition and operation numbers (opnum). The ToolTalk service uses the disposition value (start, queue, or the default discard) to determine what to do with a message that matches the signature when no process is running the program. The opnum value is provided as a convenience to message receivers. When two signatures have the same operation name but different arguments, different opnums makes incoming messages easy to identify.
The following code example shows the syntax for a ptype file
ptype::='ptype' ptid `{' property* [`observe:' psignature*] [`handle:' psignature* ] `}' [`;'] property::=property_id value `;' property_id::=`per_file' |`per_session' |`start' value::=string |number ptid::= identifier psignature::=[scope] op args [`=>' [`start'][`queue'] [`opnum='number]] `;' scope:=`file' |`session' |`file_in_session' args::=`(` argspec {, argspec}* `)' |`(void)' |`()' argspec::=mode type name mode::=`in' | `out' | `inout' type::=identifier name:=identifier |
ptid |
| |
per_file |
Set this limit to 1 for tools that cannot handle multiple processes updating the same file. | |
per_session |
Set this limit to 1 for tools that manage multiple files in one process. All files will then be handled by a single process in each user session. | |
start |
Before executing the command, the ToolTalk service defines _SUN_TT_FILE as an environment variable with the value of the file attribute of the message that caused the application to be started. The _SUN_TT_FILE value has the following format: hostname:pathname, even though the file attribute is a pathname. This command runs in the environment of ttsession, not in the environment of the sender of the message that started the application, so any context information must be carried by message arguments. |
op |
| |||
args |
| |||
scope |
|
start |
| |
queue |
| |
opnum |
|
The following sample code illustrates a ptype file.
#include "Sun_EditDemo_opnums.h" ptype Sun_EditDemo { /* setenv SUN_EDITDEMO_HOME to install dir for the demo */ start“${SUN_EDITDEMO_HOME}/edit”; handle: /* edit file named in message, start editor if necessary */ session Sun_EditDemo_edit(void) => start opnum=SUN_EDITDEMO_EDIT; /* tell editor viewing file in message to save file */ session Sun_EditDemo_save(void) => opnum=SUN_EDITDEMO_SAVE; /* save file named in message to new filename */ session Sun_EditDemo_save_as(in string new_filename) => opnum=SUN_EDITDEMO_SAVE_AS; /* bring down editor viewing file in message */ session Sun_EditDemo_close(void) => opnum=SUN_EDITDEMO_CLOSE; }; |
The Sun_EditDemo_opnums.h file defines symbolic definitions for all the opnums used by edit.c, allowing both the edit.types file and edit.c file to share the same definitions.
The following sample code illustrates a ptype file for the ttsample2_sgi example:
/* ttsample2_sgi_ptypes - ptype definitions for ttsample2_sgi example */ #include “ttsample2_sgi_opnums.h” ptype TTSAMPLE2 { start “/usr/tmp/ttsample2_sgi_service”; handle: session ttsample2_value(in int send, out int receive) => start opnum=TTSAMPLE2_VALUE; }; |
When a message is addressed to a specific object or a type of object, the ToolTalk service must be able to determine to which application the message is to be delivered. Applications provide this information in an object type (otype) file. An otype file contains the ptype information of the application that manages the object and message patterns that pertain to the object.
These message patterns also contain instructions that tell the ToolTalk service what to do if a message is available but the application is not running. In this case, ToolTalk performs one of the following instructions:
Start the application and deliver the message
Queue the message until the application is running
Discard the message
To make the information available to the ToolTalk service, the otype file is compiled with the ToolTalk type compiler tt_type_comp at application installation time. When an application that manages objects registers with the ToolTalk service, it declares its ptype. When a ptype is registered, the ToolTalk service checks for otypes that mention the ptype and registers the patterns found in these otypes.
The otype for your application provides addressing information that the ToolTalk service uses when delivering object-oriented messages. The number of otypes you have, and what they represent, depends on the nature of your application. For example, a word processing application might have otypes for characters, words, paragraphs, and documents; a diagram editing application might have otypes for nodes, arcs, annotation boxes, and diagrams.
An otype begins with an object-type identifier (otid). Following the otid are:
An optional start string — ToolTalk will execute this command, if necessary, to start a process running the program.
Signatures — Code that defines the messages that can be addressed to objects of the type (that is, the operations that can be invoked on objects of the type).
Signatures defines the messages that can be addressed to objects of the type. A signature is divided by an arrow (=>) into two parts. The first part of a signature defines matching criteria for incoming messages. The second part of a signature defines receiver values which the ToolTalk service adds to each message that matches the first part of the signature. These values specify the ptid of the program that implements the operation and the message's scope and disposition.
The following code sample shows the syntax for an otype file.
otype ::= obj_header'{' objbody* '}' [';'] obj_header ::= 'otype' otid [':' otid+] objbody ::= `observe:' osignature* | `handle:' osignature* osignature ::= op args [rhs][inherit] `;' rhs ::= [`=>' ptid [scope]] [`start'][`queue'] [`opnum='number] inherit ::= `from' otid args ::= `(` argspec {, argspec}* `)' | `(void)' | `()' argspec ::= mode type name mode ::= `in' | `out' | `inout' type ::= identifier name ::= identifier otid ::= identifier ptid ::= identifier |
otid |
|
The object body portion of the otype definition is a list of osignatures for messages about the object that your application wants to observe and handle.
op |
| |||
args |
| |||
ptid |
| |||
opnum |
| |||
inherit |
| |||
scope |
|
start |
| |
queue |
|
The following sample code illustrates an otype file.
Include "Sun_EditDemo_opnums.h" otype Sun_EditDemo_object { handle: /* hilite object given by objid, starts editor if necessary */ hilite_obj(in string objid) => Sun_EditDemo session start opnum=SUN_EDITDEMO_HILITE_OBJ; }; |
The Sun_EditDemo_opnums.h file defines symbolic definitions for all the opnums used by edit.c, allowing both the edit.types file and edit.c file to share the same definitions.
The types database makes ptype and otype information available on the host that executes the sending process, the host that executes the receiving process, and the hosts that run the sessions to which the processes are joined.
To start applications and to queue messages, the ptype definition must be placed into the types database.
To receive messages addressed to objects your application creates and manages, the otype definitions must also be installed in the types database.
To place your type information into the xdr format types database and make it available to the ToolTalk service, you compile your type files with the ToolTalk type compiler, tt_type_comp. This compiler creates the types database definitions for your type information and stores them in the types database.
To install an application's ptype and otype, run tt_type_comp on your type file:
% tt_type_comp <your-file> |
tt_type_comp runs your-file through cpp, compiles the type definitions, and merges the information into the types database.
By default, tt_type_comp uses the user database. To specify another database, use the -d option; for example:
% tt_type_comp -d user|system|network <your-file> |
For more information on tt_type_comp, see the man page.
![]() | Note: When you run tt_type_comp on your ptype or otype files, it first runs cpp on the file and then checks the syntax before it places the data into the XDR format. If syntax errors are found, a message is displayed that indicates the line number of the cpp file. To find the line, enter |
cpp -P source-file temp-file |
and view the temp-file to find the error on the line reported by tt_type_comp.
After you run tt_type_comp, you need to make your type information available to the ToolTalk service. To do this, tell the ToolTalk service to read the type information in the types database as follows:
Since type information is only specified once (when your application is installed), your application needs to only declare its ptype each time it starts.
To register your ptype information with the ToolTalk service, use tt_ptype_declare() during your application's ToolTalk initialization routine. The ToolTalk service will read the type information and create the message patterns listed in your ptype and any otypes that reference the specified ptype.
The message patterns created when you declare your ptype information exist in memory until your application exits the ToolTalk session.
![]() | Note: The message patterns created when you declare your ptype information cannot be unregistered with tt_pattern_unregister(). |
The following code sample registers its ptype during its edit.c program initialization.
/* * Initialize our ToolTalk environment. */ int edit_init_tt() { int mark; char *procid = tt_open(); int ttfd; void edit_receive_tt_message(); mark = tt_mark(); if (tt_pointer_error(procid) != TT_OK) { return 0; } if (tt_ptype_declare(“Sun_EditDemo”) != TT_OK) { fprintf (stderr,”Sun_EditDemo is not an installed ptype.\n”); return 0; } ttfd = tt_fd(); notify_set_input_func(edit_ui_base_window, (Notify_func)edit_receive_tt_message, ttfd); tt_session_join(tt_default_session()); /* * Note that without tt_mark() and tt_release(), the * above combination would leak storage * tt_default_session() returns a copy owned by the * application, but since we don't assign the * pointer to a variable we could not free it * explicitly. */ tt_release(mark); return 1; } |
The following code sample registers its ptype during its ttsample2_sgi_service.c program initialization.
/* declare ptype * note there is no dynamic pattern registration */ if (tt_ptype_declare(“TTSAMPLE2”) != TT_OK) { /* TTSAMPLE2 is not an installed ptype */ fprintf(stderr, “No TTSAMPLE2 type for ToolTalk\n”); exit(-1); } |
Your application will use either process-oriented messages or object-oriented messages to communicate with other applications. To send messages to types of processes, types of objects, and specific objects, ptypes (for process-oriented messages) and otypes (for object-oriented messages) are required. This type information is compiled at application installation time and stored in the types database.
To communicate with other vendors' applications, you must know their ptypes and possibly their otypes (depending on the method of messaging you choose).