# IRAF Object Manager Tutorial

## Contents

- 1. Introduction
- 2. System Architecture
- 3. The Client Process
  - 3.1 IRAF Graphics Task
    - 3.1.1 XGterm
  - 3.2 Standalone Task
  - 3.3 OBM Shell
  - 3.4 Named External Clients
- 4. UI Definition File
  - 4.1 Example Interface
- 5. Widget Toolkit
- 6. Object Classes
  - 6.1 Client
    - 6.1.1 Command Summary
  - 6.2 Server
    - 6.2.1 Command Summary
  - 6.3 Gterm
    - 6.3.1 Command Summary
  - 6.4 HTML
    - 6.4.1 Command Summary
  - 6.5 Markers
    - 6.5.1 Command Summary
  - 6.6 Widget
    - 6.6.1 Command Summary
  - 6.7 Parameter
    - 6.7.1 Command Summary

### 1. Introduction

An Object Manager (OBM) user interface (UI) consists of one or more windows containing an arbitrary hierarchy of widgets. These widgets and their runtime actions are defined by an interpreted text program uploaded by the client application, which does not itself deal directly with the window user interface. This interpreted program is currently written as a Tcl script.

The OBM provides a high level abstraction for dealing with widgets and other UI objects. The main function of the object manager is to deliver messages to UI objects. Each instance of a widget is an object in the interface. The UI contains other types of objects as well, including the client object (client application), the server object (the object manager itself), and the application specific UI parameters, each of which is an object with a callback list of procedures to be called when the parameter value changes. All of these UI objects can receive messages and take actions as a result. Messages may come from the client application, or as a result of actions executed by the interpreted UI code in response to graphics events.

### 2. System Architecture

For a complete description of the OBM system architecture see Tody, D, ADASS Proceedings 1994. A postscript version of this paper is also vailable.

### 3. The Client Process

The primary advantage of the OBM architecture over traditional GUI design is the separation of the user interface from the executable client code, meaning that either can be completely rewritten or developed separately without affecting the other so long as the messaging between the two remains the same. The client itself is responsible for initializing the OBM toolkit and uploading the UI definition file, after that it usually enters an event loop of some kind (e.g. an iraf graphics cursor loop, or X event handler) to process actions defined in the client callbacks.

It's important that the client program maintain the state of the application rather than the UI file. For example, a text widget in the interface may instruct the client to load a file, however if this cannot be done the interface should not have independently reset labels or whatever assuming the action was done at all. Instead, the client program uses the Parameter Class objects in the interface to update the state of the GUI as a result of some action (whose origins may not have been in the GUI at all). So for example a sequence of events could be something like

- User selects a widget in the interface, it's callback sends a message to the client directing some action be taken
- Client receives the message and performs an action in the client
- If action fails, (optionally) notify GUI of failure (e.g. send a message to an 'alert' parameter to popup a dialog box, beep the terminal, etc)
- If action succeeds, notify GUI of new state (e.g. send a message to the 'filename' Parameter object containing the new file name).
- Callback on the 'filename' parameter then updates the status bar widget with the name of the new active file.

The messaging between the client and UI depend on the details of how the client is implemented. In general any callback procedure in the UI can send a message to any other object in the interface, but the client should generally communicate only via the Parameter objects to avoid side effects and maintain a clear separation between the UI and the client code.

### 3.1 IRAF Graphics Task

### 3.1.1 XGterm

### 3.2 Standalone Task

### 3.3 OBM Shell

The obmsh is a unix shell interpreter for GUI scripts. It is a minimal standalone client with a single callback to exit the application, otherwise it's only job is to activate the GUI file. Any messages sent to the client (except a 'quit') are simply absorbed by the client

Despite the apparent lack of functionality this is sometimes all that is required for an interface that can operate independently. Remember that the Tcl scripting language has it's own facilities for file I/O, process execution, etc, all of which are still available in the GUI. In the case of IRAF tasks it's an interface violation to use these facilities directly, however they still allow for the easy creation of a GUI which requires no real underlying client (e.g. a tcl debug shell, a calculator application, task launcher, etc).

### 3.4 Named External Clients

### 4. UI Definition File

A UI definition consists of a sequence of commands to be executed by the server object using Tcl is used as an embedded interpreter within the OBM. The Tcl script contains several required OBM-specific functions (in addition to the user-defined callbacks) which is uploaded by the client as a message for the server object.

        reset-server
        appInitialize  appName appClass Resources
        createObjects  [name]
        activate

All UI files must begin with a reset-server command to initialize the OBM. An appInitialize call is then made to define all of the widgets and resources used in the interface, initializing the interface used by the application. The createObjects function then actually creates the widgets in the server, more specifically it creates the widgets defined by the named objects resource. Lastly, the activate call is used to activate the interface, i.e. put it on the screen.

### 4.1 Example

A complete "hello, world" GUI definition might look something like:

         1)    reset-server
         2)    appInitialize hello Hello {
         3)        *objects:\
         4)            toplevel     Form       helloForm\
         5)            helloForm    Label      helloLabel\
         6)            helloForm    Command    quitButton
         7)
         8)        *background:               	gray
         9)        *helloLabel.label:         	Hello, world!
        10)        *quitButton.fromHoriz:     	helloLabel
        11)        *quitButton.label:         	Quit
        12)    }
        13)
        14)    createObjects
        15)    activate
        16)
        17)    proc Quit args {
        18)	     send client gkey q
        19)      deactivate unmap
        20)    } ; send quitButton addCallback Quit

where a line-by-line analysis of the GUI shows:

Line 1:
  - The reset-server command must be the first line in the UI file since it's primary purpose is to initialize the OBM (i.e. a call to the ObmInitialize() procedure). Subsequent calls (in the same UI file or a different UI) are effectively a no-op.
Lines 2-12:
  - The appInitialize command defines the widgets and resources to be used in the interface. The first argument gives the name of the application, the second argument is the application class name for purposes of specifying resources in the environment, and the last argument is a Tcl list (hence the braces) of resources for the application.

  The primary purpose of the call is to initialize the X11 part of the system by defining the application context and the list of fallback resources. The objects resource is a required element listing the widget hierarchy to be used. Remaining resources are used to specify labels, colors, layout, etc and serve as an app-defaults file for the GUI, interacting with the normal resource database in the usual way. For example, a user's .Xdefaults file may specify a "font" resource, unless this is overridden in some way in the UI file this is the font that will be used. Resources may be specified with either "loose" (i.e. the '*') or "tight" (i.e. the '.') bindings with as much detail as is needed.

Line 14:
  - The createObjects command is what actually calls each widget's Initialize() method to create the widget in the application and in the X11 server.

  With no argument, the default value used is simply the objects resource. However, it's possible to specify a named argument and make repeated calls to createObjects to build any number widget trees prior to activating the interface. This can be useful for example to specify a "main_objects" resource contains all the widgets for the main panel, and a "help_objects" specfiying widgets used for the UI help panel, which makes the definition file easier to organize. In the past however UI files were written with a single long list (easily many hundreds of lines) of objects followed by an even longer list of their resources under a single appInitialize call, creating a monolithic and unmanageably GUI definition file. Later on we'll see how complex GUIs can be divided into separate pieces making it easier to reuse code and manage the interface more efficiently.

Line 15:
  - The activate command is what creates the interface on the screen, i.e. it calls the Realize() method for each widget to instantiate it in the server and draw the window.
Lines 17-19:
  - Lastly we have the user-defined callback procedures. On line 17 we define a procedure Quit which we use to shut down the interface and client application. The body of the procedure first sends the client object the graphics keystroke 'q' to shut down the client, then calls the deactivate command to close the interface. On the last line we send a message to the quitButton widget telling it to add this procedure to it's callback list, so when the Button is selected this procedure will be called as a result.

### 5. Widget Toolkit

### 5. Object Classes

The following OBM object classes are currently defined:

        Client		The Client application
        Server		The OBM itself
        Gterm		Gterm graphics/imaging widget class
        HTML		HTML widget class
        Markers		Gterm markers class
        Widget		General widget class
        Parameter		UI Parameter class

        Various Xt and Athena widgets
        		{box, shell, label, command, text, list, etc.}
        Misc Other X11 Widgets
        		{Layout, Tabs, ListTree, etc}

OBM client applications will upload a UI during initialization to define a custom graphics user interface. This is done by sending a message to the object manager. Non-GUI applications assume a simple graphics terminal and do not upload a UI; instead, a default UI is created for the application consisting of a single top level shell containing a Gterm (Tek 4012 graphics/imaging) widget.

### 5.1 Client

The client is the client application, which provides the functionality underlying the UI. When a message is sent to the client object it usually results in a message being sent to the client *application*, usually an external program communicating via IPC, which has little or no knowledge of the UI. The client application receives and executes commands delivered by the UI via the client object. Output from the client may or may not come back to the object manager. That portion of the output which comes back to the object manager is in the form of assignments of string values to UI Parameter class objects (another way of thinking of this is that messages or events are sent to and acted upon by the parameter objects). Hence, the client object is output only so far as the client application is concerned.

The Client-class commands are used to send a message to the client.

                    gkey <key>
                    gcmd <command-string>
                 literal <command>

or just <command>, e.g., "send client <command>" will work in most cases.

GKEY sends an IRAF graphics keystroke. GCMD sends an IRAF graphics colon command. LITERAL sends a literal command string to the client. The keyword "literal" may optionally be omitted, i.e., "send client foo" and "send client literal foo" are the same. The keyword "literal" may be used to ensure that the client command string which follows will not be interpreted as a Client-class command (such as gkey, gcmd, or literal).

## 5.1.1 Command Summary

### gcmd

Send a graphics command string to the client application. A graphics command string is a graphics cursor value with the key set to `:' and the command string given as the string part of the cursor value. The protocol module which posted the client output procedure is responsible for encoding and sending the cursor command.

Usage:

            gcmd <command-string>

### gkey

Send a graphics key event to the client application. A graphics key event is a graphics cursor value with the key set to some integer value and a null string part.

Usage:

    gkey <key>

### literal

Send a literal command to the client application.

Usage:

            literal <command>

### 6.2 Server

The server, or object manager, is the control center of the user interface. The server object provides a Tcl interpreter calling custom object manager commands. These are used to define and initialize the user interface, and execute UI action procedures at runtime.

              reset-server
             appInitialize  appname,appclass,resources
             createObjects  [resource-name]
             destroyObject  object
                  activate
                deactivate  [unmap]

       value = getResource  resource-name [default-value [class]]
              getResources  resource-list

                createMenu  menu-name parent item-list
                  editMenu  menu-name parent item-list
               destroyMenu  menu-name

              createBitmap  name width height data
              createCursor  name source mask fg_color bg_color x_hot y_hot
              createPixmap  name width height depth fg_color bg_color data

                     print  arg [arg ...] # debug messages
                      send  object message

      postActivateCallback  procedure
    id = postTimedCallback  procedure msec [client-data]
       deleteTimedCallback  id
     id = postWorkCallback  procedure [client-data]
        deleteWorkCallback  id

## 6.2.1 Command Summary

### serverReset

The "reset-server" command is implemented as a special case in ServerEvaluate. After doing a true reset ServerEvaluate calls Tcl_Eval to evaluate the full message which still contains the reset-server command. We want to ignore this the second time, so we treat the command here as a no-op.

Usage:

            reset-server

Note: for reset-server to be recognized by ServerEvaluate and really reset things, it must be the first command in a message to the server.

### createObjects

TCL command to create the tree of UI objects comprising the user interface. The object tree is defined by a string valued resource. If no resource is named the default "objects" resource will be used.

Usage:

            createObjects [resource-name]

### destroyObject

Destroy an object and all of its children.

Usage:

            destroyObject object-name

### activate

Activate the user interface. When called the first time the user interface is created and activated, thereafter the UI is merely reactivated (e.g. mapped if unmapped).

Usage:

            activate

### deactivate

Deactivate the user interface. Optionally unmaps the UI and calls the Obm client back to let it know that the UI has been deactivated.

Usage:

            deactivate [unmap]

### getResource

Get the string value of the specified application resource (window system parameter). This allows use of the resource mechanism to supply default values for GUI parameters.

Usage:

            value = getResource resource-name [class [default-value]]

In the simplest case one merely requests a resource by name and the string value is returned as the function value. If the resource has an entry in the fallback resources for the application (appInitialize resource list) then a value is guaranteed to be returned.

If the Class name for the resource is given then a class default value will be returned if no entry is found for the name resource instance. This is useful when there are a number of resources of the same type (same class). If most or all resources in the same class have the same default value one need only make one entry for the Class in the application defaults resource list. It is up to the application developer to define the class name of a resource - the class name can be any string. Examples are "Font", "Cursor", etc. By convention the first character of a class name is capitalized, while instance names begin with a lower case letter.

If there is an entry for the named resource in the resource list passed to appInitialize then a value string is guaranteed to be returned. This will be either the appInitialize default, or a value specified by the system or the user in an X resources file. If one is not certain a default value is defined somewhere, a default value should be specified in the getResource call as shown above.

See also getResources, used to get multiple resources in one call.

### getResources

Get the string values of a list of resources.

Usage:

            getResources resource-list

e.g.

            getResources {
                { resource [variable class [default-value]]] }
                { resource [variable class [default-value]]] }
                (etc.)
            }

### createMenu, editMenu

Create or modify a menu. The editMenu function is an alias for createMenu.

Usage:

            createMenu menu-name parent item-list

e.g.,

            createMenu menu-name parent {
                { label function data [options...] }
                { label function data [options...] }
                (etc.)
            }

where

            menu-name is the object name for the menu popup shell
            parent    is the parent widget of the menu shell
            label     is a menu item label
            function  is the function to be performed when the menu
            item      is selected, e.g., f.exec, f.data, f.space, or f.line.
            data      is function dependent data
            options   are option-name option-value pairs, as specified
                      below.

In the item list the fields label and option-value may be any Tcl expression. Expressions are evaluated in the server context. The data field is a Tcl script to be executed when the menu item is selected.

Options are specified as "option option-value". The menu item options are as follows.

            bitmap       A bitmap to be displayed left justified in the label field
                         (e.g. to indicate a parameter setting).
            sensitive    Specifies whether the menu item is active (sensitive=true)
                         or inactive (sensitive=false, item grayed out).
            accelerator  Specifies an input translation (accelerator, e.g.,
                         keyboard event) which can be used to execute the
                         menu item.

The option-value field may be any Tcl expression.

Example:

            createMenu fileMenu toplevel {
                { "File Menu" f.title}
                { Open f.exec openFile}
                { Save f.exec saveFile}
                { Load f.menu loadMenu}
                { no-label f.line }
                { Quit f.exec "send client Quit" }
            }

The first createMenu is called for a given menu the menu is created, added to the menu list, and all window system widgets are created for the menu. Subsequent calls will result in only the changed parts of the menu being altered provided the changes are not great. Hence this routine can be called to efficiently modify a menu when minor runtime changes occur, e.g., an item label or action changes, the item value changes state, and so on, without need for the GUI code to know how to make the necessary detailed changes to the widgets used to implement the menu.

### destroyMenu

Destroy a menu. This can be used to free up the resources used by a menu, e.g., if the menu is not expected to be needed again for a while.

Usage:

            destroyMenu menu-name

### createBitmap

Create a named bitmap. This replaces any old bitmap of the same name. The new bitmap is cached in server memory; when a widget bitmap resource is set, the bitmap cache will be searched for the named bitmap before asking Xlib to find the bitmap.

Usage:

            createBitmap name width height data

e.g.,

###

###

###

###

###

###

###

###

###

###

##

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

##

###

##

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

###

##

##

##

##

##

##

            createBitmap foo 16 16 {
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,
                0x60,0x03,0x20,0x02,0x60,0x03,0xc0,0x01,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }

    createCursor

    Create a cursor from bitmap data. The cursor is entered into the server's
    cursor cache and will override any existing entry of the same name.

    Usage:

            createCursor name source mask fg_color bg_color x_hot y_hot

    e.g.,

            createCursor foo bitmap1 bitmap2 black white 8 8

    The named bitmaps must be created first with createBitmap.

    createPixmap

    Create a named pixmap. This replaces any old pixmap of the same name. The
    new pixmap is cached in server memory; when a widget pixmap resource is set,
    the pixmap cache will be searched for the named pixmap before asking Xlib
    to find the pixmap.

    Usage:

            createPixmap name width height depth fg_color bg_color data

    e.g.,

            createPixmap foo 16 16 8 black white {
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x01,
                0x60,0x03,0x20,0x02,0x60,0x03,0xc0,0x01,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }

    print

    Print a string on the standard output. This is used mainly for debugging
    user interfaces.

    Usage:

            print arg [arg ...]

    send

    Send a message to an object. The object interprets the message and returns
    a function value as the string result of the TCL command.

    Usage

            send <object> <message>

    postActivateCallback

    Post a callback procedure to be called when the UI is activated. The UI is
    activated when it is first downloaded to server, but it may also be
    activated (reactivated) after the application has exited and is later
    restarted, or when the UI is deactivated and reactivated. Note
    that the UI state vis-a-vis the external world (client application) may
    no longer be accurate after it has been idle for a time and then reactivated.

    Usage:

            postActivateCallback <procedure>

    postTimedCallback

    Post a callback to call the named procedure back after a specified delay
    in milliseconds.

    Usage:

            id = postTimedCallback procedure msec [client-data]

    After the specified delay the user callback procedure will be called with
    client_data (if given) as the single argument. Only one call will be made;
    the client must repost the callback in each call if the procedure is to be
    repeatedly executed.

    An ID value is returned which may be passed to deleteTimedCallback to delete
    the timer.

    deleteTimedCallback

    Delete a timer callback procedure. This procedure is typically used to
    break a timer loop, where the timer procedure repeatedly reposts itself at
    the end of each interval.

    Usage:

            deleteTimedCallback id

    The ID string is returned by postTimedCallback when a timer is posted.

    postWorkCallback

    Post a callback for a procedure to be called when the server is idle.
    Work procedures are used to perform computations in the background while
    the user interface remains active and able to respond to input events.
    This works only if the user work procedure does its job in small increments,
    doing only a small amount of processing in each call. The work procedure
    will be called repeatedly until it returns a status indicating that it has
    finished its task.

    Usage:

            id = postWorkCallback procedure [client-data]

    When the server has nothing else to do the user work procedure will be
    called with client_data (if given) as the single argument. The work procedure
    should return the string "done" when all processing is finished, or any other
    string if the procedure is to be called again.

    An ID value is returned which may be passed to deleteWorkCallback to delete
    the work procedure.

    deleteWorkCallback

    Delete a work callback procedure.

    Usage:

            deleteWorkCallback id

    The ID string is returned by postWorkCallback when a work procedure is posted.

    6.3 Gterm

    The gterm-image widget is a general 2D graphics-imaging widget providing
    a wide range of facilities for drawing graphics and text, for image
    display, and for graphics interaction.  Normally the client communicates
    directly with the Gterm widget to draw graphics, download image data,
    and so on, using some communications protocol outside the domain of the
    object manager.  Nonetheless so far as possible the facilities of the Gterm
    widget have also been made available to GUI code via the commands listed
    here.

    The Gterm widget adds the following function to the OBM library.

        ObmPostSetGtermCallback (obm, &setgterm, setgterm_client_data)

    This is called by a client application to post a procedure to be called
    when a gterm widget receives the setGterm command.  The calling sequence
    for setGterm callback is as follows:

                       setgterm (client_data, gterm_widget)

    The purpose of this callback is to tell the client which gterm widget is
    the "active" gterm widget.  This is used by clients which only support
    one active Gterm widget, i.e., which can only direct graphics output to
    one Gterm widget at a time.

    The messages or commands that can be sent to the Gterm widget by GUI
    code follow.

    General commands:

                       setGterm          # make widget the active Gterm

                       activate
                     deactivate
                    addCallback procedure-name callback-type
                          reset
                          flush

                   setCursorPos x y [raster]
                   getCursorPos x y
                  setCursorType cursortype
                           bell

    Graphics drawing commands:

                      setRaster raster
             raster = getRaster [raster]

                      setLogRes width height
                      getLogRes width height
                     setPhysRes width height
                     getPhysRes width height
                     setTextRes rows cols
                   setDataLevel level
                   setLineWidth width
                   setLineStyle style
                  setColorIndex index
                    setFillType filltype

                    clearScreen
                   drawPolyline vector
                 drawPolymarker vector
                    drawPolygon vector
                     drawMarker x y xsize ysize type

                  drawAlphaText x y text
               getAlphaTextSize string width height base
                    startDialog
                      endDialog
                    eraseDialog
                 drawDialogText x y text
              getDialogTextSize string width height base

    The coordinates used in the graphics drawing commands are logical
    coordinates as defined by setLogRes, in the coordinate system of the
    reference drawing raster as defined by setRaster.  The default reference
    raster is raster zero, the widget's window.  Vectors are specified as
    a list of points, e.g., { {x y} {x y} ... }.

    Imaging commands:

                  rasterInit
                assignRaster raster drawable
                createRaster raster type width height depth
               destroyRaster raster
        exists = queryRaster raster type width height depth
         raster = nextRaster [raster]
         nrasters = nRasters [nrasters]

                    setPixel raster x y value
            value = getPixel raster x y
                 writePixels raster pixels encoding x1 y1 nx ny
                  readPixels raster pixels encoding x1 y1 nx ny
               refreshPixels raster ct x1 y1 nx ny
       pixmap = createPixmap src x y width height
                  copyPixmap pixmap dst x y width height

     colormap = nextColormap [colormap]
                freeColormap colormap
               writeColormap colormap first nelem colors
                readColormap colormap first nelem colors
                loadColormap colormap offset scale

                initMappings
       mapping = nextMapping [mapping]
                 freeMapping mapping
               enableMapping mapping
              disableMapping mapping
      active = activeMapping mapping
              refreshMapping mapping

       raster = selectRaster dras dt dx dy rt rx ry [map]
                  unmapPixel sx sy raster rx ry [rz]

                  copyRaster rop src  st sx sy snx sny  dst dt dx dy dnx dny
                  setMapping mapping rop
                             src st sx sy snx sny  dst dt dx dy dnx dny
                  getMapping mapping rop
                             src st sx sy snx sny  dst dt dx dy dnx dny

                        flip mapping axis [axis...]

    Pixel arrays are long strings consisting either of a sequence of numeric
    pixel values separated by whitespace (space or newline), or a hex encoded
    sequence of bytes (2 hex digits per 8 bit pixel).  Colors are specified
    as a list of RGB triplets, e.g., { {R G B} {R G B} ... }.

    Refer to the documentation for the Gterm widget for a detailed description
    of rasters, mappings, and colormaps.

    Markers:

                   createMarker name [attribute-list]
                     markerInit

    New markers may be created with createMarker.  Once created, a marker
    functions under the Object Manager as a named object of class "marker".
    Refer to the marker class for a description of the commands defined for
    a marker.

    gterm Actions List

            ignore
            graphics-input
            graphics-context
            crosshair
            track-cursor
            enter-window
            leave-window
            popup-menu     {not implemented}
            reset
            m_create

    Default translations for Gterm window.
    Omitted for now: Ctrl ~Meta : popup-menu(tekMenu)

    default Gterm Translations

                   [Btn1Down]:m_create()
                   [Btn2Down]:crosshair(on)
                 [Btn2Motion]:crosshair(on)
                     [Btn2Up]:crosshair(off)
       ~Ctrl ~Meta [Btn3Down]:graphics-context()
                [EnterWindow]:enter-window()
                [LeaveWindow]:leave-window()
                   [KeyPress]:graphics-input()
                     [Motion]:track-cursor()

    6.3.1 GTERM class commands

    setGterm

    Set the active Gterm widget.  A UI can have more than one
    gterm widget, but due to restrictions on the client-server interface, it
    may be possible for only one to receive client output at any one time (any
    gterm widget can generate input to be sent to the client).  If the client
    has this restriction, the client-server interface code which uses OBM can
    call the ObmPostSetGtermCallback procedure to post a function to be called
    when the UI code calls the setGterm procedure.

    Usage:

            setGterm

    activate

    Activate the gterm widget.   This causes the next GIN mode
    setCursorType to warp the pointer into the gterm window.

    Usage:

            activate

    deactivate

    Deactivate the gterm widget.   If the cursor has been warped
    into the window by a previous activate/setCursorType GIN mode, this causes
    the cursor to be warped back to where it was previously.

    Usage:

            deactivate

    reset

    Reset the gterm widget.  This causes a number of state variables
    affecting graphics drawing options to be set to their default values.

    Usage:

            reset

    flush

    Flush any graphics output and synchronize the state of the widget
    with what is shown on the display.

    Usage:

            flush

    The gterm widget uses XLIB, which buffers graphics drawing commands and
    automatically sends them to the X server when 1) the buffer fills,
    2) input is requested from the server.  Such buffering of data is necessary
    for efficient operation and it should rarely be necessary to explicitly
    flush graphics output since XLIB does this automatically in most cases.
    An example of when explicitly flushing the ouptut might be necessary is in
    cases where smooth animation is desired and drawing the graphics in batches
    could cause the display to appear "jerky".

    addCallback

    Post a callback for a Gterm widget event.

    Usage:

            addCallback procedure-name [callback-type]

    The recognized Gterm callbacks are

            input           Called when the graphics-input action is invoked in
                            a translation table.  The default Gterm translation
                            table invokes this action when a KeyPress event occurs
                            in the Gterm window.
                            Callback:        widget-name input-type event-data

            resize          Called when the gterm window is resized.
                            Callback:        widget-name width height

            reset           Called when the "reset" action is invoked.
                            Callback:        widget-name

    If no callback is specified the default is "input".

    Note that in GUI code one can also use the translation table to directly
    invoke GUI procedures without need to use the Gterm input mechanism.  This
    is more flexible but we support the Gterm input callback here for
    applications that use the default translations.

    setCursorPos

    Warp the cursor (pointer) to the given coordinates.  This
    is a graphics drawing command and if no raster number is specified the
    current reference drawing raster, as set with setRaster, defines the
    coordinate system.

    Usage:

            setCursorPos x y [raster]

    A raster number may optionally given to define the raster coordinate system
    to be used.  raster=0 yields screen coordinates.

    getCursorPos

    Get the cursor position (raster 0 or screen coordinates).

    Usage:

            getCursorPos x y

    setCursorType

    Set the cursor type.

    Usage:

            setCursorType cursor-type

            idle        default cursor
            busy        busy cursor, e.g, when program is busy
            ginMode     graphics input mode cursor, set when program is
                        waiting for graphics input

    bell

    Gterm widget sound output.

    Usage:

            bell

    setRaster

    Set the number of the raster to be used to define the drawing
    context (e.g. coordinate system) for graphics and text drawing functions.

    Usage:

            setRaster raster-number

    getRaster

    Get the number of the raster which defines the drawing
    context, as set in the last setRaster call.

    Usage:

            raster = getRaster [raster]

    If the name of a variable is given the raster number will be stored
    directly in that variable.

    clearScreen

    Clear the "screen", i.e., window.  This action clears the
    drawing window and sets a number of drawing state variables to their default
    values.

    Usage:

            clearScreen

    rasterInit

    Initialize the raster subsystem, deleting all rasters and
    mappings and freeing the dynamic part of the colortable.

    Usage:

            rasterInit

    writePixels

    Set the values of some subset of the pixels in a raster.
    If any mappings are defined on the affected region and are enabled, any
    destination rasters will be automatically updated as defined by the mapping.

    Usage:

            writePixels raster pixels encoding nbits x1 y1 nx ny

            raster       The raster number.
            pixels       The pixel array, encoded as a string.
            encoding     The pixel encoding.  "numeric" means each pixel is
                         encoded as a decimal integer delimited by whitespace.
                         "hex" means the pixel array is hex encoded, 2 bytes
                         per 8 bit pixel, as a printable text string.  The
                         two bytes are defined as follows (v = pixel value):

                              byte1 = ((v >> 4) & 017) in hex [0-9A-F]
                              byte2 = ((v     ) & 017) in hex [0-9A-F]

                         Whitespace in a hex encoded string is ignored.
                         Hex encoding reduces the data volume by about a factor
                         of two (compared to numeric) and is only a factor of
                         two less space efficient than binary.

            nbits        Number of bits per pixel - currently only 8 bit pixels
                         are supported.

            x1,y1,nx,ny  Region of the raster to be written.

    Most real-world image processing applications get the Gterm widget handle
    with setGterm and pass binary data to the widget by calling GtWritePixels
    directly.  This is the most efficient approach for serious image processing
    where large amounts of data are involved.  However, being able to read and
    write raster pixels directly in a GUI can be useful in specialized
    applications, e.g., where the image is computed or modified by the GUI.

    setPixel

    Set the value of a single pixel.

    Usage:

            setPixel raster x y value

            raster   The raster number.
            x, y     The pixel to be set.
            value    The pixel value.

    This routine is more efficient than writePixels for setting the value of
    a single pixel, but is a lot less efficient if a block of pixels are to
    be set.

    readPixels

    Get the values of some subset of the pixels in a raster.

    Usage:

            readPixels raster pixels encoding nbits x1 y1 nx ny

            raster        The raster number.
            pixels        The pixel array, encoded as a string.
            encoding      The pixel encoding.  "numeric" means each pixel is
                          encoded as a decimal integer delimited by whitespace.
                          "hex" means the pixel array is hex encoded, 2 bytes
                          per 8 bit pixel, as a printable text string.  The
                          two bytes are defined as follows (v = pixel value):

                               byte1 = ((v >> 4) & 017) in hex [0-9A-F]
                               byte2 = ((v     ) & 017) in hex [0-9A-F]

                          Whitespace in a hex encoded string is ignored.
                          Hex encoding reduces the data volume by about a factor
                          of two (compared to numeric) and is only a factor of
                          two less space efficient than binary.

            nbits         Number of bits per pixel - currently only 8 bit pixels
                          are supported.

            x1,y1,nx,ny   Region of the raster to be read.

    Use readPixels to read a block of pixels, and getPixel to get the value
    of a single pixel.

    getPixel

    Get the value of a single pixel.

    Usage:

            getPixel raster x y

            raster      The raster number.
            x, y        The pixel to be set.

    This routine is more efficient than readPixels for getting the value of
    a single pixel, but is a lot less efficient if a block of pixels are to
    be read.

    nextMapping

    Return the index of the next unused mapping.

    Usage:

            nextMapping

    Returns the mapping number as the function value.

    getMapping

    Get a mapping.

    Usage:

            getMapping mapping rop src st sx sy snx sny dst dt dx dy dnx dny

    All parameters except the mapping number are output parameters.

    setMapping

    Set a mapping.

    Usage:

            setMapping mapping rop src st sx sy snx sny dst dt dx dy dnx dny

    All parameters are input parameters.

    loadColormap

    Load a colormap.

    Usage:

            loadColormap colormap [offset [scale]]

    The offset and scale parameters may be used to adjust the brightness and
    contrast of the image when the colormap is loaded.  The normalized colormap
    has offset=0.5, scale=1.0.  Colormap zero is the hardware colormap.

    selectRaster

    Given the raw screen coordinates SX,SY (or coords in
    any destination raster), determine the mapping and source raster which are
    mapped to that pixel and return the raster and mapping numbers and the
    coordinates of the same pixel in the source raster.

    Usage:

            raster = selectRaster dras dt dx dy rt rx ry [map]

    where

    		dras         display raster
                    dt,rt        coordinate type - "pixel" or "ndc"
                    dx,dy        display raster coordinates (input)
                    rx,ry        source raster coordinates (output)
                    map          mapping selected (output)

    Note that the coordinates returned by selectRaster are measured (taking
    a line as an example) from zero at the left edge of the first pixel, to
    "width" at the right edge of the last pixel.  This means that the floating
    point coordinates of the center of raster pixel N will be N + 0.5.  For
    example, if we input screen coordinates (dras=0), x=117, and no mapping
    is in effect, the floating point raster coordinates returned will be 117.5.
    The difference occurs because the input coordinate is a pixel number
    (integer) while the output coordinate is a floating point coordinate
    measuring the continuously variable location a pixel.  int(x) will convert
    this coordinate to a raster pixel number.

    unmapPixel

    unmapPixel is a simplified, less general version of
    selectRaster which will automatically follow graphics pipelines back to
    the original mapped raster.  If desired the raster pixel value can be
    returned as well as the raster number and raster pixel coordinates
    corresponding to a screen (raster 0) pixel.

    Usage:

            unmapPixel sx sy raster rx ry [rz]

    where

    		sx,sy        "screen" (raster 0) coordinates
                    raster       original mapped raster (output)
                    rx,ry        source raster coordinates (output)
                    rz           source raster pixel value (output)

    By following graphics pipelines back to the original source raster we mean
    the following.  If raster A is mapped to raster B which is mapped to C (the
    screen), given a screen coordinate in the mapped region unmapPixel will
    return the raster number and coordinates for raster A.

    flip

    Edit a mapping to flip the mapped subimage in X and/or Y.

    Usage:

            flip mapping axis [axis]

    where axis is "x" or "y".  This is a convenience routine for changing only
    the flip portion of a mapping.

    markerInit

    Initialize the Marker subsystem for a Gterm widget.
    This destroys all markers and initializes the marker subsystem.

    Usage:

            markerInit

    createMarker

    Create a new marker.

    Usage:

            createMarker name attribute-list
      e.g.  createMarker name {attribute value [attribute value ...]}
        or  createMarker name attribute value [attribute value ...]

    Any marker attribute may be assigned a value when the marker is created.
    Refer to <ObmW/Gterm.h> for a list of marker attribute names.  Often the
    the attributes "type" and "createMode" need to be specified at marker
    create time.

            type            The marker type: text, rectangle, circle, etc.

            createMode      A marker should be created with createMode=interactive
                            if the user is expected to interactively drag out
                            the marker using the pointer and either the default
                            or an application specified translation table.  A
                            marker can also be created interactively using only
                            the m_create (marker create) action, however m_create
                            does not allow the marker attributes to be set.

    There are any number of ways to use a GUI to create a marker under the
    Object Manager, but an example might be using a translation to call a GUI
    procedure which issues the createMarker call.  For example a pointer down
    event could translate as "call(newMarker,$name,$x,$y) m_create()" where
    newMarker is a GUI marker creation procedure which sends a createMarker
    message to the Gterm widget.  The GUI procedure could set the marker
    attributes as desired, possibly using additional GUI components to define
    the marker attributes.  The m_create action will notice that a
    createMarker has been executed and will merely activate the marker and
    give it the pointer focus (i.e. install the marker translations).  The
    user will then use the pointer or keyboard to drag out the marker.

    If the marker is created noninteractive the application must set the marker
    position and size using marker attributes.  If the marker is sensitive
    the user can then use the marker's translations to interactively modify
    the marker (resize it, move it, etc.).  All markers which are visible and
    sensitive and which have the necessary translations can be interactively
    modified by the user; the reason for creating a marker in interactive mode
    is to allow the initial marker position and size to be specified
    interactively *when* the marker is created, instead of afterwards.

    Any number of attributes may be given when the marker is created.  Most
    marker attributes can also be modified after a marker has been created
    by sending setAttribute messages to the marker.

    6.4 HTML

    The HTML (hypertext markup language) widget displays a block of HTML
    formatted text, the "document" to be displayed.  The text consists of a
    mixture of text to be displayed and embedded formatting directives.  The
    text may also contain "hot links" pointing to other HTML-formatted
    documents.

                   setText text [target [header_text [footer_text]]]
            text = getText [format [font]]
             retestAnchors

         id = positionToId x y
              idToPosition id x y
          anchorToPosition name x y
           id = anchorToId name
                    gotoId id

              n = getHRefs list
          n = getImageSrcs list
              n = getLinks list

              setSelection start end
       text = getSelection start end
            clearSelection

                searchText pattern start end [direction [search_type]]

               addCallback procedure-name [callback-type]
            deleteCallback procedure-name [callback-type]

    The possible callback types and their callback arguments are as follows.

           anchor          widget cbtype event text href element_id
           testAnchor      widget cbtype href
           submitForm      widget cbtype event attrs href method enctype encentity
           link            widget cbtype href role
           pointerMotion   widget cbtype href

    See the comments below for further details on the callback types and their
    arguments.

    6.4.1 Command Summary

    6.5 Markers

    A marker is a graphics object implemented by the Gterm-Image widget.
    Markers are not real toolkit widgets, but they act much like widgets and
    are interfaced as an object class under the Object Manager.  The Marker
    class is not a subclass, it is a base class like Widget, but Marker objects
    can exist only as children of Gterm widgets.

    Since markers are not independent widgets but rather part of a Gterm widget
    instance, the parent Gterm widget is partially responsible for managing
    markers.  The Gterm widget implements the following commands for dealing
    with markers.

                   createMarker name [attribute-list]
                     markerInit

    A new marker is created by sending the createMarker message to the parent
    gterm widget.  This creates a marker of the given name and type.
    The markerInit command, if sent to a gterm widget, destroys any markers
    defined for that widget and reinitializes the marker facility.  Markers
    may also be created by action procedures in response to user input events.

    A marker may be destroyed by itself in response to an input event (e.g. the
    user presses the delete key), by sending the marker the destroy message
    to tell it to destroy itself, by sending a markerInit to the parent gterm
    widget, or by destroying the marker object (or any parent) with the server
    command destroyObject.

    Once a marker has been created it behaves as an independent object and
    receives and executes messages, responds to events, generates callbacks,
    and so on.  The marker class defines the following commands.

                    makeCopy name
                 addCallback procedure [event [event ...]]
                      notify [event-type [param [param ...]]]
                     destroy [nocallback]

                     markpos
                      redraw [function] [markpos|nomarkpos] [erase|noerase]

                       raise [reference-marker]
                       lower [reference-marker]

                        move x y
                      resize width height
                      rotate angle                # radians

                         set attribute value      # alias for setAttribute
                 value = get attribute            # alias for getAttribute

                setAttribute attribute value
        value = getAttribute attribute
               setAttributes attribute-list
               getAttributes attribute-list
                 setVertices points first npts
                 getVertices points first npts

          region = getRegion [unmap] [coord-type]
                     getRect dx dy dnx dny

    Marker positions and dimensions are given in window (raster 0) coordinates.

    The operators raise, lower, move, resize, and rotate erase the marker,
    modify it as indicated, and redraw it with the new attributes.  For finer
    control over marker attributes one can use [get|set]Attribute[s] and
    [get|set]Vertices to edit the markers directly.  In this case an auto
    redraw is not performed (unless the autoRedraw marker attribute is set).
    The usual sequence is a markpos to record the marker position, one or more
    setAttribute calls to change marker attributes, then a redraw to erase
    the old marker and redraw the new one.  Markers have many attributes which
    can be set to control things like the position and size, colors, line
    widths, fill type and style, font, rubber-band technique, and so on.
    Refer to <ObmW/Gterm.h> for a list of marker types and attributes.

    The marker type may be changed at runtime without destroying the marker.
    For example a circle can be changed to an ellipse or a rectangle.  This
    also works for polygons (the vertex list is preserved and restored when
    the marker is changed back to a polygon).

    The current shape of a marker may be queried with getVertices, which
    returns the polygon or polyline vertex list in window coordinates.  A more
    powerful routine which does something similar is getRegion.  This routine
    returns a high level description of the region outlined by the marker,
    giving the marker type (rectangle, circle, ellipse etc.), center, width
    and height, and so on.  Any position or dimension information may
    optionally be transformed back to the original source raster, if the marker
    center is in a region of the window which is the destination of an active
    mapping.  The unmap option will follow multiple mappings back to the
    original mapped source raster.

    The getRect function returns the parameters of the region outlined by a
    rectangle marker in a form convenient for use in a Gterm setMapping call
    (this is used to display an image within a marker).

    Default translations when pointer is over a marker.
    default Marker Translations

            Shift <Btn1Motion>    m_rotateResize()
                  <Btn1Motion>    m_moveResize()
              Shift <Btn1Down>    m_raise()  m_markpos()
                    <Btn1Down>    m_raise()  m_markposAdd()
                      <Btn1Up>    m_redraw() m_destroyNull()
                    <Btn2Down>    m_lower()
                <Key> BackSpace   m_deleteDestroy()
                   <Key> Delete   m_deleteDestroy()
                    <KeyPress>    m_input()
                      <Motion>    track-cursor()

    6.5.1  Command Summary

    makeCopy

    Copy a marker.  The new marker is initially identical to the
    old one, and will not be distinct until, e.g., moved to a new center.

    Usage:

             makeCopy name

    addCallback

    Post a marker callback to be called when the specified
    event or events occurs.  If no events are listed a Notify callback will
    be posted.

    Usage:

    	addCallback procedure [event [event ...]]

    notify

    Generate a Marker pseudo-event, causing any posted client
    callback procedures to be called.

    Usage:

            notify [event-type [param [param ...]]]

    destroy

    Destroy a marker.  Just tell the marker to destroy itself.
    All cleanup outside the marker facility relies upon the use of callbacks.
    This includes our callback markerDestroyCallback below.

    Usage:

            destroy

    markpos

    Mark the current position of a marker for a later redraw.

    Usage:

            markpos

    Markpos is used to mark the position of a marker before changing any
    marker attributes, so that a later "redraw marked" will erase the old
    marker rather than the new one.  This is necessary, for example, if any
    marker attributes are changed which affect the size or position of the
    marker.

    redraw

    Redraw a marker.

    Usage:

            redraw [function] [erase|noerase] [markpos|nomarkpos]

    By default redraw will erase the old marker at the position indicated by
    a previous call to markpos, and redraw the marker with the current
    attributes using the drawing function copy (copy source to destination).
    Hence the usual usage is "markpos ... change marker attributes ... redraw".
    Optional arguments may be given to change the drawing function, enable or
    disable erase, or force redraw to do a markpos.  These arguments may be
    given in any order.

    The drawing functions are as given in the XLIB documentation, minus the
    "GX" prefix.  The most commonly used functions are "copy" and "xor".
    A normal marker redraw uses function=copy.

    raise

    Raise a marker, i.e., cause it to be drawn on top of other
    markers when overlapping markers are drawn.

    Usage:

            raise [reference-marker]

    In a reference marker is named the marker will raise itself above this
    marker, otherwise the raised marker becomes the topmost marker.

    lower

    Lower a marker, i.e., cause it to be drawn beneath other
    markers when overlapping markers are drawn.

    Usage:

            lower [reference-marker]

    In a reference marker is named the marker will lower itself beneath this
    marker, otherwise the lowered marker becomes the lowest marker.

    move

    Move a marker.

    Usage:

            move x y

    Move the marker center to the indicated coordinates in the display window.

    resize

    Resize a marker.

    Usage:

             resize width height

    Resize the marker to the indicated size.  By default width and height are
    given in pixels.  For a text marker one can append "ch" to indicate that
    the units are chars in whatever font is in use, e.g., "40ch" or "40 chars"
    is an acceptable value for a text marker dimension.

    rotate

    Rotate a marker.

    Usage:

             rotate angle

    Redraw a marker oriented to the given rotation angle.  The angle is
    given in radians.

    getAttribute

    Return the value of a marker attribute.

    Usage:

            value = getAttribute attribute-name

    setAttribute

    Set the value of a marker attribute.

    Usage:

            setAttribute attribute-name value

    getAttributes

    Return the values of a list of marker attributes.

    Usage:

              getAttributes attribute-list
      i.e.    getAttributes {name value [name value ...]}
        or    getAttributes name value [name value ...]

    where "value" is the name of the variable in which the attribute value
    is to be stored.

    setAttributes

    Set the values of a list of marker attributes.

    Usage:

            setAttributes attribute-list
      i.e.  setAttributes {name value [name value ...]}

    where "value" is the new value of the associated marker attribute.

    getVertices

    Get some or all of the vertices making up the polygon or
    polyline representation of a marker.

    Usage:

            getVertices points [first npts]

    The polygon or polyline representation of a marker is returned in the
    variable "points", as a string of the form { {x y} {x y} ...}.  The first
    point is number zero.

    setVertices

    Set some or all of the vertices making up the polygon or
    polyline representation of a marker.

    Usage:

            setVertices points [first npts]

    The polygon or polyline representation of a marker is set using the points
    passed in the "points" variable as a string of the form { {x y} {x y} ...}.
    If FIRST and NPTS are not specified first is assumed to be zero (the first
    point) and NPTS is the length of the points array.

    getRegion

    Return as a text string a high level description of the
    region defined by a marker.

    Usage:

            region = getRegion [unmap] [coord-type]

    The output string defines the marker type and the major marker positional
    attributes.  The region description formats for the various marker types
    follow.

            text raster x y width height
            line raster x y x y
            polyline raster npts { {x y} {x y} ...}
            rectangle raster x y width height rotangle
            circle raster x y radius
            ellipse raster x y width height rotangle
            polygon raster npts { {x y} {x y} ...}

    Here, width and height refer to the distance from the marker center to an
    edge, not to the width or height of the whole marker.  This avoids
    ambiguities about where the edge of a marker is if the width is even or
    odd.  Using the center to edge measurement, the edge is at x +/- width,
    y +/- height.

    If the "unmap" flag is given getRegion will attempt to associate the
    marker with a mapped raster, reversing any mappings from the screen back
    to the original source raster, and returning the raster number and raster
    coordinates and marker sizes.  If "unmap" is not given the marker
    coordinates will refer to raster 0.  Either pixel ("pixel") or NDC
    ("ndc") coordinates may be returned, pixel coordinates being the default.

    getRect

    Return the region enclosed by a rectangle marker.  The rect is
    returned in a form convenient for use as the destination rect in a gterm
    widget raster mapping.

    Usage:

            getRect dx dy dnx dny

    The rect is stored in the output arguments.

    6.6 Widget

    The Widget class is the generic or base class for the window system
    toolkit widgets supported by the object manager.  The Widget class
    supports a number of different Xt widget classes using a table driven
    approach to describe each widget.  Any widget may be created, destroyed,
    and manipulated in various ways using only the generic Widget class
    procedures and Widget-specific resources.  The Widget class may be
    subclassed to support complex Widgets that require custom class-specific
    commands for use by the GUI code.

    Generic Widget-class commands:

                     set <resource-name> <value>
                     get <resource-name>

             addCallback <procedure-name> []
          deleteCallback <procedure-name>
            setSensitive <sensitive>
             isSensitive

                 realize
               unrealize
             isRealizeed
                     map
                   unmap
                  manage child [child ...]
                unmanage child [child ...]
                   popup [grab-kind]
                 popdown
       popupSpringLoaded

                    move <x> <y>
                  resize <width> <height> <border-width>
               configure <x> <y> <width> <height> <border-width>

    The most important Widget commands are set/get resource, and the
    callbacks.  The widget sensitivity can be set and queried using set/get
    resource, but special procedures are provided to make this common operation
    more convenient.

    Class specific functions:

                     append text                         # text widget
                    setList list [resize]                # list widget
            value = getItem itemno
                  highlight itemno
                unhighlight

    Ideally the widget class should be subclassed for widgets that require
    class-specific functions, but in simple cases involving standard widgets
    the support is built into the widget class code as a special case.

    Special actions (used in translations):

                    call (proc [,arg, ...])
                   popup (menu-name [xoffset [yoffset]])
                 popdown (menu-name)

    The "call" action is a very general mechanism which allows any GUI procedure
    to be registered with any translation using the X translation table
    mechanism.  The popup and popdown actions are used for popup menus.  The
    menu will be popped up at the event coordinates plus the optional offsets
    if given.

    Event handling:

         addEventHandler <procname> <event-mask> [<event-mask>...]

    Event callback:

        userEventHandler widget event-type time wx wy rx ry other

    In most cases translations are preferable to events, but a GUI can capture
    raw events if it wishes by adding event handlers.  Nearly all of the X
    event types are supported.  The callback syntax employs a number of
    standard arguments, followed by a number of event-specific arguments.

    addCallback

    Add a callback procedure to the callback list for
    a widget.  If no callback name is given, "callback" is assumed.

    Usage:

            addCallback  [<callback-name>]

    Specific widgets only support certain types of callbacks.  There is no
    checking that the callback type specified is supported by a widget; the
    wrong type of callback can be registered, but it will never be called.

    deleteCallback

    Delete a callback procedure previously registered
    for a widget.

    Usage:

            deleteCallback <procedure-name>

    do_userproc (call)

    Translation action procedure used to call general user
    action procedures in the interpreter.  The name of the user procedure to
    be called is given as the first argument in the translation.  For example,
    the translation "call(foo,a,b,c)" would cause procedure foo to be called
    with the arguments (a,b,c).  The following arguments are special:

            Argument        Replaced by

            $name             object name of widget
            $time             event->time
            $x                event->x
            $y                event->y
            $x_root           event->x_root
            $y_root           event->y_root

    The "user procedure" can be any server procedure.

    do_popup

    Popup a menu (or other spring loaded popup) at the location
    of the event which triggered this action.

    Usage:

            popup(menu-name [xoffset [yoffset]])

    do_popdown

    Pop down a menu.

    Usage:

            popdown(menu-name)

    set

    Set a widget resource.

    Usage:

            set <resource-name> <value>

    get

    Get a widget resource value as a string.

    Usage:

            get <resource-name>

    append

    Append data to a text widget.

    Usage:

            append <text>

    setList

    Set the item list of a list widget.

    Usage:

            setList list [resize]

    The list is a simple list of strings, passed as a single string argument to
    setList (quotes, braces, etc. may be used to quote strings containing
    special characters).

    getItem

    Get an item in a list widget.

    Usage:

            value = getItem itemno

    If ITEMNO is a number the indicated list item is returned, or the string
    "EOF" if the requested item is beyond the end of the list.  Otherwise the
    currently selected item is returned, and the index of the item is returned
    in the output variable ITEMNO.  If no item is currently selected ITEMNO
    will be set to "none" on output.

    highlight

    Highlight an item in a list widget.

    Usage:

            highlight itemno

    The indicated item of the list is highlighted as if the item had been
    selected by the user.  Any previously highlighted item is unhighlighted.

    unhighlight

    Unhighlight the currently highlighted item in a
    list widget.

    Usage:

            unhighlight

    Any currently highlighted item in the list widget is unhighlighted.

    realize

    Realize a widget.  This activates and assigns windows for
    a widget and all of its descendants.  Realizing a widget does not in itself
    cause it to appear on the screen.

    Usage:

            realize

    unrealize

    Unrealize a widget.  This destroys the windows assigned
    to a widget and all of its descendants.

    Usage:

            unrealize

    isRealized

    Test whether a widget is realized.

    Usage:

            isRealized

    map

    Map a widget.

    Usage:

            map

    unmap

    Unmap a widget.

    Usage:

            unmap

    manage

    Manage a list of child widgets.  These should share the
    same common parent, a geometry widget of some sort.  Managing the
    children makes them appear in the window, possibly causing the other
    children to be rearranged in the window.

    Usage:

            manage child [child ...]

    This message should be sent to the geometry widget which is the parent
    of the children.

    unmanage

    Unmanage a list of child widgets.  These should share the
    same common parent, a geometry widget of some sort.  Unmanaging the
    children makes them disappear from the window and be removed from geometry
    management, possibly causing the other children to be rearranged in the
    window.

    Usage:

            unmanage child [child ...]

    This message should be sent to the geometry widget which is the parent
    of the children.

    popup

    Popup a shell widget.  If no grab is indicated the popup
    can remain up while other windows accept input.

    Usage:

            popup [grab-kind]

    popdown

    Popdown a shell widget.

    Usage:

            popdown

    popupSpringLoaded

    Popup a shell widget, e.g., a popup menu.
    This implies an exclusive grab.

    Usage:

            popupSpringLoaded

    move

    Move a widget to the given window relative coordinates.

    Usage:

            move <x> <y>

    resize

    Resize a widget.

    Usage:

            resize <width> <height> <border-width>

    configure

    Configure a widget, i.e., execute a simultaneous
    move and resize.

    Usage:

            configure <x> <y> <width> <height> <border-width>

    setSensitive

    Set the sensitivity of a widget.

    Usage:

            setSensitive <sensitive>

    isSensitive

    Test the sensitivity of a widget.

    Usage:

            isSensitive

    addEventHandler

    Add a custom event handler to a widget.  A list
    of event masks is given to define the classes of events the user supplied
    event handling procedure is to receive.

    Usage:

            addEventHandler <procname> <event-mask> [<event-mask>...]

    removeEventHandler

    Remove an event handler previously posted
    with addEventHandler, above.

    Usage:

            removeEventHandler procname

    event

    Generic event handler called when a widget event handler
    posted by addEventHandler is called.

    The user event handler is called as

            userEventHandler widget event-type time wx wy rx ry other

    where "other" is an event-type specific list of fields describing the
    the event.

    6.7 Parameter

    The UI parameter class is used for client-UI communications.  The client
    does not control the user interface directly, rather the UI defines a set
    of abstract UI parameters, and during execution the client application
    assigns values to these parameters.  These UI parameters should be thought
    of as describing the runtime state of the client as viewed by the GUI.
    The GUI is free to interpret this state information in any way, including
    ignoring it.  Many GUIs can be written which use the same client state
    as described by the UI parameters.

    Assigning a value to a UI parameter causes the new value to be stored, and
    any parameter action procedures registered by the UI to be called.
    The action or actions [if any] taken when a parameter value changes are
    arbitrary, e.g. the action might be something as simple as changing a
    displayed value of a UI widget, or something more complex like displaying
    a popup.

    UI Parameter class commands:

                getValue
                setValue  <new-value>
             addCallback  <procedure-name>
          deleteCallback  <procedure-name>
                  notify

    The most common usage is for the GUI to post one or more callbacks for
    each UI parameter.  When the UI parameter value is changed [with setValue,
    e.g. by the client] the GUI callback procedures are called with the old
    and new UI parameter values on the command line.  addCallback is used to
    add a callback procedure, and deleteCallback to delete one.  Multiple
    callbacks may be registered for a single UI parameter.  notify is used
    to simulate a parameter value change, causing any callback procedures to
    be invoked.

    The callback procedure is called as follows:

    	user-procedure param-name {old-value} {new-value}

    The important thing to note here is that the old and new value strings
    are quoted with braces.  This prevents any interpretation of the string
    by Tcl when the callback is executed, which is necessary because the
    strings can contain arbitrary data.  When Tcl calls the callback the
    first level of braces will be stripped off, leaving old-value and new-value
    each as a single string argument.

    setValue

    Set the value of a parameter, and notify all clients
    via the posted callback procedures that the parameter value has changed.

    Usage:

            setValue <new-value>

    getValue

    Get the value of a parameter.

    Usage:

            getValue

    notify

    Notify the registered clients of a parameter as if the
    value had changed.

    Usage:

            notify

    addCallback

    Add a callback procedure to the callback list for
    a parameter.

    Usage:

            addCallback <procedure-name>

    deleteCallback

    Delete a callback procedure previously registered
    for a parameter.

    Usage:

            deleteCallback <procedure-name>