This is apptalk v1.0b1

Copyright (c) 1996, Healthcare Communications, Inc
All Rights Reserved

See the file "license.terms" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL 
WARRANTIES.

Send comments to oakley@healthcare.com

You will find the following files in this directory:

README        - this file
license.terms - licensing information
apptalk.tcl   - the apptalk code
apptalk.pod   - the apptalk man page in perlpod format
apptalk.3     - apptalk.pod, formatted as a man page
apptalk.html  - apptalk.pod, formatted in html
hello.tcl     - the quintessential "hello, world!" program that
                has been made "apptalk-aware"

Installation Instructions:

apptalk is implemented in a single file. Simply arrange for it to be
loaded into any application that uses it, either via auto-loading, the
source command, or included directly in the application's file.

What is apptalk?

apptalk is tcl based front-end to tk's built-in send command (or any
other communication mechanism that has a syntax that can be mapped to
the syntax of the send command). The apptalk code is *not* an end-user
program, but rather is intended to enable application developers to
add simple cross-application communication to a program or suite of
programs, (almost) hassle-free.

Put another way, apptalk allows you, the application developer, to put
a scriptable interface on your application. Without having to publish
widget paths or global variables, you can still provide access to
internal routines through a public API. When the code changes (for
example, reorganizing the widgets) you only have to update the API,
and any program that references it will continue to work.

Why use it?

apptalk removes some of the tedium associated with setting up
communication between two or more tk based applications. Plus, it
provides a layer of abstraction between the programs. One can
provide a public interface to an application without having to publish
widget paths, global variables on so on.

A philosophical example:

Imagine a fictitious application named "tkwebbrowser", a program which
can fetch and display HTML. Some other application that has it's 
documentation in html format could request tkwebbrowser to display
that documentation with the following short piece of code:

    apptalk connect tkwebbrowser
    @tkwebbrowser fetch $some_url
    @tkwebbrowser popup


If tkwebbrowser is already running it will load the requested document
and make sure it is deiconified. If it is not running it will be
started automatically, then the requested document will be fetched. No
muss, no fuss.

Imagine now if tkmailreader, tktextedit and tknewsreader (all fictional
apps...) were all apptalk enabled. They could all talk to each other,
sharing information and requesting services of each other, all without
each program having to know internal widget paths and functions of the
others. New releases of the apps could come and go, but as long as the
apptalk commands haven't changed (though their *implementation* could
change dramatically), the other programs wouldn't have to be updated
to continue to communicate.

Features:

* servers (ie: apptalk-enabled applications) are referenced by logical
  names instead of the internal tk application names, so clients
  (applications which makes requests to a server) don't have to be
  concerned with the fact a server's tk id is "foo" or "foo #2". 

* servers can automatically be started by a client on an as-needed
  basis, or an already running server can be detected and
  automatically "attached" to the client. Once "attached", the
  connection remains until one of the programs is halted.

* if multiple servers with the same logical name are running, an 
  apptalk client can present a dialog box to let the user pick which
  application to interact with. A "Show Me" button let's the user
  see which window belongs to each application listed in the dialog
  listbox. 

* server commands are self-documented. A client can request that a
  server send usage information on a given command, or send a list
  of all available commands. This feature could be useful, for 
  example, if you get an apptalk enabled application off the net and
  want to use it as a server to your own client. You can simply
  ask the application what apptalk commands it responds to.

* all apptalk enabled applications share a common base of commands:
  - commands   returns a list of commands known by the server
  - exit       runs the command "exit 0" (but may be redefined by the 
               server)
  - info       get information on a command
  - popdown    causes the application to be iconified
  - popup      causes the application to be deiconified

How it works:

Ok, let's look at an example. We have a program named "hello" which
is the quintessential "Hello, world" application. We want to build
apptalk in to this program so that other programs can request that it
display the "hello, world." dialog. This will become our SERVER program.

Here is the pre-apptalk version:

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

Regardless of the name of the file that implements this program, we
want it to be identified by the logical name "hello". To do so we must 
add code to our application to initialize apptalk:

  apptalk init hello wish hello.tcl
  button .b -text "Hello, world!" -command "puts stdout {Hello, world!}"
  pack .b

Just doing that creates a new proc named "hello", whose sole purpose
is to service apptalk requests. It simply takes as arguments command
names that have been defined as apptalk commands. Since we haven't defined
any commands yet, the only valid arguments are the built-in apptalk
commands popup, popdown, info, commands and exit. 

Ok, we've now "apptalk-enabled" our hello, world program. Let's test
it out.

To test our application, the easiest thing to do for the moment is to
start a wish in some other window. Be sure to load apptalk.tcl if it
isn't autoloaded for you.

    $ wish
    wish> source apptalk.tcl
    wish> 

Once the prompt appears, the first thing we need to do is establish a
link between our program and the apptalk server program we created
earlier. To do that we use "apptalk connect", giving it the logical
name of the program we want to run, and instructions on how to run it
if it isn't already running

    wish> apptalk connect hello wish hello.tcl

If you left your hello, world program running it would connect to
it. If it wasn't running, you might see a message stating that apptalk
is starting the program for you (this depends on how fast your machine
is -- if the program can start in less than a second you won't see the
dialog).

When the connection is established, a new command will be available to
us in the wish shell. In this case it will be named "@hello", and is
responsible for sending commands to the program we connected to
earlier. Let's see what commands have been defined:

    wish> @hello commands
    commands exit info popdown popup

As you can see, the five pre-defined commands already exist. Now let's
add a new apptalk command to our hello, world program. We'll name the
command "press_button", and it's purpose will be to cause the button
to be pressed. Back in the "hello, world" file enter the following
code:

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

Once we restart the program, we can access this new command from a
wish interpreter like so:

    wish> @hello press_button

which will do exactly the same thing as if we had pressed the button
using the mouse.


