@c  Copyright (c) 1994 William Schelter.

@node General, Widgets, Top, Top
@chapter General

@menu
* Introduction::		
* Getting Started::		
* Common Features of Widgets::	
* Return Values::		
* Argument Lists::		
* Lisp Functions Invoked from Graphics::  
* Linked Variables::		
* tkconnect::			
@end menu

@node Introduction, Getting Started, General, General
@section Introduction

@b{GCL-TK} is a windowing interface for @b{GNU Common Lisp}.   It provides the
functionality of the @b{TK} widget set, which in turn implements a widget
set which has the look and feel of @b{Motif}.

The interface allows the user to draw graphics, get input from menus,
make regions mouse sensitive, and bind lisp commands to regions.  It
communicates over a socket with a @file{gcltksrv} process, which speaks to the
display via the @b{TK} library.  The displaying process may run on
a machine which is closer to the display, and so involves less
communication.  It also may remain active even though the lisp is
involved in a separate user computation.  The display server can, however,
interrupt the lisp at will, to inquire about variables and run
commands.   

The user may also interface with existing @code{TCL/TK} programs,
binding some buttons, or tracking some objects.

The size of the program is moderate.   In its current form it adds only
about 45K bytes to the lisp image, and the @file{gcltksrv} program uses shared
libraries, and is on the order of 150Kbytes on a sparc.

This chapter describes some of the common features of the command
structure of widgets, and of control functions.   The actual functions
for construction of windows 
are discussed in @ref{Widgets}, and more general functions
for making them appear, lowering them, querying about them in @ref{Control}.

@node Getting Started, Common Features of Widgets, Introduction, General
@section Getting Started

Once @b{GCL} has been properly installed you should be able to do the
following simple example:

@example
(in-package "TK")
(tkconnect)
(button '.hello :text "Hello World" :command '(print "hi"))
==>.HELLO
(pack '.hello)
@end example
We first switched to the "TK" package, so that functions like button
and pack would be found.  
After doing the tkconnect, a window should appear on your screen, see @xref{tkconnect}.
The invocation of the function @code{button} creates a new function
called @code{.hello} which is a @i{widget function}.   It is then
made visible in the window by using the @code{pack} function.

You may now click on the little window, and you should see the command
executed in your lisp.  Thus "hi" should be printed in the lisp
window.  This will happen whether or not you have a job running in
the lisp, that is lisp will be interrupted and your command will run,
and then return the control to your program.

The function @code{button} is called a widget constructor, and the
function @code{.hello} is called a widget.  If you have managed to
accomplish the above, then @b{GCL} is probably installed correctly, and you
can graduate to the next section!  If you dont like reading but prefer
to look at demos and code, then you should look in the demos directory,
where you will find a number of examples.  A monitor for the garbage
collector (mkgcmonitor), a demonstration of canvas widgets (mkitems),
a sample listbox with scrolling (mklistbox).   

@node Common Features of Widgets, Return Values, Getting Started, General
@section Common Features of Widgets

A @i{widget} is a lisp symbol which has a function binding.   The
first argument is always a keyword and is called the @i{option}.
The argument pattern for the remaining arguments depends on the
@i{option}.    The most common @i{option} is @code{:configure} in
which case the remaining arguments are alternating keyword/value
pairs, with the same keywords being permitted as at the creation
of the widget.

A @i{widget} is created by means of a @i{widget constructor}, of
which there are currently 15, each of them appearing as the title of a
section in @ref{Widgets}.  They live in the @code{"TK"} package, and for
the moment we will assume we have switched to this package.  Thus for
example @code{button} is such a widget constructor function.   Of course
this is lisp, and you can make your own widget constructors, but when
you do so it is a good idea to follow the standard argument patterns
that are outlined in this section.

@example
(button '.hello)
==> .HELLO
@end example
@noindent
creates a @i{widget} whose name is @code{.hello}.  There is a parent child
hierarchy among widgets which is implicit in the name used for the
widget.   This is much like the pathname structure on a Unix or Dos
file system, except that @code{'.'} is used as the separator rather
than a @code{/} or @code{\}.   For this reason the widget instances
are sometimes referred to as @i{pathnames}.   A child of the
parent widget @code{.hello} might be called @code{.hello.joe}, and
a child of this last might be @code{.hello.joe.bar}.  The parent of
everyone is called @code{.} .   Multiple top level windows are created
using the @code{toplevel} command (@pxref{toplevel}).

The widget constructor functions take keyword and  value  pairs, which
allow you to specify attributes at the time of creation:

@example
(button '.hello :text "Hello World" :width 20)
==>.HELLO
@end example
@noindent
indicating that we want the text in the button window to be
@code{Hello World} and the width of the window to be 20 characters
wide.  Other types of windows allow specification in centimeters
@code{2c}, or in inches (@code{2i}) or in millimeters @code{2m}
or in pixels @code{2}.   But text windows usually have their
dimensions specified as multiples of a character width and height.
This latter concept is called a grid.

Once the window has been created, if you want to change the
text you do NOT do:
@example
(button '.hello :text "Bye World" :width 20)
@end example
This would be in error, because the window .hello already exists.
You would either have to first call

@example
(destroy '.hello)
@end example

But usually you just want to change an attribute.  @code{.hello} is
actually a function, as we mentioned earlier, and it is this function
that you use:

@example
(.hello :configure :text "Bye World")
@end example

This would simply change the text, and not change where the window had
been placed on the screen (if it had), or how it had been packed
into the window hierarchy.   Here the argument @code{:configure} is
called an @i{option}, and it specifies which types of keywords can
follow it.   For example

@example
(.hello :flash)
@end example
@noindent
is also valid, but in this case the @code{:text} keyword is not permitted
after flash.   If it were, then it would mean something else besides
what it means in the above.  For example one might have defined

@example
(.hello :flash :text "PUSH ME")
@end example
@noindent
so here the same keyword @code{:text} would mean something else, eg
to flash a subliminal message on the screen.

We often refer to calls to the widget functions 
as messages.   One reason for this is that they actually turn into
messages to the graphics process @file{gcltksrv}.   To actually see these
messages you can do
@example
(debugging t).
@end example

@node Return Values, Argument Lists, Common Features of Widgets, General
@section Return Values

@subsection Widget Constructor Return Values

On successful completion, the widget constructor functions return the
symbol passed in as the first argument.   It will now have a functional
binding.   It is an error to pass in a symbol which already corresponds
to a widget, without first calling the @code{destroy} command.   On failure,
an error is signalled.

@subsection Widget Return Values

The @i{widget} functions themselves, do not normally return any value.
Indeed the lisp process does not wait for them to return, but merely
dispatches the commands, such as to change the text in themselves.
Sometimes however you either wish to wait, in order to synchronize, or
you wish to see if your command fails or succeeds.  You request values
by passing the keyword :return and a value indicating the type.   

@example
(.hello :configure :text "Bye World" :return 'string)
==> "" 
==> T
@end example
@noindent
the empty string is returned as first value, and the second value
@code{T} indicates that the new text value was successfully set.  LISP
will not continue until the tkclsrv process indicates back that the
function call has succeeded.  While waiting of course LISP will continue
to process other graphics events which arrive, since otherwise a
deadlock would arise: the user for instance might click on a mouse, just after
we had decided to wait for a return value from the @code{.hello} function.
More generally a user program may be running in @b{GCL} and be interrupted
to receive and act on communications from the @file{gcltksrv}
process.   If an error occurred then the second return value of the
lisp function will be NIL.  In this case the first value, the string
is usually an informative message about the type of error.

A special variable @code{tk::*break-on-errors*} which if not
@code{nil}, requests that that @b{LISP} signal an error when a message
is received indicating a function failed.  Whenever a command fails,
whether a return value was requested or not, @file{gcltksrv} returns a
message indicating failure.  The default is to not go into the
debugger.  When debugging your windows it may be convenient however to
set this variable to @code{T} to track down incorrect messages.

The @file{gcltksrv} process always returns strings as values.
If @code{:return} @i{type} is specified, then conversion to @i{type}
is accomplished by calling

@example
(coerce-result @i{return-string} @i{type})
@end example

Here @i{type} must be a symbol with a @code{coercion-functions}
property.
The builtin return types which may be requested are:

@table @code
@item T
in which case
the string passed back from the @file{gcltksrv} process, will be read by the
lisp reader.
@item number
the string is converted to a number using the current *read-base*
@item list-strings

@example
(coerce-result "a b @{c d@} e" 'list-strings)
==> ("a" "b" "c d" "e")
@end example
@item boolean
(coerce-result "1" 'boolean)
==> T
(coerce-result "0" 'boolean)
==> NIL
@end table

The above symbols are in the @code{TK} or @code{LISP} package.
It would be possible to add new types just as the @code{:return t}
is done:

@example
(setf (get 't 'coercion-functions)
      (cons #'(lambda (x) (our-read-from-string x 0))
	    #'(lambda (x) (format nil "~s" x))))
@end example

The @code{coercion-functions} property of a symbol, is a cons whose
@code{car} is the coercion form from a string to some possibly different
lisp object, and whose @code{cdr} is a function which builds a string
to send to the graphics server.   Often the two functions are inverse
functions one of the other up to equal.

@subsection Control Function Return Values

The @i{control} funcions (@pxref{Control})  do not return a value
or wait unless requested to do so, using the @code{:return} keyword.
The types and method of specification are the same as for the
Widget Functions in the previous section.

@example
(winfo :width '.hello :return 'number)
==> 120
@end example
@noindent
indicates that the @code{.hello} button is actually 120 pixels
wide.

@node Argument Lists, Lisp Functions Invoked from Graphics, Return Values, General
@section Argument Lists

@subsection Widget Functions

The rule is that the first argument for a widget function is a keyword,
called the @i{option}.  The pattern of the remaining arguments depends
completely
on the @i{option} argument.  Thus

@example
(.hello @i{option} ?arg1? ?arg2? ...)
@end example

One @i{option} which is permitted for every widget function is
@code{:configure}.  The argument pattern following it is the same
keyword/value pair list which is used in widget creation.  For a
@code{button} widget, the other valid options are @code{:deactivate},
@code{:flash}, and @code{:invoke}.   To find these, since
@code{.hello} was constructed with the @code{button} constructor, you
should see @xref{button}.  
The argument pattern for other options depends completely on the option
and the widget function.
For example if @code{.scrollbar} is a scroll bar window, then the option
@code{:set} must be followed by 4 numeric arguments, which indicate how
the scrollbar should be displayed, see @xref{scrollbar}. 

@example
(.scrollbar :set a1 a2 a3 a4)
@end example

If on the other hand @code{.scale} is a scale (@pxref{scale}), then we have

@example
(.scale :set a1 )
@end example
@noindent
only one numeric argument should be supplied, in order to position the
scale.

@subsection Widget Constructor Argument Lists

These are

@example
(widget-constructor @i{pathname} :keyword1 value1 :keyword2 value2 ...)
@end example

@noindent
to create the widget whose name is @i{pathname}.  The possible keywords
allowed are specified in the corresponding section of @xref{Widgets}.

@subsection Concatenation Using `:' in Argument List

What has been said so far about arguments is not quite true.  A
special string concatenation construction is allowed in argument lists
for widgets, widget constructors and control functions.

First we introduce the function @code{tk-conc} which takes an arbitrary
number of arguments, which may be symbols, strings or numbers, and 
concatenates these into a string.   The print names of symbols are 
converted to lower case, and package names are ignored.

@example
(tk-conc "a" 1 :b 'cd "e") ==> "a1bcde"
@end example

One could use @code{tk-conc} to construct arguments for widget
functions.  But even though @code{tk-conc} has been made quite
efficient, it still would involve the creation of a string.   The
@code{:} construct avoids this.   In a call to a widget function,
a widget constructor, or a control function you may remove the call to
@code{tk-conc} and place @code{:} in between each of its arguments.
Those functions are able to understand this and treat the extra
arguments as if they were glued together in one string, but without
the extra cost of actually forming that string.

@example
(tk-conc a b c .. w) <==> a : b : c : ... w
(setq i 10)
(.hello :configure :text i : " pies")
(.hello :configure :text (tk-conc i  " pies"))
(.hello :configure :text (format nil "~a pies" i))
@end example

The last three examples would all result in the text string being
@code{"10 pies"}, but the first method is the most efficient.
That call will be made with no string or cons creation.   The 
@b{GC Monitor} example, is written in such a way that there is no
creation of @code{cons} or @code{string} types during normal operation.
This is particularly useful in that case, since one is trying to 
monitor usage of conses by other programs, not its own usage.

@node Lisp Functions Invoked from Graphics, Linked Variables, Argument Lists, General
@section Lisp Functions Invoked from Graphics


It is possible to make certain areas of a window mouse sensitive,
or to run commands on reception of certain events such as keystrokes,
while the focus is in a certain window.   This is done by having
a lisp function invoked or some lisp form evaluated.   We shall
refer to such a lisp function or form as a @emph{command}. 

For example

@example
(button '.button :text "Hello" :command '(print "hi"))
(button '.jim :text "Call Jim" :command 'call-jim)
@end example

In the first case when the window @code{.button} is clicked on, the
word "hi" will be printed in the lisp to standard output.   In the
second case @code{call-jim} will be funcalled with no arguments.

A command must be one of the following three types.  What happens
depends on which type it is:

@table @samp
@item function
If the value satisfies @code{functionp} then it will be called with
a number of arguments which is dependent on the way it was bound,
to graphics.  
@item string
If the command is a string, then it is passed directly to @b{TCL/TK}
for evaluation on that side.  Lisp will not be required for the
evaluation when the command is invoked.
@item lisp form
Any other lisp object is regarded as a lisp form to be eval'd, and
this will be done when the command is invoked.
@end table

The following keywords accept as their value a command:

@example
   :command
   :yscroll    :yscrollcommand
   :xscroll    :xscrollcommand
   :scrollcommand
   :bind
@end example

@noindent
and in addition @code{bind} takes a command as its third argument,
see @xref{bind}.

@c todo!!
Below we give three different examples using the 3 possibilities for
a command: functionp, string, and lisp form.  They all accomplish
exactly the same thing.  
For given a frame @code{.frame} we could construct a listbox
in it as:

@example
(listbox '.frame.listbox :yscroll 'joe)
@end example

Then whenever the listbox view position changes, or text is inserted,
so that something changes, the function @code{joe} will be invoked with 4
arguments giving the totalsize of the text, maximum number of units
the window can display, the index of the top unit, and finally the
index of the bottom unit.   What these arguments are is specific
to the widget @code{listbox} and is documented @xref{listbox}.

@code{joe} might be used to do anything, but a common usage is to have
@code{joe} alter the position of some other window, such as a scroll
bar window.   Indeed if @code{.scrollbar} is a scrollbar then
the function

@example
(defun joe (a b c d)
  (.scrollbar :set a b c d))
@end example

@noindent
would look after sizing the scrollbar appropriately for the percentage
of the window visible, and positioning it.

A second method of accomplishing this identical, using a string (the
second type of command),


@example
(listbox '.frame.listbox :yscroll ".scrollbar set")
@end example

@noindent
and this will not involve a call back to lisp.   It uses the fact that
the @b{TK} graphics side understands the window name @code{.scrollbar} and
that it takes the @i{option} @code{set}.   Note that it does not get
the @code{:} before the keyword in this case.

In the case of a command which is a @i{lisp form} but is not installed
via @code{bind} or @code{:bind}, then the form will be installed as

@example
#'(lambda (&rest *arglist*) @i{lisp-form})
@end example

@noindent
where the @i{lisp-form} might wish to access the elements of the special
variable @code{*arglist*}.   Most often this list will be empty, but for
example if the command was setup for @code{.scale} which is a @i{scale},
then the command will be supplied one argument which is the new numeric
value which is the scale position.  A third way of accomplishing the
scrollbar setting using a lisp form is:

@example
(listbox '.frame.listbox :yscroll '(apply '.scrollbar :set *arglist*))
@end example

The @code{bind} command and @code{:bind} keyword, have an additional
wrinkle, see @xref{bind}.   These are associated to an event in a
particular window, and the lisp function or form to be evaled must have
access to that information.   For example the x y position, the window
name, the key pressed, etc.   This is done via @i{percent symbols} which
are specified, see @xref{bind}.

@example
(bind "Entry" "<Control-KeyPress>" '(emacs-move  %W %A ))
@end example

@noindent
will cause the function emacs-move to be be invoked whenever a control
key is pressed (unless there are more key specific or window specific
bindings of said key).   It will be invoked with two arguments, the
first %W indicating the window in which it was invoked, and the second
being a string which is the ascii keysym which was pressed at the same
time as the control key.

These @i{percent constructs} are only permitted in commands which are
invoked via @code{bind} or @code{:bind}.  The lisp form which is passed
as the command, is searched for the percent constructs, and then a
function

@example
#'(lambda (%W %A) (emacs-move %W %A))
@end example

@noindent
will be invoked with two arguments, which will be supplied by the
@b{TK} graphics server, at the time the command is invoked.   The
@code{*arglist*} construct is not available for these commands.

@node Linked Variables, tkconnect, Lisp Functions Invoked from Graphics, General
@section Linked Variables

It is possible to link lisp variables to @b{TK} variables.  In general
when the @b{TK} variable is changed, by for instance clicking on a
radiobutton, the linked lisp variable will be changed.  Conversely
changing the lisp variable will be noticed by the @b{TK} graphics side, if
one does the assignment in lisp using @code{setk} instead of
@code{setq}.

@example
(button '.hello :textvariable '*message* :text "hi there")
(pack '.hello)
@end example

This causes linking of the global variable @code{*message*} in lisp
to a corresponding variable in @b{TK}.  Moreover the message that is in
the button @code{.hello} will be whatever the value of this global
variable is (so long as the @b{TK} side is notified of the change!).

Thus if one does

@example
(setk *message* "good bye")
@end example

@noindent
then the button will change to have @i{good bye} as its text.
The lisp macro @code{setk} expands into

@example
(prog1 (setf *message* "good bye") (notice-text-variables))
@end example

@noindent
which does the assignment, and then goes thru the linked variables
checking for those that have changed, and updating the @b{TK} side should
there be any.   Thus if you have a more complex program which might
have done the assignment of your global variable, you may include
the call to @code{notice-text-variables} at the end, to assure that
the graphics side knows about the changes.

A variable which is linked using the keyword @code{:textvariable} is
always a variable containing a string.

However it is possible to have other types of variables.

@example
(checkbutton '.checkbutton1 :text "A button" :variable '(boolean *joe*))
(checkbutton '.checkbutton2 :text "A button" :variable '*joe*)
(checkbutton '.checkbutton3 :text "Debugging" :variable '(t *debug*)
              :onvalue 100 :offvalue -1)
@end example

The first two examples are the same in that the default variable type
for a checkbutton is @code{boolean}.  Notice that the specification of a
variable type is by @code{(@i{type} variable)}.  The types which are
permissible are those which have coercion-fucntions, @xref{Return
Values}.  In the first example a variable @code{*joe*} will be linked, and
its default initial value will be set to nil, since the default initial
state of the check button is off, and the default off value is nil.
Actually on the @b{TK} side, the corresponding boolean values are @code{"1"}
and @code{"0"}, but the @code{boolean} type makes these become @code{t}
and @code{nil}.

In the third example the variable *debug* may have any lisp value (here
@i{type} is @code{t}).   The initial value will be made to be @code{-1},
since the checkbutton is off.   Clicking on @code{.checkbutton3} will
result in the value of @code{*debug*} being changed to 100, and the light
in the button will be toggled to on, @xref{checkbutton}.  You may
set the variable to be another value besides 100.

You may also call

@example
(link-text-variable '*joe* 'boolean)
@end example

@noindent
to cause the linking of a variable named *joe*.  This is done
automatically
whenever the variable is specified after one of the keys

@example
:variable   :textvariable.
@end example

Just as one must be cautious about using global variables in lisp, one
must be cautious in making such linked variables.  In particular note
that the @b{TK} side, uses variables for various purposes.  If you make a
checkbutton with pathname @code{.a.b.c} then unless you specify a
@code{:variable} option, the variable @code{c} will become associated to
the @b{TK} value of the checkbutton.  We do NOT link this variable by
default, feeling that one might inadvertently alter global variables,
and that they would not typically use the lisp convention of being of
the form @code{*c*}.  You must specify the @code{:variable} option, or
call @code{link-variable}.


@node tkconnect,  , Linked Variables, General
@section tkconnect

@example
@i{tkconnect} &key host display can-rsh gcltksrv
@end example

This function provides a connection to a graphics server process, which
in turn connects to possibly several graphics display screens.   The
graphics server process, called @file{gcltksrv} may or may not run
on the same machine as the lisp to which it is attached.
@code{display}
indicates the name of the default display to connect to, and this
in turn defaults to the value of the environment variable @code{DISPLAY}.

When @i{tkconnect} is invoked, a socket is opened and it waits for 
a graphics process to connect to it.  If the host argument is not
supplied, then a process will be spawned which will connect back to
the lisp process.   The name of the command for invoking the process
is the value of the @file{gcltksrv} argument, which defaults to
the value of the environment variable @code{GCL_TK_SERVER}.   If that variable
is not set, then the lisp @code{*lib-directory*} is searched for
an entry @file{gcl-tk/gcltksrv}.

If @code{host} is supplied, then a command to run on the remote machine
will be printed on standard output.   If @code{can-rsh} is not nil,
then the command will not be printed, but rather an attempt will be
made to rsh to the machine, and to run the command.

Thus

@example
(tkconnect)
@end example

@noindent
would start the process on the local machine, and use for @code{display}
the value of the environment variable @code{DISPLAY}.

@example
(tkconnect :host "max.ma.utexas.edu" :can-rsh t)
@end example

@noindent
would cause an attempt to rsh to @code{max} and to run the command
there, to connect back to the appropriate port on the localhost.

You may indicate that different @i{toplevel} windows be on different
displays, by using the @code{:display} argument when creating the
window, @xref{toplevel}.

Clearly you must have a copy of the program @file{gcltksrv} and @b{TK}
libraries installed on the machine where you wish to run the server.
