
Disclaimer

This user manual is shockingly short.
The whole system should currently only be attempted by someone who is brave,
knows either Motif or Tk, or preferably knows both.

Introduction

This is a binding of the Tcl language to the Motif widgets.
Tcl is an interpreted language originally intended for use as a command
language for other applications. It has been used for that, but has also
become useful as a language in its own right.

Tcl has been extended by a set of widgets called Tk. The Tk widgets are not
based on the Xt Intrinsics, but are built above Xlib. They allow an easy
way of writing X Window applications.

The standard set of widgets in the X world is now the Motif set. This forms
a large set of widgets, and these have been through a large amount of
development over the last five years. Use of this set is sometimes a
requirement by busineses, and other widget sets try to conform to them in
appearance and behaviour.

This system allows the programmer to use the Motif widgets instead of the
Tk widgets from Tcl programs. This increases programmer choices, and allows
comparison of the features of both Tcl and the Tk/Motif style of widget
programming.  The binding gives the full set of Motif widgets, accessible
through the simple interpreted Tcl language.

Acknowledgments

This system is based on Tk for the style of widget programming. This was
because it provides a good model, but it also allows the Tcl programmer to
move relatively easily between Tk and Motif programming. An alternative
style of binding to Motif is used in the WKSH system, which performs a
similar sort of role for the Korn Shell. An intermediate style is provided
by the Wafe binding of Xt-based widgets to tcl.

The documentation is incomplete (and is likely to be for a very
long time). Consequently the programmer will probably need to refer to the
Motif Programers Reference Manual. The system has been designed so that
it is relatively easy to translate the C-based information in this manual
into the corresponding Tcl information. This has been aided by the
consistency with which Motif has been implemented in certain areas.

Running Tcl/Motif programs

Tcl/Motif programs may be run by the `moat' (MOtif And Tcl) interpreter.
When called with no arguments it reads Tcl commands from standard input.
When called by

moat -file file-name

or

moat -f file-name

it reads Tcl commands from `file-name', executes them and then enters the
Tm event loop.  This is similar to the Tk `wish' and the concept was
borrowed from there.

Depending on your shell interpreter, you will probably be able to run 
Tcl/Motif programs as standalone programs. If your moat interpreter is
installed in say `/usr/local/bin/moat', make this the first line of your
executable program:

#!/usr/local/bin/moat -file

Widget naming

Widgets are visual objects that exist on the screen.
They are organised as a hierarchy, with the application itself forming the
root of this hierarchy.
The naming of objects within this hierarchy is similar to the ``absolute
path names'' of Unix files with a `.' replacing the `/' of Unix.
The application itself is known as `.'.
A Form in the application may be known as `.form1'.
A Label in this form may be `.form1.okLabel', and so on.
Note that Xt requires that `.' can only have one child
(except for dialogs).
This naming convention is the same as in Tk.

Widget creation

Widgets belong to classes, such as Label, PushButton or List.
For each class there is a creation command which takes the pathName of the
object as first argument with optional further arguments:

form .form1

label .form1.okLabel

label .form1.cancelLabel -labelString "Get rid of me"

creates a Form `form1' as child of `.', and two Labels `okLabel' and
`cancelLabel' as children of `form1'. The `cancelLabel' has additional
arguments that set the labelString to "Get rid of me".

The set of classes generally mirrors the Motif set.
Some widgets in Motif and Xt are not accessible from this binding because
they are intended for use in inheritance only, such as Core and Primitive.
The types of widgets that can be created using this include the primitive
widgets:

arrowButton - a simple arrow, 
drawnButton - a button with graphics in it
cascadeButton - for use in menus
toggleButton - for on/off boxes
label - a fixed piece of text
text - a text editor
textField - a one line text editor
separator - for simple lines between objects
list - a list selector
scrollBar - a horizontal or vertical scrolling bar

and the Manager widgets:

bulletinBoard - simple geometry management
rowColumn - regular geometry management
panedWindow - multiple panes separated by sashes
frame - a 3-D border
scale - a slider on a scale
scrolledWindow - for displaying a clip view over an area
mainWindow - contains a menu bar and the main application windows
form - for irregular geometry arrangements
messageBox - message display area
command - a command entry area with a history list
fileSelectionBox - selection of a file from a list

Motif has two special commands for creating a ScrolledList and a ScrolledText.
These commands actually create a pair of widgets: a List or Text inside a
 ScrolledWindow. To create such widgets is similar to the C binding: the
List (or Text) widget name is given. If the parent ScrolledWindow is required
then you have to call the ``parent'' method on the List or Text widget.

form .form1

scrolledList .form1.list2

[.form1.list2 parent] setValues -attachTop attach_form

Motif also has convenience functions that create dialogs.
These don't create ordinary widgets, but Motif pretends that they do.
Tm follows this, and allows you to use commands such as

questionDialog .askMe

to create such dialogs. When you have to destroy such widgets, destroy the
parent:

[.askMe parent] destroy

This set of dialogs includes:

bulletinBoardDialog - a dialog with arbitrary contents, based on bulletinBoard
fileSelectionDialog - a dialog based on fileSelectionBox
formDialog - a dialog based on form
informationDialog - a dialog displaying information
messageDialog - a dialog showing a message
promptDialog - a dialog with a prompt area
questionDialog - a dialog asking a question
selectionBoxDialog - a dialog based on selectionBox
warningDialog - a dialog showing a warning message
workingDialog - a dialog showing a busy working message

For example, consider a rowColumn containing two labels and a pushButton,
where the rowColumn is inside a mainWindow:

mainWindow .main
rowColumn .main.rowcol
label .main.rowcol.label1
label .main.rowcol.label2
pushButton .main.rowcol.btn

Not all objects used in the OSF C library are supported: gadgets are 
not supported by Tm, nor are the ``simple'' menu functions.
The drag and drop mechanism has not been implemented yet.

Managing widgets

Before a widget cn be displayed, it must be brought under the geometry
control of its parent (similar to placing a Tk widget). This can be done
by the ``manageChild'' method of each widget, but also by an optional 
third command to each widget creation function, similar to the
XtCreateManagedWidget functions. For example,

label .l1 managed
label .l2
.l2 manageChild

Documentation
 
The widgets described above not only look and act the same as the Motif
widgets, they *are* the Motif widgets. So descriptions of them in any Motif
book or reference apply. In the Motif Programmers Reference these widgets
are described under the same names, prefixed by ``Xm'' as in XmPushButton.
The creation functions are prefixed by ``XmCreate'' as in
XmCreatePushButton.

The Tm documentation is at present incomplete. There should be a man page
for each widget, under the name of the widget prefixed by ``Tm'' as in
TmPushButton.

Widget commands

Creating a widget actually creates a Tcl command known by its pathName.
This command may be executed with at least one parameter 
to either change the behavior of the object
or the value of its components, or to get information about the object.
The parameter acts like a ``method'' to the object, and specifies an action
that it should perform. The parameters that are recognised by every object
include:

unmanageChild - remove the object from its parents geometry management, which
makes it disappear from the display

manageChild - make it appear again

getValues - obtain properties of the widget

setValues - set properties of the widget

parent - return the parent of the widget

destroy - destroy the widget and all its children

setSensitive - change the sensitivity of the widget to responses to input

any string ending in ``Callback'' - register Tcl code to be executed when
something happens to the widget.

For example,

.form1.okLabel unmanageChild

.form1.okButton activateCallback {puts stdout "I was pushed into it..."}

Unmanaging a widget removes it from the display, and from the geometry
management of its parent. Managing it reverses this. The other methods
are explained later.

Widget resources

Each widget has a set of resources that can be set at creation time,
set at a later time, or queried for their value. For example, a pushButton
has a width and a height, a labelString that is the text that will show in
it, a foreground and background colour, a fontList giving the set of fonts
that will be used to draw the text, and so on.

All resource names are prefixed by a minus `-' in Tcl programs, for 
consistency with the Tk widgets. 
On setting a value, all resources take the next
word as value, and on getting a value the next word is the name of a variable
to  store the value in.

On creation, the resource/value pairs come after the widget pathName, as in

.okLabel -labelType pixmap -labelPixmap xlogo32

which sets the labelType to pixmap and the labelPixmap to xlogo32.

Resources can be set at any time using the setValues method

.text setValues -editMode editable -value "Some text"

which ensures that the text widget can be edited, and sets a
value of "Some text".

Resources can be obtained from the widget using the getValues method.
For example

.fileSelectionBox getValues -dirSpec file_selected -directory dir

stores in the Tcl variable file_selected the filename that was entered, and
in the Tcl variable dir the directory in which the file selection occurred.

Each widget inherits resources from superclasses. For example, Label is a
subclass of Primitive which in turn is a subclass of Core.  From Core it
inherits resources such as background, height and width.  From Primitive it
inherits resources such as foreground.  It is neccessary to look at these
superclasses.  In addition, each class adds extra resources.  For example,
Label has the additional resources labelType, labelPixmap and labelString,
among others.

Resources are documented in the Tm man page for each widget. This
documentation is weak.

Resource names can be obtained from the Motif documentation for each
widget. The Motif documentation for each widget has a set of tables
headed ``Resource Set''.  In the table of resources, the names of these
 are given prefixed by ``XmN'', such as XmNeditMode.  Drop the prefix
to get the Tcl resource name. Case is important here.

Resource values can also be obtained from the Motif documentation.  For
each resource look at its type.  Types such as Dimension and Position are
numeric types, and along with int types need an integer value.  In the Tcl
program they are implemented as Tcl Strings, as is everything.  In fact,
all resource values are Tcl strings.  Pixmaps, for example, are the string
name of a pixmap such as ``xlogo32''.  Pixel is a color such as ``blue'',
or a hexadecimal representation of the color.  Types such as the
arrowDirection of an ArrowButton form a discrete set with values listed as
XmARROW_UP, XmARROW_DOWN, etc.  For these types, drop the ``Xm'' and use
the rest of the string as the value.  On setting values, case is not
important but on getting values the string will be lower case for these
discrete types.

So for example, a pushButton may have

pushButton .btn -width 100
.btn setValues -labelString "Push Me" -foreground red
.btn getValues -background bg
puts stdout "background colour is $bg"

Callbacks

When the user does things to a widget, it may cause the widget to take certain
actions.  For example, when a button is pressed it changes appearance to
look pressed in. Some of these actions can have Tcl code attached to them,
so that the Tcl code is evaluated when the action is performed. The Tcl
code is attached to a ``callback'' by a widget command.  For example, a
pushButton has an activateCallback that is called when the user presses and
releases the left mouse button inside the widget; it has an armCallback
that is called when the user presses the mouse button; it has a
disarmCallback that is called when the user releases the mouse button
inside the widget.

Tcl code is attached to a callback by giving it as the second argument to the
appropriate widget methodod. For example,

.btn armCallback {puts stdout "Stop squashing me!!!"}
.btn disarmCallback {puts stdout "That's better!"}

The names of the callbacks available for a particular widget are derived
from the resource documentation for the Motif widget.  Each callback ends
with the string "Callback" in its name.  Drop the "XmN" from the Motif
description to gain the widget command.  Callbacks are treated differently
to other resources because the Xt toolkit treats them differently - the
resource is not meant to be handled directly by any ordinary application.

Callback substitutions

Motif supplies information to each callback function that is specific to
the widget type.  Generally this is not of much interest. However, for some
widgets such as List this is used to supply important information, such as
what item in the List was selected! To make this available to the Tcl
callback function a pattern substitution mechanism may be used.  Any ``%''
followed by a word will be treated as a pattern for potential substitution.
For example, ``%item'' in a List will be replaced by the item selected,and
``%item_position'' will be replaced by its position in the list.
An example list callback is

.list singleSelectionCallback {print_info %item %item_position}

proc print_info {item position} {

    puts stdout "item was $item, at position $position"

}

The substitutions allowed may be found from the Motif documentation.  In
the description of callback information one or more structures will be
defined. The field names in these structures are the names used in ``%''
substitutions. Not all of the possibilities are implemented yet.  
This is admittedly obscure and not easy to find, so the Tm
documentation needs to fix this lack. If you feel upto reading C code
instead, the upto date ``list'' is found in the file ``tmExpand.c''

Text verify callbacks

The Text widget allows special processing by the application of text entered.
After a character has been typed, or text pasted in, initial processing by
the Text widget determines what the user is entering. This text is then
passed to special callback functions. These functions can make copies of
the text, can alter it, or can set a flag to say do not display it. Simple
uses for this are a password entry widget that reads the text but does not
display it (or echoes `*' instead), or text formatting widgets.

The callback mechanism for this is basically the same as for  other
callbacks, and similar sorts of substitutions are allowed. For example, the
term %currInsert is replaced by the current insertion position. Other
substitutions do not give a value, but rather give the name of a tcl
variable. This allows the application to change the value as required. The tcl
variable is in the context of the callback caller, so upvar should be used. For
example, to turn off echoing of characters, the following should be done:

.text modifyVerifyCallback {no_echo %doit}

proc no_echo {doit} {
  upvar 1 $doit do_insert

  set do_insert false
}

(Actually, the tcl variable here is the global variable _Tm_Text_Doit. For
this reason, variables beginning with _Tm_ are reserved for use by the Tm 
library.)

Dialogs

Selection Box has a number of component children, which may be managed or unmanaged
by the application. If the SelectionBox was named .sel, these are

	.sel.Items
	.sel.ItemsList
	.sel.Selection
	.sel.Text
	.sel.Separator
	.sel.Apply
	.sel.Cancel
	.sel.Help
	.sel.OK

Examples

A number of examples are in the programs directory. Those with `DH' in
them duplicate the examples in Dan Heller's ``Motif Programming Manual'',
O'Reilly & Associates Inc. Those that are just numbered are undocumented
test programs. They may not behave in a nice way, but that doesn't matter
too much.

The following example is in the programs directory as progEG.
The typical structure of a Motif program is that the top-level object is a
mainWindow. This holds a menu bar, and a container object such as a form or
a rowColumn which in turn holds the rest of the application objects. So a
mainWindow with a list and some buttons in a form would be created by

mainWindow .main
form .main.form
list .main.form.list
pushButton .main.form.btn1
pushButton .main.form.btn2

The form acts as what is called the ``workWindow'' of the mainWindow. This
resource would be set by

.main setValues -workWindow .main.form

Values would also be set into the list and buttons:

.main.form.list setValues \
	-itemCount 3 \
	-items "one, two, three" \
	-selectionPolicy single_select
.main.form.btn1 setValues -labelString Quit
.main.form.btn2 setValues -labelString "Do nothing"

Behaviour would be set by a callback function

.main.form.btn1 activateCallback {exit 0}
.main.form.list singleSelectionCallback {puts stdout "Selected %item"}

Geometry would be set for the form, to put the objects in their correct
relation to each other. Suppose this is the list on the left, with the two
buttons one under the other on the right:

.main.form.list setValues \
	-topAttachment attach_form \
	-leftAttachment attach_form \
	-bottomAttachment attach_form
.main.form.btn1 setValues \
	-topAttachment attach_form \
	-leftAttachment attach_widget \
	-leftWidget .main.form.list
.main.form.btn2 setValues \
	-topAttachment attach_widget \
	-topWidget .main.form.btn1 \
	-leftAttachment attach_widget \
	-leftWidget .main.form.list \

