\chapter{Implementation of the User Interface}
\label{XGUIImplem}
\index{User Interface Implementation}
\thispagestyle{empty}

This chapter explaines important data types, functions, and the
program structure of the graphical user interface. Definitions and
data structures used by the program, are located not only in the file
{\tt glob\_typ.h }of the SNNS kernel, but also in the header files of
the X-window system and the Athena Toolkit. For reference of those
definitions see the X11 documentation release 4.0 or 5.0.

\index{XGUI!Implementation}
How X, XGUI and the kernel cooperate is sketched in
figure~\ref{PicComponents}. The MIT Athena Toolkit was selected
because of its widespread use. In this toolkit, so called {\em
widgets}\/ are defined (window elements like boxes, menu buttons,
toggles, scrollbars and so forth). XGUI should work with all window
mangers, but the following descriptions refer only to the {\it twm}
window manager.

%\begin{figure}[htbp]
%\begin{center}
%  \begin{minipage}{\textwidth}
%    \screendump{0.8}{xgui_figs/PicComponents.ps}
%  \end{minipage}
%\caption{How X, XGUI and the simulator kernel cooperate}
%\label{PicComponents}
%\end{center}
%\end{figure}

\begin{figure}[htbp]
\begin{center}
\setlength{\unitlength}{0.0125in}
\begin{picture}(455,205)(55,342)
\thicklines
\put(102,455){\vector( 0, 1){ 50}}
\put(125,505){\vector( 0,-1){ 50}}
\put( 55,417){\framebox(113,38){}}
\put( 55,380){\framebox(178,37){}}
\put( 55,342){\framebox(244,38){}}
\put(187,417){\vector( 0, 1){ 88}}
\put(205,505){\vector( 0,-1){ 88}}
\put(257,380){\vector( 0, 1){125}}
\put(280,505){\vector( 0,-1){125}}
\put(341,342){\framebox(169,38){}}
\put(341,427){\framebox(169,37){}}
\put(400,505){\vector( 0,-1){ 41}}
\put(449,464){\vector( 0, 1){ 41}}
\put(398,427){\vector( 0,-1){ 47}}
\put(449,380){\vector( 0, 1){ 47}}
\put( 55,505){\framebox(455,42){}}
\put( 65,431){\parbox{4cm}{\bf Athena Toolkit}}
\put(102,394){\parbox{4cm}{\bf Xt-Intrinsics}}
\put(163,356){\parbox{3cm}{\bf Xlib}}
\put(369,441){\parbox{4cm}{\bf Kernel Interface}}
\put(379,356){\parbox{4cm}{\bf SNNS-kernel}}
\put(238,524){\parbox{3cm}{\bf SNNS-XGUI}}
\end{picture}
\caption{How X, XGUI and the simulator kernel cooperate}
\label{PicComponents}
\end{center}
\end{figure}

After opening of the first window, SNNS-XGUI transfers control to X by
entering the main-event-dispatch-loop\footnote{SNNS-XGUI interpretes
this as an application.}.To react to different events (e.g.\ mouse
movement), X now calls predefined subroutines like callbacks and
event handlers, which return control to X after completion. All outputs
(e.g.\ line drawing) are buffered by the X server until it has resumed
control. This asynchronous behaviour complicates debugging, since
changes in the user interface are invisible at the time they are
processed. The compile switch {\tt DEBUG} forces the X server with
calls to {\tt XFLUSH()} to produce output at crucial points. The same
result is obtained by specifying {\tt -synchronous} as an argument in
the call to XGUI\@. In both cases output speed decreases dramatically.

For windows which return a value, like the Layer window or the
Confirmer, X must react directly to events. There, the
\index{Event-Dispatch-Loop}
Event-Dispatch-Loop is  re-programmed where the exit condition is true
after the call to a routine for a specific button (e.g.\ {\tt DONE}).
The next program segment can immediately use the result. The call to the
confirmer demonstrates this very clearly:

\begin{quote}
\begin{verbatim}
if (ui_confirmYes(''Load will erase current network. Load?''))
    ui_file_loadNet(filename);
else
    ui_printMessage(''Loading aborted.'');
...
\end{verbatim}
\end{quote}

{\tt ui\_confirmYes()} builds the confirmer and dispatches all events
until one of the buttons {\tt YES} or {\tt NO} is pressed. Then it
returns this value as a boolean. Without this loop, the confirmer would
become visible only after the processing of the code, and a default
value would always be returned!

On processing the teaching cycles or the update steps, it is necessary
to check for new events after each step. This is the only way to
recognize the clicking of the {\tt STOP} button in time.  The {\em
WorkProc}\/ construct is a means for solving this problem.  The
routine for performing one step is declared as WorkProc with the
statement {\tt XtAppAddWorkProc(\dots)}. This routine is called as
long as no events are waiting. When all cycles/steps are processed it
returns {\tt True}, thereby being removed. A soon as the button {\tt
STOP} is pressed, the corresponding callback routine {\tt
ui\_rem\_stopProc} removes the WorkProc with the command {\tt
XtRemoveWorkProc(ui\_workProcId)}. A WorkProc, already existing when a
new one is defined, gets deleted (see also \cite{you89}, p. 136ff).
This also explains, why the starting of update steps cancels a
running teaching process and vice versa. A running WorkProc always
terminates correctly, i.e.\ it is not interrupted by incomming events.
Therefore XGUI processes all events as usual, but slows down with
increasing running time of the WorkProcs.

\index{Callback Function}
In general there is one callback function for each button. However,
some buttons call the same function, and use just different values for
the argument {\tt client\_data}. This argument, the calling widget and
an aditional argument {\tt call\_data} are passed over to the callback
procedure. {\tt client\_data} is defined by {\tt AtAddCallback()}, {\tt
call\_data} by the kind of widget that is calling. The scrollbar
widget, for example, passes the position of the slider.

With the use of window systems like X, a structuring of the source
code according to the windows used is almost automatic (see also
table~\ref{TabSourceFiles} and~\ref{TabSourceFiles2}).

\begin{table}
\begin{center}
\begin{tabular}{|l|l|}
\hline
bn\_TD\_bignet.c & the BIGNET time delay panel \& functions\\
bn\_art1.c & the BIGNET ART1 panel \& functions\\
bn\_art2.c & the BIGNET ART2 panel \& functions\\
bn\_artmap.c & the BIGNET ARTMAP panel \& functions\\
bn\_basics.c & subroutines common to all BIGNET tools\\
bn\_bignet.c & the BIGNET feed forward panel \& functions\\
bn\_menu.c & the BIGNET tools selection menu\\
cc\_main.c & cascade correlation control panel\\
d3\_anageo.c & 3--D matrix operations \\
d3\_disp.c & event loop for 3--D display\\
d3\_dither.c & color rastering\\
d3\_draw.c & high level drawing functions\\
d3\_font5x7.c & 5x7 font array\\
d3\_font5x8.c & 5x8 font array\\
d3\_font8x14.c & 8x14 font array\\
d3\_fonts.c & text output control\\
d3\_global.c & global variables for 3--D \\
d3\_graph.c & low level drawing functions\\
d3\_light.c & illumination panel\\
d3\_links.c & 3--D link display panel\\
d3\_lists.c & 3--D list managenemt\\
d3\_main.c & 3--D interface handling\\
d3\_model.c & solid/wire display setting\\
d3\_move.c & rotation,translation and scaling\\
d3\_pannels.c & 3--D control panel\\
d3\_point.c & 3--D pixel output\\
d3\_project.c & 3--D projection panel\\
d3\_setup.c & 3--D setup panel\\
d3\_shade.c & shading algorithm\\
d3\_units.c & 3--D unit setup panel\\
d3\_xUtils.c & X window routine interface\\
d3\_zValue.c & z--value input panel\\
d3\_zgraph.c & z--buffer functions\\
o\_graph.c & plotting of the error graph\\
pr\_main.c & pruning panel \\
ui\_action.c & editor actions\\
ui\_colEdit.c & changing of the display colors\\
\hline 
\end{tabular}
\caption{The source files of SNNS-XGUI, Part I}
\label{TabSourceFiles}
\end{center}
\end{table}

\index{XGUI!Source File (Table)}
\begin{table}
\begin{center}
\begin{tabular}{|l|l|}
\hline
ui\_color.c & handles the color maps\\
ui\_config.c & load \& save of configurations\\
ui\_confirmer.c & handling of the confirmer\\
ui\_display.c & administration of displays\\
ui\_displwght.c & implements the Hinton-- and WV--diagrams\\
ui\_edit.c & editing of f-types and sites\\
ui\_event.c & event handler for mouse or window events\\
ui\_file.c & creation of the file panel\\
ui\_fileP.c & load, save (high level)\\
ui\_funcdispl.c & displays the activation and output functions\\
ui\_info.c & creation of the info panel\\
ui\_infoP.c & callbacks and handling of the info panel\\
ui\_inversion.c & handels the inversion display \& algorithm\\
ui\_key.c & event handler for keyboard\\
ui\_layer.c & creation of layer popups\\
ui\_layerP.c & handling of the layer popup\\
ui\_lists.c &  administration of the list popup\\
ui\_main.c & initializing\\
ui\_mainP.c & windows and popups, help facility\\
ui\_maspar.c & maspar user interface\\
ui\_netGraph.c & drawing of network elements (mid level)\\
ui\_netUpdate.c & drawing of the network, whole or parts (high level)\\
ui\_print.c & creation of the print panel\\
ui\_printP.c & callbacks and handling of the print panel\\
ui\_printps.c & handling of the Postscript generation\\
ui\_control.c & creation of the control panel\\
ui\_controlP.c & callbacks and handling of the control panel\\
ui\_result.c & handling of the result file generation\\
ui\_selection.c & administration of the selection\\
ui\_setup.c & creation of the setup panel\\
ui\_setupP.c & administration of the setup panel\\
ui\_status.c & status information in the manager panel\\
ui\_textP.c & text output (stdout, Log file)\\
ui\_utilP.c & utility functions\\
ui\_xGraphic.c & X graphic interface (low level)\\
ui\_xWidgets.c & handling of widgets\\
ui.h & datatypes, definitions\\
\hline 
\end{tabular}
\caption{The source files of SNNS-XGUI, Part II}
\label{TabSourceFiles2}
\end{center}
\end{table}


Callback procedures are kept in a separate file. Since SNNS-XGUI
consists mainly of those functions and calling depth remains fairly
shallow, the source code is easily readable.


\section{Administration of the Windows}
\index{Window!Administration}

There are three kinds of windows. They differ in the shell selected, and
in the mode of the event handling. Transient shell windows ({\tt
transientShellWidgetClass}) have only a thin frame and block all other
\index{Window!Transient Shell Window}
windows. This means that no more events are processed until this
window is closed and the shell widget is destroyed. This is done by
generating the window with the call {\tt Xt\_popup(widget,
XtGrabExklusive)} with the toplevel widget {\tt ui\_toplevel} as the
parent. Some windows, like the file panel, do not block XGUI, because
they are called with {\tt Xt\_popup(widget, XtGrabNone)}. The third
\index{Window!Popup Window}
\index{Window!Top Level Shell Window}
kind of windows are created as a top level shell ({\tt
topLevelShellWidgetClass}) like the manager panel.

Most of the windows (AsciiTextWidget, ToggleWidget, ScrollbarWidget)
have panel items that can be changed by the user. These values are
commonly stored in global variables, to enable other parts of the
program to access them, even after the widget is  destoyed. Some
resources are predefined as so called {\em fallback resources}\/ in
the file  {\tt ui\_main.h}. The bitmaps for the buttons are located in
the directory {\tt iconsXgui} and are linked to the program at compile
time. 

\index{Callback Routine}
A callback routine is called every time a window is destroyed (for
example by clicking {\tt DONE} in popups). This routine takes care
of all necessary actions, before vital information is lost, like
copying the values of  AsciiTextWidgets into global variables. In
addition, there are flags which indicate whether or not a popup is
existing. 

Many panels contain form widgets, where other widgets can be
positioned freely. In XGUI the location of these new widgets is always
relative to the position of already existing widgets. The info panel,
for example, takes the first line as horizontal reference. The change
of widget positions has to be made very carefully, since some widgets
have the same variable\footnote{ Otherways every widget would need its
own local variables} and may not be addressable anymore.

\index{Widget}
{\tolerance=9999
To ease the handling of the widgets some routines are given in the
file {\tt ui\_xWidgets.c}. They allow the creation of Label-,
Ascii\-Text-, Button-, MenuButton-, Toggle- and Scrollbar-Widgets in
a form widget. Three functions return the value of an ascii text
widget as a string ({\tt ui\_xStringFromAsciiWidget}), float ({\tt
ui\_xFloatFromAsciiWidget}) or integer ({\tt
ui\_xIntFromAsciiWidget}). To set the contents of a widget to a
specific value use {\tt ui\_xSetString}, or {\tt ui\_xSetLabel}. To
set/read the state of a toggle use {\tt ui\_xSetToggleState} and {\tt
ui\_xGetToggleState}.\par}

\clearpage

\section{Main Program}
\label{MainProgram}
\index{XGUI!Implementation!Main Program}

The function {\tt main()} in the file {\tt ui\_main\_.c} performs the
initialisation and creates the manager panel. It then passes the
control to X with XtMainLoop(). Here is the pseudo code:

\begin{quote}
{\tt  \begin{verbatim}
Initialize the application;
Initialize the selection list;
Initialize the display list;
Initialize the editor;
Initialize all global variables;
Load default configuration from the file default.cfg;
Create manager panel;
Pass control to X;
\end{verbatim} }
\end{quote}

Loading data from the configuration file changes some global
variables, therefore they must be initialized already. The X event
dispatcher calls the SNNS-XGUI callback routines and event handler
routines.  Actions that affect the network require communication with
the kernel (see also chapter~\ref{InterfaceKernel}). The following
sections describe the reactions of the windows and widgets to
different events.


\section{Manager Panel}
\index{Manager Panel!Implementation}

The manager panel consists of the info panel, a message line and the
XGUI menu. The panel is created at initialization time. The callback
functions in the file {\tt ui\_mainProcs.c} create all the windows and
the procedure {\tt ui\_printMessage()} creates messages in the panel.
SNNS-XGUI is left by pressing the {\tt QUIT} button with the function
{\tt ui\_quit()}.

If multiple displays are used, all status information is best kept in
one window. To display the information in different windows would
waste space on the displays. Therefore this information is collected
in the manager panel.

Functions, which change a value displayed in the manager panel have
to use the routine {\tt ui\_stat\_displayStatus} to updated the panel.
The function {\tt ui\_stat\_displayStatus} displays the other status
information with the help of the variables {\tt
ui\_sel\_\-numberOf\-Selected\-Items}, {\tt ui\_key\_flags}, {\tt
currentLayer} and {\tt ui\_currentDisplayPtr}. The scanning position
is pased on as a parameter. To avoid flickering, this function is
called only when there is a change in information (i.e.\ it
is not called if the mouse is dragged over the display without changing
the scanning position).

Sometimes the displayed attributes have to be checked for validity.
The function {\tt ui\_info\_\-anyUnit\-Selected()} checks whether the
displayed source and target really exist.  The function {\tt
ui\_info\_makeUnit\-InfoPanel\-Consistent()} updates the panel, if units
or sites have been erased. It is also called by several functions of
the action module.

\index{Info Panel!Implementation}
The Info panel is the most complex of SNNS-XGUI\@. To ease access to the
widgets of the source and target units, they are accumulated in
structures ({\tt ui\_targetWidgets, ui\_sourceWidgets,
ui\_linkWidgets}). This was used in programming the routines in {\tt
ui\_infoProcs.c}. Each attribute is also stored in a corresponding
attribute structure ({\tt ui\_targetUnit, ui\_sourceUnit, ui\_link}).


\section{Layer Panel}
\label{Layer}
\index{Setup Panel!Layer Panel Implementation}

The toggle button in the layer panel is initialized with the bits of
the variable {\tt ui\_layer\-Start\-Value}. Bit~0 corresponds to
layer~1, bit~1 to layer~2, etc. Because the layer panel yields a
value, X has to display the panel and allow user input before the
program is continued (just like it was the case with the confirmer).
The result is available in the variable {\tt ui\_layerReturnValue}.


\section{Graphic Windows}
\index{Graphic!Window Implementation}

\index{Event Type}
All data for the graphic windows is stored in a linear linked list.
Valid for all these windows are the following event types: {\tt
GraphicExpose}, {\tt ButtonPress}, {\tt ButtonRelease}, {\tt
KeyPress}, {\tt MotionNotify}, {\tt EnterNotify}, {\tt LeaveNotify},
{\tt MapNotify}, {\tt UnmapNotify}, and {\tt StructureNotify}.

There is no background storage for the graphic output, because it
would be too memory intensive. The drawback is a longer screen setup
time which depends mainly on the number and kind of link options that
are displayed.

\index{Graphic!Context}
For simplicity reasons, all displays use the same graphic context {\tt
ui\_gc} (see \cite{you89}, p. 184 for reference).

\index{Event Handler}
The events for all graphic windows are processed with the three event
handlers {\tt ui\_\-K\-Event()} for {\tt Key\-Press} events, {\tt
ui\_\-can\_\-MW\-Event()} for mouse and window events and {\tt
ui\_\-can\_\-Map\-Event()} for window mapping events. These functions
are installed for each window with {\tt Xt\-Add\-EventHandler}. They
determine in which window the event has occurred. This information is
needed to determine subnet number and grid position because of the
different origins in the various displays.

Input to the windows are all keyboard events, mouse events, and window
events. A window is always active, if it has last sent an {\tt
EnterNotify} event (the mouse has been moved into the window) and is
not closed. Thereby, the editor becomes independent from the windows.

\index{Graphical Output}
The processing of graphical output is more complicated, since some
operations affect only one (e.g.\ a refresh; {\tt UI\_LOCAL}), others
all open windows (e.g.\ a change in the network; {\tt UI\_GLOBAL}). A
simple approach would just draw a new network in every display. This,
however, would take much more time than the solution found in
SNNS-XGUI, where the editor determines whether it is better to re-draw
the whole network or only the updates. This approach leaves some
pixels white on each update, which slowly spoils the picture.

\index{Display!Refresh}
X refreshes the displays with a call to {\tt ui\_refresh} after each
{\tt GraphicExpose} event, if the {\tt count} component of the event
is 0 (see also \cite{you89}, p. 118). This routine is also defined as
a callback function for expose events on the generation of a display.


\subsection{Event Handler for Mouse and Window Events}
\index{Event Handler for Mouse and Window Events}

This function, located in the file {ui\_can\_MWEvent.c}, does the
following: 

\begin{quote}
{\tt \begin{verbatim}
SWITCH (event type)
  ButtonPress:
    get event data;
    SWITCH (mouse button):
      left button:
        remember current first position for selection of area;
        draw selection rectangle;
      middle button:
        remember current position as source unit, if there is
        a unit;
  ButtonRelease:
    get event data;
    SWITCH (mouse button):
      left button:
        delete selection rectangle;
        remember second position for area and normalize both
        coordinates;
        select or unselect area;
      middle button:
        IF info panel created THEN
          show this unit as target and remembered 
          unit as source;
      right button:
        IF empty position THEN
           unselect all (in this subnet)
        ELSE
           unselect this single unit
  EnterNotify (mouse is moved into a graphic window):
    set this window as actual and show new status;
  MouseMoves (mouse is moved):
    show new status, if new grid position reached;
  MouseDragg (mouse is moved with at least one button down):
    if the left button is pressed, delete old selection box, 
    draw a new one.
save position of the event in the global variables
ui_pixPosOld and ui_gridPosOld;
\end{verbatim} }
\end{quote}

The actions to these events are defined in this function. The results
affect the info panel and the status panel.

\clearpage

\subsection{Event Handler for Keyboard Events}
\index{Event Handler for Keyboard Events} 

This function, in the file {\tt ui\_KEvent.c}, is implemented as a big
SWITCH statement. It represents an automaton for the recognition of
editor commands. The transition from one state to the following state
(stored in the global variable {\tt ui\_key\_currentState}) is
performed at the next call to the function. Depending upon the
selected mode (normal, {\tt Mode Units}, {\tt Mode Links}), the
following state is stored in one of the global variables {\tt
ui\_key\_returnUnitState} or {\tt ui\_key\_returnLinkState}. This
means that the automata changes its behaviour according to these
two variables.

On {\tt Units Move/Copy} the user is expected to click on a target
position. In the meantime the automata is on hold ({\tt
UI\_STATE\_GETDEST}), and signals this to the event handler for mouse
and window events in the global varaible {\tt ui\_outlineActiv}. When
the target is defined, this event handler defines the next state of
the automata.

Some actions ask the user for a value in a popup window. Since this
blocks SNNS-XGUI as a whole (with {\tt XtPopup(widget,
XtGrabExclusive)}), no additional steps have to be taken.


\subsection{Editor Actions}
\index{Editor!Actions Implementation}

The file  {\tt ui\_action.c} contains all editor operations that are
called exclusively by the event handlers for keyboard and pointer
events. The basic structures of the functions that process selected
units look very much alike. The concept is the following:


\begin{quote}
{\tt
\begin{verbatim}
IF operation can not be performed THEN
  error message;
  return;

delete marks of all selected units;
WHILE there is a selected unit DO
 IF desired operation for this unit can be  performed THEN
   execute operation;
   change graphic if necessary;
 ELSE
   report (if desired)
END WHILE
keep graphic and values in info panel consistent;
Redraw marks for selected units;
\end{verbatim}
}
\end{quote}

To perform the actions {\tt Units Copy} and {\tt Units Move}, it first
has to be checked, whether all target positions in the grid are
available for the operation. Therefore, the function {\tt
ui\_action\_checkNewPositions()} checks, whether the target position is
empty for {\tt UI\_ACTION\_COPY}, or occupied by unselected
units for {\tt UI\_ACTION\_MOVE}. The whole operation is skipped if an
error condition results from the check.

After links or units have been deleted, it is possible that
information in the info panel has become invalid. A call to {\tt
ui\_info\_makeInfoPanelConsistent()} assures consistency in that
panel.

Often it is necessary to reiterate the list of selected units within
the while-loop (e.g.\ the function {\tt ui\_action\_linksMakeClique()}
generates connections between all selected units). In that case, a
second while-loop is used that traverses the selection list, either
from the start, or from the current element.


\subsection{Setup Panel}
\index{Setup Panel!Implementation}

All setup data is contained in a structure ({\tt struct
SetupDataType}) which is itself contained in a display structure.

\begin{quote}
{\tt
\begin{verbatim}
typedef struct SetupDataType {
    Bool          showValueFlg;
    Bool          showValue;
    Bool          showTitleFlg;
    Bool          showTitle;
    Bool          showLinkFlg;
    Bool          showDirectionFlg;
    Bool          showWeightFlg;
    FlintType     linkPosTrigger, linkNegTrigger;
    FlintType     unitScaleFactor;
};
\end{verbatim}
}
\end{quote}


When the setup panel is opened, the corresponding display is current.
Therefore all changes are performed in the current display {\tt
ui\_currentDisplayPtr}, and all inital data is read there. If
a scrollbar is manipulated, the callback function {\tt ui\_thumbed()}
is called to save the value in the corresponding global variable. To
set the values of {\tt showValue} and {\tt showTitle}, there are two
callback functions that assign the value to the parameter {\tt
client\_data} in each menu option. The layer value is determined by
the common method of the layer popup.

The toggles, that switch the various display options on and off call
the function  {\tt ui\_set\_\-toggle\-Values()}. This function sets the
corresponding component of the setup variables in the current graphic
window. 
\index{Setup Panel!Setup Variable}

\begin{itemize}
\item {\tt showValueFlg}: If this flag is set, the value that
determines the size of the unit is numerically displayed below it. 

\item {\tt showValue}: This number gives the displayed value and can
be one of the following: {\tt UI\_ACTIVATION}, {\tt UI\_OUTPUT}, {\tt
UI\_INITIAL\_ACTIVATION} oder {\tt UI\_BIAS}.

\item {\tt showTitleFlg}: States whether or not the unit title should
be given.

 \item {\tt showTitle}: States whether the unit number ({\tt
UI\_\-NUMBER}), or the unit name ({\tt UI\_\-NAME}) will be the title.

\item {\tt showLinkFlg}: Links are displayed only if this flag is set.

\item {\tt showDirectionFlg}: If this flag is set, the connections
will be displayed as arrows.

\item {\tt showWeightFlg}: States, whether the link weights are
displayed.

\item {\tt linkPosTrigger} and {\tt linkNegTrigger}: For positive and
negative weights, these flags hold the threshold for drawing links.

\item {\tt unitScaleFactor}: If the activation of a unit is above this
limit it is displayed with maximum extension.

\end{itemize}

When the  {\tt DONE} button is pressed, the setup panel becomes
invisible again. The new grid size and origin are read from the panel,
and the graphic window is redrawn. There the new parameters are used,
and the desired picture is created.


\subsection{Freezing Displays}
\index{Freezing Displays}

The {\tt FREEZE} button flips a switch in the display structure which
prevents the high level display routines from affecting this window.
The call {\tt ui\_netCompleteRefresh(UI\_LOCAL)}, necessary after a
GraphicExpose event, is the only one that changes a frozen display.


\section{List Module}
\index{List Module}

\index{Panel!Construction}
The construction of a panel with a list widget is a separate module.
These panels are used to select functions, IO-types and F-types. There
are only three functions which must react to the various lists in a
specific way: {\tt ui\_list\_getFirstItem()} yields the first element
of the list, {\tt ui\_list\_getNextItem()} the rest, and {\tt
ui\_list\_setValue} handles the result. Depending upon the type of the
list, the result is either written to the appropriate place in the
panel (source unit or target unit), or put into the global variable {\tt
ui\_list\_returnName}. In any case, the variable {\tt
ui\_list\_returnIndex} contains the list index used last. The list is
constructed with {\tt ui\_list\_buildList(parentWidget, type)}, where
{\tt type} can have one of the following values:


\begin{center}
\begin{tabular}{|l|l|}
\hline
Type & Meaning\\
\hline
{\tt UI\_LIST\_IOTYPE} & all IO-types\\
{\tt UI\_LIST\_FTYPE} & all defined f-types\\
{\tt UI\_LIST\_FTYPE\_NAME} & ditto (edit f-type)\\
{\tt UI\_LIST\_ACT\_FUNC} & all activation functions\\
{\tt UI\_LIST\_FTYPE\_ACT\_FUNC} & ditto (edit F-Typ)\\
{\tt UI\_LIST\_OUT\_FUNC} & all output functions\\
{\tt UI\_LIST\_FTYPE\_OUT\_FUNC} & ditto (edit F-Typ)\\
{\tt UI\_LIST\_SITE\_FUNC} & all site functions\\
{\tt UI\_LIST\_SITE} & all defined sites\\
{\tt UI\_LIST\_FTYPE\_SITE} & all sites on the current F-Typ\\
{\tt UI\_LIST\_UNIT\_SITE} & all sites at the current unit\\
{\tt UI\_LIST\_LEARN\_FUNC} & all teaching functions\\
\hline
\end{tabular}
\end{center}


\section{File Panel}
\index{File Browser Panel!Implementation}

After clicking {\tt DONE}, the directory and the four file names are
copied from the Ascii\-Text\-Widgets ({\tt ui\_path}, {\tt
ui\_fileNET}, {\tt ui\_filePAT}, {\tt ui\_fileCFG}, {\tt ui\_fileTXT})
into the corresponding global variables ({\tt ui\_pathname}, {\tt
ui\_filenameNET}, {\tt ui\_filenamePAT}, {\tt ui\_file\-name\-CFG},
{\tt ui\_filenameTXT}).

The file {\tt ui\_fileProcs.c} contains the functions for loading and
saving of nets, patterns, configurations and texts. The structure of
these functions is:

\begin{quote}
{\tt
\begin{verbatim}
PROCEDURE save;
IF a file with this name already exists THEN
  IF User allows overwrite THEN
   save;
  ELSE
   abort and message;
END;

PROCEDURE load;
IF a file with this name already exists THEN
  load;
  IF error THEN message;
END;
\end{verbatim}
}
\end{quote}
\index{File Panel Procedure load}


\section{Help Window}
\index{Help!Window!Implementation}

The callback function {\tt ui\_help\_searchText} is called by clicking
one of the buttons {\tt MORE}, {\tt LOOK} or {\tt TOPICS} with a
flag as {\tt client\_data}. On clicking {\tt LOOK} or {\tt
MORE} the string is read from the X primary section, and the help text
is searched for this string from the beginning. On clicking
{\tt TOPICS} the string  {\tt \verb*@* TOPICS@} is searched.


\section{Confirmer}
\index{Confirmer!Implementation}

The file {\tt ui\_confirmer.c} consists mainly of the functions listed
in \cite{sun86}, p.  348 ff (prefix {\tt ui\_cf\_}) for the
construction of a confirmer package adapted to X windows. This package
was enhanced only for the functions {\tt ui\_confirmOk()} and {\tt
ui\_confirmYes()} to highlight the calls to the confirmer in the
source code. Additionally an icon ({\tt STOP} or exclamation mark) is
displayed in the confirmer.

\index{Main Loop Interuption}
The intrinsics of X don't allow an interuption of
XtAppMainLoop(). Therefore, a temporary event dispatch loop has to be
programmed (see below). This loop is exited when a button in the
confirmer is pressed, whose callback routine changes the variable {\tt
ui\_cf\_exit} to {\tt TRUE}. Since XtGrabExklusive is set and the XGUI
toplevel widget {\tt ui\_toplevel} is the parent of the confirmer, it
blocks all events for SNNS-XGUI until it is destroyed.


\begin{quote}
{\tt
\begin{verbatim}
ui_cf_exit = FALSE;
while (NOT ui_cf_exit) {
    XtAppNextEvent(ui_appContext, &event);
    (void) XtDispatchEvent(&event);
}
\end{verbatim}
}
\end{quote}


\section{Graphic}
\index{Graphic!Module}

The graphic module consists of three levels: The first level is
responsible for drawing the network as a whole. The middle level draws
or delets single network elements. This level uses graphic primitives
of the lowest level, which make up the X graphic interface, as well as
basic Xlib output functions for graphics and text.

\index{Drawing Function}
The file {\tt ui\_netUpdate.c} contains the functions for drawing
the whole net (prefix {\tt ui\_net\_}). All routines in this module
determine in which of the open displays to draw. Iconified or frozen displays
are ignored. Depending upon parameters, the function {\tt
ui\_\-net\_\-up\-date\-Whole\-Net()} draws either all links or all units. For a
complete update of the net use the function {\tt
ui\_net\_completeRefresh()}. This function first clears the window,
then draws the links and finally the units.

The file {\tt ui\_netGraph.c} contains the functions for drawing
network elements ({\tt ui\_\-draw\-Unit()}, {\tt ui\_\-draw\-Link()}).
Two switches are important, one to determine whether to draw or delete
the element ({\tt UI\_\-ERASE} or {\tt UI\_DRAW}), and one to
determine whether to do the output globally ({\tt UI\_GLOBAL}) or only
in the current window ({\tt UI\_LOCAL}). Units are drawn if the subnet
number is the same as in the window, at least one layer of the unit is
activated in the window, and the display is neither frozen nor
iconified. Links are drawn if the corresponding units are visible,
have the same subnet number, and have a weight that exceeds the
threshold set by the trigger sliders in the setup panel.

\index{Grid!Coordinates Computation} 
Functions to compute grid coordinates from pixel coordinates and vice
versa are located in the file {\tt ui\_utilProcs.c}. Normalizing
\index{Graphic!Normalizing Function}
functions are also located here. Normalization of edges of a rectangle
here means exchanging the coordinates, if necessary, to place the
first edge to the left and above the second ({\tt
ui\_normalize\_rect()}). A normalization with {\tt
ui\_normalize\_coord()} only puts the first coordinate left of the
second.

All functions which call X graphic routines are kept in the file {\tt
ui\_xGraphic.c}. Among them is a function for drawing an arrow ({\tt
ui\_xDrawArrow()}), a function for drawing a box ({\tt
ui\_xDrawBox()}),as well as a function to delete a black or white
rectangle ({\tt ui\_xDelete\-Rect()}).  To generate an arrow head, a
triangle is rotated appropriately (see also the algorithm in
\cite{har83}).


\section{Selection Mechanism}
\label{SelectionMech}
\index{Selection Mechanism}

All functions and global variables dealing with the selection
mechanism have the prefix {\tt ui\_sel\_}. All selected units are held
in a linear linked list starting at the pointer {\tt
ui\_sel\_listPtr}. It is set to point to an element on initialization.
The number of selected units is stored in the globale variable {\tt
ui\_sel\_numberOfSelectedItems}. The total number of allocated items
is kept in {\tt ui\_sel\_numberOfItems}.  This list is always
increasing, i.e.\ memory is not freed by {\tt dispose()}, but all
unused elements are kept in the list, marked as such (Bit 0 in the
component {\tt flags}), and are used again when needed. New elements
are attached at the beginning of the list.

\begin{quote}
{\tt
\begin{verbatim}
typedef struct SelectionType {
    struct SelectionType     *nextPtr;
    struct PosType           gridPos;  
    int                      subNetNo;
    int                      unitNo;   
    int                      copyNo;   
    int                      flags;
}; 
\end{verbatim}
}
\end{quote}

For an unambiguous identification of the units, their subnet number is
stored in addition to their grid position. This is necessary, since
units in different subnets may have the same grid positions. On
processing the action {\tt Units Copy Structure} the unit number is
saved, in order to keep track of the units during the copying process.
After completion of the action, the component is superfluous.
Table~\ref{TabSelektionBits} gives the meaning of the bits in the
component {\tt flags}.

\begin{table}
\begin{center}
\begin{tabular}{|l|l|}
\hline
 bit  0 & selected, if set\\
 bit  1 & failure of last action on this unit; not used\\
 bit  3 & action UNITS MOVE: Unit was already moved\\
 bit  4 & action LINKS INVERSE: Links were already turned\\
\hline 
\end{tabular}
\end{center}
\caption{Meaning of the Bits in the flag item of each list element for
the selection.}
\label{TabSelektionBits}
\end{table}


When several windows are used, units can be selected in multiple
windows. The case of one unit being displayed in more than one window
has to be observed. SNNS-XGUI therefore allows selection only of units
belonging to an active layer, and at least one window with the same
subnet number must be open. If a unit is selected in one window, the
selection mark becomes visible in all displays.

When a unit is marked selected, a cross is drawn over the unit. It has
to be assured that prior to drawing or deleting, all marks are reset,
and get updated afterwards with the function {\tt
ui\_sel\_reshowItems}.  All editor functions dealing with moving or
deleting units ( prefix "`{\tt ui\_action\_}"'), have to assure
consistency of the selection list.  This can be done by changing the
flag, since these functions anyway have access to this element, when
they process the selected unit.



\section{Interface to the Simulator Kernel}
\label{InterfaceKernel}
\index{Interface Function}

The simulator kernel of SNNS offers a set of interface functions (see
also chapter~\ref{KernelFunctionInterface}) which allow a one way
communication with the graphic routines. There the graphical user
interface acts as the master, the kernel as the slave. The functions
can be assigned to the following tasks:

\begin{itemize} 
\item read and set unit, site, and link attributes and functions
\item administer f-types and sites
\item change the network topology
\item load and save networks and patterns
\item simulator functions: update, teaching
\end{itemize} 

The keys to all operations of the user interface (like adding or
deleting units or links, changing attributes etc.) are always the unit
number and the unit position. Therefore these two attributes always
have to be unambiguous. On dealing directly with the unit numbers
great caution is needed, since the kernel compresses its data
structures during a save, thereby changing the unit numbers. The
access via unit number, however, is much faster than via position,
because a sequential search can be avoided that way.

The search is necessary, however, when the user interface has to
process an event (ButtonPress, ButtonRelease, KeyPress, \ldots) which
has occured in a window. A possible improvement would be an additional
data structure which sorts all units by their grid positions. A linear
linked list could, for example, be assigned to each row of the grid.
The search time is then limited by the maximum number of units in a
row. Unfortunately, for small nets the longer time to build up the
display might outweigh the faster access time. In very large nets this
mechanism could be a real improvement.

To increase the stability of the simulator, the current version always
requests its data from the kernel (and not from global variables) in
all situations where consistency is important. There are also data
consistency checks contained in the code, before any change on the net
is performed. This does not decrease system performance, since these
requests are answered very fast by the kernel.

The type {\tt bool}, used by all boolean functions of the kernel, is
identical with the type {\tt Bool}, used by all SNNS-XGUI functions.
The type {\tt Bool} is used by X windows and therefore is also used
in the user interface. 


\begin{quote} 
{\tt
\begin{verbatim}
typedef int Bool; \* User Interface *\
typedef int bool; \* Kernel *\
\end{verbatim}
}
\end{quote} 

All functions in this interface have the prefix "`{\tt krui\_}"', to
be able to identify the functions in this module. They are a part of
the kernel functions.

More detailed information about the interface between XGUI and the
kernel can be found in chapter~\ref{KernelFunctionInterface} or in the
source files {\tt krui\_typ.h} and {\tt glob\_typ.h} of the kernel.
Modules of the user interface which use kernel functions must
include the file {\tt kr\_ui.h}.
