NAME

apptalk - interapplication communication interface


SYNOPSIS

apptalk init target
apptalk proc name documentation body
apptalk connect target ?exec args?


DESCRIPTION

apptalk is a tcl command that can be run by both a server and client application. Embedded in a server application, apptalk accepts requests and processes them. Embedded in a client application, apptalk is a mechanism by which requests can be made to a server .

Using apptalk, you can initiate communication with another application without having to know it's specific application name (as returned by [tk appname]). You do, however, need to know how to start the application with which you want to communicate.

Apptalk uses logical names to associate an application (or applications) with a particular set of functionality. If multiple applications are running on a display, all with the same logical name, when a client request is made you will be given the opportunity to pick which server application to use (see the discussion on the X resource apptalk*policy, below).

Apptalk manages the communication by keeping track of the internal application name, and can start up an application automatically before the first command is sent to it.


Embedded in a server

To use apptalk as a server command, there are two forms of the command. The first form, apptalk init name , associates a logical name with the application. Logical names are used to associate a given functionality with a program. Examples of useful logical names are ``textedit'', ``testutil'', and so forth.

apptalk init target
Associates the logical name target with the server application. This name is used internally by clients to designate what type of server to connect to.

When a server is initialized, there are five commands that are created automatically. They may be overridden by the server with appropriate apptalk proc commands. These predefined commands are:

commands
returns a list of commands known by the server

exit
runs the command exit 0 (but may be redefined by the server)

info ?command?
returns usage information on a single command

popdown
causes the application to be iconified

popup
causes the application to be deiconified

apptalk proc name documentation body
Defines a new apptalk subcommand for the server application. The data in documentation is displayed by a call to the info server command.

Within the documentation string a sequence of %N will be replaced with the name of the server. Using %N instead of hard-coding the server name makes it easier to rename a server, or to cut and paste procedures between servers.

When the new command is called, all arguments are available to the procedure via the standard tcl argument args. The global variables apptalkServer and apptalkClient are also available.

Example:

	apptalk proc printargs {
	    usage: %N printargs
	    prints the name of the calling client, the name of
	    the server, and each argument.
	} {
	    puts stdout "client: $apptalkClient"
	    puts stdout "server: $apptalkServer"
	    foreach arg $args {
		puts stdout "argument: $arg"
	    }	    
	}


Embedded in a client

apptalk connect target ?exec args?
This establishes a connection between the client application and a server application. Once the connection has been established a new command will be available in the client named @target. For example, apptalk connect tkhello will create a command named @hello. This command can then be used to issue commands to the server application.

If no suitable server application is presently running on the same display, one will be started. If no exec args are provided, target will be passed to exec. Otherwise, exec args will be passed to exec. For example, apptalk connect foo will run the server app foo by issuing the tcl command exec foo. On the other hand, apptalk connect foo wish4.2 tkfoo will start the server application by issuing the tcl command exec wish4.2 tkfoo. Note that it is not required that target be the same as any of the exec args .

If a suitable server application is not running, the connection will be established in one of three ways based on the value of the resource apptalk*policy:

ask
You will be presented with a dialog box showing you the window titles of all applications that match the requested target . From the dialog you may choose one of the applications from the list or you may start a new application up.

first
The first suitable application that can be found will be used.

new
A new instance of the server application will be started.

Once a connection has been established, the @target command may be used to send commands to the server. For example, to cause the server ``hello'' to pop up you would use the command:

	apptalk connect hello
	@hello popup


EXAMPLE

Here is a simple ``Hello, World!'' wish script that is apptalk enabled. It is referenced by the logical name hello and has one command, named press_button , in addition to the predefined commands:

    wm title . "Hello, world!"

    button .b -text "Hello, world!" -command {puts stdout "Hello, world!"}
    pack .b

    apptalk init hello

    apptalk proc press_button {
	usage: %N press_button
	causes the hello, world button to be pressed.
    } {
	.b invoke
    }

From within some other script, we can cause the button to be pressed with the following sequence (assuming the above script was saved in a file named hello.tcl :

    wish> apptalk connect hello wish hello.tcl
    wish> @hello press_button

To see the documentation for the press_button command, we can do the following in an interactive wish shell:

    wish> @hello info press_button
    press_button:
        usage: @hello press_button
        causes the hello, world button to be pressed.
    wish>


BUGS

If you aren't careful with apptalk connect and request an application that is not apptalk enabled, the client program will wait forever for the application to start up. That is because the client program waits for notification that is sent by the server. If the server isn't apptalk enabled, it won't know to send the notification. Such is life.

Running an apptalk enabled server or client in an application that can't use send is a problem. Most likely the send command will fail but you'll have no way to know. Many of the times send is used the errors are caught (and ignored) or never seen (such as when using send -async). I need to do something about this. Perhaps I need to use sockets instead of send.