\c wish.tex
\c Geoffrey Furnish
\c 9 May 1994

\node Extended WISH, API, Drivers, Top
\chapter{Building an Extended WISH}
\cindex{wish}
\cindex{Tcl Extensions}

Beginning with PLplot 5.0, a new and powerful paradigm for interaction
with PLplot is introduced.  This new paradigm consists of an
integration of PLplot with a powerful scripting language (Tcl), and
extensions to that language to support X Windows interface development
(Tk) and object oriented programming ([incr Tcl]).  Taken together,
these four software systems (Tcl/Tk/itcl/PLplot) comprise a powerful
environment for the rapid prototyping and development of
sophisticated, flexible, X Windows applications with access to the
PLplot API.  Yet that is only the beginning--Tcl was born to be
extended.  The true power of this paradigm is achieved when you add
your own, powerful, application specific extensions to the above
quartet, thus creating an environment for the development of wholly
new applications with only a few keystrokes of shell programming ...

\begin{menu}
* Tcl Intro::		The Tool Command Language
* Tk Intro::		User Interface Programming with Scripts
* Itcl Intro::		All the above with Object Orientation
* PLplot Extensions::	Using PLplot from Tcl.
* Custom Extensions::	Making your own WISH
\end{menu}

\node Tcl Intro, Tk Intro, Extended WISH, Extended WISH
\section{Introduction to Tcl}
\cindex{Tcl}
\cindex{What is Tcl}
\cindex{Programming with Tcl}

The Tool Command Language, or just Tcl (pronounced ``tickle'') is an
embedable script language which can be used to control a wide variety
of applications.  Designed by John Ousterhout of UC Berkeley, Tcl is
freely available under the standard Berkeley copyright.  Tcl and Tk
(described below) are extensively documented in a new book published by
Addison Wesley, entitled ``Tcl and the Tk toolkit'' by John
Ousterhout.  This book is a must have for those interested in
developing powerful extensible applications with high quality X
Windows user interfaces.  The discussion in this chapter cannot hope
to approach the level of introduction provided by that book.  Rather
we will concentrate on trying to convey some of the excitement, and
show the nuts and bolts of using Tcl and some extensions to provide a
powerful and flexible interface to the PLplot library within your
application.

\begin{menu}
* Motivation for Tcl::		Why Tcl exists
* Capabilities of Tcl::		What it can do for you
* Acquiring Tcl::		Where to get it, supporting tools, etc.
\end{menu}

\node Motivation for Tcl, Capabilities of Tcl, Tcl Intro, Tcl Intro
\subsection{Motivation for Tcl}

The central observation which led Ousterhout to create Tcl was the
realization that many applications require the use of some sort of a
special purpose, application specific, embedded ``macro language''.
Application programmers cobble these ``tiny languages'' into their
codes in order to provide flexibility and some modicum of high level
control.  But the end result is frequently a quirky and fragile
language.  And each application has a different ``tiny language''
associated with it.  The idea behind Tcl, then, was to create a single
``core language'' which could be easily embedded into a wide variety
of applications.  Further, it should be easily extensible so that
individual applications can easily provide application specific
capabilities available in the macro language itself, while still
providing a robust, uniform syntax across a variety of applications.
To say that Tcl satisfies these requirements would be a spectacular
understatement.

\node Capabilities of Tcl, Acquiring Tcl, Motivation for Tcl, Tcl Intro
\subsection{Capabilities of Tcl}

The mechanics of using Tcl are very straightforward.  Basically you
just have to include the file \file{tcl.h}, issue some API calls to
create a Tcl interpreter, and then evaluate a script file or perform
other operations supported by the Tcl API.  Then just link against 
\file{libtcl.a} and off you go.

Having done this, you have essentially created a shell.  That is, your
program can now execute shell scripts in the Tcl language.  Tcl
provides support for basic control flow, variable substitution file
i/o and subroutines.  In addition to the builtin Tcl commands, you can
define your own subroutines as Tcl procecdures which effectively
become new keywords.

But the real power of this approach is to add new commands to the
interpretter which are realized by compiled C code in your
application.  Tcl provides a straightforward API call which allows you
to register a function in your code to be called whenever the
interpretter comes across a specific keyword of your choosing in the
shell scripts it executes.

This facility allows you with tremendous ease, to endow your
application with a powerful, robust and full featured macro language,
trivially extend that macro language with new keywords which trigger
execution of compiled application specific commands, and thereby raise
the level of interaction with your code to one of essentially shell
programming via script editing.

\node Acquiring Tcl, , Capabilities of Tcl, Tcl Intro
\subsection{Acquiring Tcl}

There are several important sources of info and code for Tcl.
Definitely get the book mentioned above.  The Tcl and Tk toolkits are
distributed by anonymous ftp at \file{sprite.berkeley.edu:/tcl}.
There are several files in there corresponding to Tcl, Tk, and various
forms of documentation.  At the time of this writing, the current
versions of Tcl and Tk are 7.3 and 3.6 respectively.  Retrieve those
files, and install using the instructions provided therein.

The other major anonymou ftp site for Tcl is
\file{harbor.ecn.purdue.edu:/pub/tcl}.  Harbor contains a mirror of
\file{sprite} as well as innumerable extensions, Tcl/Tk packages,
tutorials, documentation, etc.  The level of excitement in the Tcl
community is extraordinarily high, and this is reflected by the great
plethora of available, high quality, packages and extensions available
for use with Tcl and Tk.  Explore--there is definitely something for
everyone.

Additionally there is a newsgroup, \file{comp.lang.tcl} which is well
read, and an excellent place for people to get oriented, find help,
etc.  Highly recommended.

In any event, in order to use the Tk and Tcl-DP drivers in PLplot, you
will need at a miniumum, \file{tcl7.3.tar.gz}, \file{tk3.6.tar.gz} and
\file{tcl-dp-3.1.tar.gz}.  Additionally, in order to use the extended
WISH paradigm (described below) you will need \file{itcl-1.5.tar.gz}.
Because of these dependencies, the PLplot ftp archive site provides
these files as well.  You can retrieve them when you get PLplot.

However, you will quite likely find Tcl/Tk to be very addictive, and
the great plethora of add-ons available at \file{harbor} wil
undoubtedly attract no small amount of your attention.  It has been
our experience that all of these extensions fit together very well.
You will  find that there are large sectors of the Tcl user community
which create so-called ``MegaWishes'' which combine many of the
available extensions into a single, heavily embellished, shell
interpretter.  The benefits of this approach will become apparent as
you gain experience with Tcl and Tk.

\node Tk Intro, Itcl Intro, Tcl Intro, Extended WISH
\section{Introduction to Tk}
\cindex{Tk}
\cindex{Programming Tk}

As mentioned above, Tcl is designed to be extensible.  The first and
most basic Tcl extension is Tk, an X11 toolkit.  Tk provides the same
basic facilities that you may be familiar with from other X11 toolkits
such as Athena and Motif, except that they are provided in the context
of the Tcl language.  There are C bindings too, but these are seldom
needed--the vast majority of useful Tk applications can be coded using
Tcl scripts.

If it has not become obvious already, it is worth noting at this point
that Tcl is one example of a family of languages known generally as
``Very High Level Languages'', or VHLL's.  Essentially a VHLL raises
the level of programming to a very high level, allowing very short
token streams to accomplish as much as would be required by many
scores of the more primitive actions available in a basic HLL.
consider, for example, the basic ``Hello World!'' application written
in Tcl/Tk.
\begin{verbatim}
#!/usr/local/bin/wish -f

button .hello -text "Hello World!"  -command "destroy ."
pack .hello
\end{verbatim}

That's it!  That's all there is to it.  If you have ever programmed X
using a traditional toolkit such as Athena or Motif, you can
appreciate how amazingly much more convenient this is.  If not, you
can either take our word for it that this is 20 times less code than
you would need to use a standard toolkit, or you can go write the same
program in one of the usual toolkits and see for yourself...

We cannot hope to provide a thorough introduction to Tk programming in
this section.  Instead, we will just say that immensely complex
applications can be constructed merely by programming in exactly the
way shown in the above script.  By writing more complex scripts, and
by utilizing the additional widggets provided by Tk, one can create
beautiful, extensive user interfaces.  Moreover, this can be done in a
tiny fraction of the time it takes to do the same work in a
conventional toolkit.  Literally minutes versus days.

Tk provides widgets for labels, buttons, radio buttons, frames with or
without borders, menubars, pull downs, toplevels, canvases, edit
boxes, scroll bars, etc.

A look at the interface provided by the PLplot Tk and Tcl-DP drivers
should help give you a better idea of what you can do with this
paradigm.  Also check out some of the contributed Tcl/Tk packages
available at harbor.  There are high quality Tk interfaces to a great
many familiar unix utilites ranging from mail to info, to SQL, to
news, etc.  The list is endless and growing fast...

\node Itcl Intro, PLplot Extensions, Tk Intro, Extended WISH
\section{Introduction to [incr Tcl]}
\cindex{[incr Tcl]}
\cindex{object oriented Tcl}

Another extremely powerful and popular extension to Tcl is [incr Tcl].
[incr Tcl] is to Tcl what C++ is to C.  The analogy is very extensive.
Itcl provides an object orientated extension to Tcl supporting
clustering of procedures and data into what is called an
\code{itcl_class}.  An \code{itcl_class} can have methods as well as
instance data.  And they support inheritance.  Essentially if you know
how C++ relates to C, and if you know Tcl, then you understand the
programming model provided by Itcl.

In particular, you can use Itcl to implement new widgets which are
composed of more basic Tk widgets.  A file selector is an example.
Using Tk, one can build up a very nice file selector comprised of more
basic Tk widgets such as entries, listboxes, scrollbars, etc.

But what if you need two file selectors?  You have to do it all again.
Or what if you need two different kinds of file selectors, you get to
do it again and add some incremental code.

This is exactly the sort of thing object orientation is intended to
assist.  Using Itcl you can create an \code{itcl_class FileSelector}
and then you can instantiate them freely as easily as:
\begin{verbatim}
    FileSelector .fs1
    .fs1 -dir . -find "*.cc"
\end{verbatim}
and so forth.

These high level widgets composed of smaller Tk widgets, are known as
``megawidgets''.  There is a developing subculture of the Tcl/Tk
community for designing and implementing megawidgets, and [incr Tcl]
is the most popular enabling technology.

In particular, it is the enabling technology which is employed for the
construction of the PLplot Tcl extensions, described below.

\node PLplot Extensions, Custom Extensions, Itcl Intro, Extended WISH
\section{PLplot Extensions to Tcl}
\cindex{PLplot Tcl extension}
\cindex{Tcl extension}

Following the paradigm described above, PLplot provides extensions to
Tcl as well, designed to allow the use of PLplot from Tcl/Tk programs.
Essentially the idea here is to allow PLplot programmers to achieve
two goals:
\begin{itemize}
\item To access PLplot facilties from their own extended WISH and/or
Tcl/Tk user interface scripts.

\item To have PLplot display its output in a window integrated
directly into the rest of their Tcl/Tk interface.
\end{itemize}

For instance, prior to PLplot 5.0, if a programmer wanted to use
PLplot in a Tcl/Tk application, the best he could manage was to call
the PLplot C api from compiled C code, and get the output via the Xwin
driver, which would display in it's own toplevel window.  In other
words, there was no integration, and the result was pretty sloppy.

With PLplot 5.0, there is now a supported Tcl interface to PLplot
functionality.  This is provided through a ``family'' of PLplot
megawidgets implemented in [incr Tcl].  Using this interface, a
programmer can get a PLplot window/widget into a Tk interface as
easily as:
\begin{example}
PLWin .plw
pack .plw
\end{example}
Actually, there's the update/init business--need to clear that up.

The \code{PLWin} class then mirrors much of the PLplot C API, so that
a user can generate plots in the PLplot widget entirely from Tcl.
This is demonstrated in the \file{tk02} demo,

\node Custom Extensions, , PLplot Extensions, Extended WISH
\section{Custom Extensions to Tcl}

By this point, you should have a pretty decent understanding of the
underlying philosophy of Tcl and Tk, and the whole concept of
extensions, of which [incr Tcl] and PLplot are examples.  These alone
are enough to allow the rapid prototyping and development of powerful,
flexible grpahical applications.  Normally the programmer simply
writes a shell script to be executed by the Tk windowing shell,
\code{wish}.  It is in vogue for each Tcl/Tk extension package to
build it's own ``extended WISH''.  Tcl-DP, for example builds
\code{dpwish} which users can use to evaluate scripts combining Tcl-DP
commands with standard Tcl/Tk.  There are many examples of this, and
indeed even PLplot's \code{plserver} program, described in an earlier
chapter, could just as easily have been called \code{plwish}.

In any event, as exciting and useful as these standalone, extended
windowing shells may be, they are ultimately only the beginning of
what you can do.  The real benefit of this approach is realized when
you make your own ``extended WISH'', comprised of Tcl, Tk, any of the
standard extensions you like, and finally embellished with a
smattering of application specific extensions designed to support your
own application domain.  In this section we give a detailed
introduction to the process of constructing your own WISH.  After
that, you're on your own...

\begin{menu}
* WISH construction::		How to write code for a private WISH
* WISH linking::		Turning your code into an executable
* WISH programming::		Using your new WISH
\end{menu}

\node WISH construction, WISH linking, Custom Extensions, Custom Extensions
\subsection{WISH Construction}
\cindex{making a wish}

The standard way to make your own WISH, as supported by the Tcl/Tk
system, is to take a boilerplate file, \file{tkAppInit.c}, edit to
reflect the Tcl/Tk extensions you will be requiring, add some commands
to the interpretter, and link it all together.

Here for example is the important part of the \file{tk02} demo,
extracted from the file \file{xtk02.c}, which is effectively the
extended WISH definition file for the \file{tk02} demo.  Comments and
other miscelany are omitted.
\begin{example}
#include "tk.h"
#include "itcl.h"

/* ... */

int   myplotCmd        (ClientData, Tcl_Interp *, int, char **);

int
Tcl_AppInit(interp)
    Tcl_Interp *interp;		/* Interpreter for application. */
\{
int   plFrameCmd        (ClientData, Tcl_Interp *, int, char **);

    Tk_Window main;

    main = Tk_MainWindow(interp);

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) \{
     *     return TCL_ERROR;
     * \}
     *
     * where "Mod" is the name of the module.
     */

    if (Tcl_Init(interp) == TCL_ERROR) \{
        return TCL_ERROR;
    \}
    if (Tk_Init(interp) == TCL_ERROR) \{
        return TCL_ERROR;
    \}
    if (Itcl_Init(interp) == TCL_ERROR) \{
        return TCL_ERROR;
    \}
    if (Pltk_Init(interp) == TCL_ERROR) \{
        return TCL_ERROR;
    \}

    /*
     * Call Tcl_CreateCommand for application-specific commands, if
     * they weren't already created by the init procedures called above.
     */

    Tcl_CreateCommand(interp, "myplot", myplotCmd,
                      (ClientData) main, (void (*)(ClientData)) NULL);


    /*
     * Specify a user-specific startup file to invoke if the
     * application is run interactively.  Typically the startup
     * file is "~/.apprc" where "app" is the name of the application.
     * If this line is deletedthen no user-specific startup file
     * will be run under any conditions.
     */

    tcl_RcFileName = "~/.wishrc";
    return TCL_OK;
\}

/* ... myPlotCmd, etc ... */
\end{example}

The calls to \code{Tcl_Init()} and \code{Tk_Init()} are in every WISH.
To make an extended WISH, you add calls to the initialization routines
for any extension packages you want to use, in this [incr Tcl]
(\code{Itcl_Init()}) and PLplot (\code{Pltk_Init()}).  Finally you add
keywords to the interpretter, associating them with functions in your
code using \code{Tcl_CreateCommand()} as shown.

In particular, PLplot has a number of [incr Tcl] classes in its Tcl
library.  If you want to be able to use those in your WISH, you need
to include the initialization of [incr Tcl].

\node WISH linking, WISH programming, WISH construction, Custom Extensions
\subsection{WISH Linking}

Having constructed your \code{Tcl_AppInit()} function, you now merely
need to link this file with your own private files to provide the code
for any functions you registered via \code{Tcl_CreateCommand()} (and
any they depend on), against the Tcl, Tk and extension libraries you
are using.
\begin{example}
cc -c tkAppInit.c
cc -c mycommands.c
cc -o my_wish tkAppInit.o mycommands.o 
           -lplplotftk -ltcl -ltk -litcl -lX11 -lm
\end{example}
Add any needed \code{-L} options as needed.

Voila!  You have made a wish.

\node WISH programming, , WISH linking, Custom Extensions
\subsection{WISH Programming}

Now you are ready to put the genie to work.  The basic plan here is to
write shell scripts which use your new application specific windowing
shell as their interpreter, to imlement X Windows user interfaces to
control and utilize the facilities made available in your extensions.

Effectively this just comes down to wrting Tcl/Tk code, embellished as
appropriate with calls to the extension commands you registered.
Additionally, since this wish includes the PLplot extensions, you can
instantiate any of the PLplot family of [incr Tcl] classes, and invoke
methods on those objects to effect the drawing of graphs.  Similarly,
you may have your extension commands (which are coded in C) call the
PLplot C programmers API to draw into the widget.  In this way you can
have the best of both worlds.  Use compiled C code when the
computational demands require the speed of compiled code, or use Tcl
