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.
The ToolTalk types mechanism is designed to help the ToolTalk service route messages. When your tool declares a ptype, 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 will be printed out in source format.
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:
An optional start string - The ToolTalk service will execute 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). Example 2-2 shows a snippet from the ptype file for the CoEd application.
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. */ }
After you have created the ptype file, you need to install the ptype. To do this, run the ToolTalk type compiler. On the command line, type the following:
% tt_type_compCoEd.ptype
where CoEd.ptype is the name of the CoED ptype file.
The ToolTalk service provides a simple function to test if a given ptype is already registered in the current session.
// Test for existing ptype registered in current session tt_ptype_exists(const char *ptid)
where ptid is the identifier of the session to test for registration.
The ToolTalk service provides a function to merge a compiled ToolTalk type file into the currently running ttsession:
// Merge new compiled ptypes into currently running ttsession tt_session_types_load(current_session, compiled_types_file)
where current_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.
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.
The code snippets used in this section are taken from the CoEd.C file. This file contains the general commands any application needs to perform that are not specific to any particular application. See Appendix B, The CoEd Demonstration Program for the detailed source code.
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 snippet shows how to obtain a procid and how to initialize the toolkit.
// Obtain process identifier int myTtFd; // Initialize toolkit and create a ToolTalk communication endpoint char *myProcID = ttdt_open( &myTtFd, ToolName, "SunSoft", "%I", 1 );
Your application must call ttdt_open before any other calls are made; otherwise, errors may occur.
Before your application can receive messages, it must join a ToolTalk session and register the message patterns that are to be matched.
// Join a ToolTalk session and register patterns and default callbacks sessPats = ttdt_session_join( 0, 0, session_shell, this, 1 ); }
Your application also needs to add the ToolTalk service to its event loop.
// Process ToolTalk events for Xt Clients XtAppAddInput( myContext, myTtFd, (XtPointer)XtInputReadMask, tk_Xt_input_handler, myProcID );
In addition to the duties described in the section "Tasks Every ToolTalk-aware Application Needs to Perform", ToolTalk-aware editor applications also need to perform other tasks, including:
Declaring a ptype
Processing the start string message
Passing a media callback
Failing 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.
The code snippets used in this section are taken from the CoEditor.C file. This file contains specific commands for editor applications. See Appendix B, The CoEd Demonstration Program for the detailed source code.
There is one step you need to perform before you code your editor application to include any ToolTalk functions: you need to write a media load pattern callback routine. For example,
Tt_message CoEditor::loadISOLatin1_( Tt_message msg, void *pWidget, Ttttk_op op, Tt_status diagnosis, unsigned char *contents, int len, char *file, char *docname )
This callback is passed to the media load function at runtime.
Since type information is specified only once (when your application is installed), your application needs to only declare its ptype each time it starts.
The media load pattern callback routine you wrote previously is passed in at runtime. The callbacks are registered when your application joins the session. When your tool agrees to handle a request, a callback message is sent. A callback message is also sent if a file is joined or if a message is failed.
// 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 );
After your application has completed the operation request, it must reply to the sending application. The following message returns the edited contents of text to the sender.
// Reply to media load pattern callback // with edited contents of text ttmedia_load_reply( _contract, (unsigned char *)contents, len, 1 );
In addition to the tasks described in the section "Tasks ToolTalk-aware Editor Applications Need to Perform" editor applications can also perform other optional tasks such as tasks that use desktop file interfaces to coordinate with other editors. This section provides examples of some of the ToolTalk code you need to include in your editor application so that it can perform these optional tasks.
The code snippets used in this section are taken from the CoEditor.C file. This file contains specific commands for editor applications. See Appendix B, The CoEd Demonstration Program for the detailed source code.
The following code snippet asks a file whether it has any changes pending:
// Does the file have any changes pending? _modifiedByOther = ttdt_Get_Modified( _contract, _file, TT_BOTH, 10 * timeOutFactor );
The following code snippet reverts a file to its last version:
// Revert file to last version status = ttdt_Revert(_contract, _file, TT_BOTH, 10 * timeOutFactor );
The following code snippet saves pending changes to a file:
// Save pending changes status = ttdt_Save( _contract, _file, TT_BOTH, 10 * timeOutFactor );
The following code snippet announces to interested tools that your application has changes pending for the file:
// File has been modified ttdt_file_event( _contract, TTDT_MODIFIED, _filePats, 1 );
The following code snippet announces to interested tools that your application has reverted the file to its last saved version:
// File has been reverted to last version ttdt_file_event( _contract, TTDT_REVERTED, _filePats, 1 );
The following code snippet announces to interested tools that your application has saved its pending changes for the file.
// File has been saved ttdt_file_event( _contract, TTDT_SAVED, _filePats, 1 );
The following code snippet unregisters interest in ToolTalk events about a file and destroys the patterns.
// Unregister interest in ToolTalk events and destroy patterns status = ttdt_file_quit( _filePats, 1 ); _filePats = 0;