TCA UTILITY LIBRARIES
=====================

We currently supply two libraries of utilities, devUtils and ezx.

DevUtils
--------

The device utilities library provides methods for creating and managing
interfaces to hardware devices and other "IO" devices like X11, TCA and
stdin.  It provides more robust error and interrupt handling to improve
the robustness of your TCA programs.

Most event driven programs, such as TCA programs, are written around a
main event loop.  Both TCA and X11 provide main event loops, as well as
functions for handling single events.  Most main event loops are created
using a "select" call with a timeout.  There are three ways to integrate
TCA and X11 into an event loop.  The program can have its own "home
grown" event loop that calls the appropriate TCA and X11 routines.  The
X11 main event loop can be used, with the TCA inputs added as extra
inputs with their own handlers, or the device utils main event loop can
be used.  The advantage of using the devUtils loop is that it is better
able to deal with exceptions and broken pipes.  It also has per device
timers and supports polling and simple data parsing.  Examples of how to
use each type of event loop can be found in the tutorial/simulator
directory.  sim.c pro

Below is a description of the Main functions in the devUtils library.
The general way to use the library is to create some devices, connect
them and then call the devMainLoop.

devCreateDev: Create a device data structure and initialize it.
The first parameter is a string that gives the name of the device.
This is followed by a variable length list of parameter name, 
parameter value pairs.  The list is terminated with a NULL parameter.
For example myDev = devCreateDev("myDev" DEV_OUTPUTHND, myOutputHnd, NULL);
Unset parameters are the to their defaults, usually NULL.

DEV_PTR devCreateDev(const char *name, ...);

devCreateTTYDev: Same as devCreateDev, except that the defaults are set
for a device that opens a tty port for I/O.

DEV_PTR devCreateTTYDev(const char *name, ...);

devSetParameters: Set parameters for a device.
The first parameter is the device data structure.
This is followed by a variable length list of parameter name, 
parameter value pairs.  The list is terminated with a NULL parameter.
For example devSetParameters(myDev DEV_OUTPUTHND, myOutputHnd, NULL);
Unset parameters are left unchanged.

void devSetParameters(DEV_PTR device, ...);

devSetParameter: Set a parameter for a device.
The first parameter is the device data structure.
This is followed by a parameter name, 
parameter value pair.
For example devSetParameter(myDev DEV_OUTPUTHND, myOutputHnd);
Unset parameters are left unchanged.

void devSetParameter(DEV_PTR device, DEV_PARAM_TYPE param, void *value);

functions for setting the parameter values one at at time.

void devSetUseSimulator(DEV_PTR device, BOOLEAN useSim);
void devSetSimMachine(DEV_PTR device, const char *machine);
void devSetPort(DEV_PTR device, int port);
void devSetBaudRate(DEV_PTR device, int baudRate);
void devSetListening(DEV_PTR device, LISTENING_TYPE listen);
void devSetDebug(DEV_PTR device, BOOLEAN debug);
void devSetDebugFile(DEV_PTR device, FILE *);
void devSetOutputHnd(DEV_PTR device, DEVICE_OUTPUT_HND hnd);
void devSetSignalHnd(DEV_PTR device, void (* hnd)(DEV_PTR));
void devSetDisconnectHnd(DEV_PTR device, void (* hnd)(DEV_PTR));
void devSetReconnectHnd(DEV_PTR device, void (* hnd)(DEV_PTR));

functions for getting the parameter values one at at time.

const char *devGetName(DEV_PTR device);
fd_set *devGetFds(DEV_PTR device);
BOOLEAN devGetUseSimulator(DEV_PTR device);
const char *devGetSimMachine(DEV_PTR device);
int devGetPort(DEV_PTR device);
int devGetBaudRate(DEV_PTR device);
LISTENING_TYPE devGetListening(DEV_PTR device);
BOOLEAN devGetDebug(DEV_PTR device);
FILE *devGetDebugFile(DEV_PTR device);
DEVICE_OUTPUT_HND devGetOutputHnd(DEV_PTR device);
DEVICE_HANDLER devGetSignalHnd(DEV_PTR device);
DEVICE_HANDLER devGetDisconnectHnd(DEV_PTR device);
DEVICE_HANDLER devGetReconnectHnd(DEV_PTR device);

devConnect: connect the device according the the parameter settings.

void devConnect(DEV_PTR device);

devMainLoop: Loop for ever processing events and dispatching them to the 
correct handlers for each device.

void devMainLoop(void);

ProcessDevices: Process events for up to maxTime time.
If the timeout is NULL, the maximum time to process is infinite.
Note that this function will return after 1 or more events have been 
processed, even if the max allowed time has not elapsed. 

void devProcessDevices(struct timeval *maxTime);

devStartPolling: call the polling routine every interval usecs.  Note that 
because the operating system is not a real time system, the delay in 
calling the polling routine maybe arbitrarily long.

void devStartPolling(DEV_PTR dev,
		     struct timeval *interval,
		     Handler handler, void *data);

devStopPolling: stop calling the polling routine.

void devStopPolling(DEV_PTR dev);

devIsPolling: Returns true if the device is being polled.

BOOLEAN devIsPolling(DEV_PTR dev);

setTimeout: Set an alarm to go off at a specific time.  
The handler function is called if the alarm goes off.

void devSetAlarm(DEV_PTR dev, struct timeval *timeoutTime,
		 Handler timeoutHnd, void *data);

setTimer: Set an alarm to go off at a delay time from now.
The handler function is called if the alarm goes off.

void devSetTimer(DEV_PTR dev, struct timeval *delay,
		 Handler timeoutHnd, void *data);

cancelTimeout: remove a timeout set either with setTimeout or setTimer.

void devCancelTimeout(DEV_PTR dev);

Routines for parsing characters from a device.

LINE_BUFFER_POINTER: private structure used to keep track of partial lines
and other parsing information.

typedef struct _dev_line_buffer_type *DEV_LINE_BUFFER_PTR;

createLineBuffer: Create a data structure to keep track of information
needed to parse output from a device and dispatch it to a routine for 
processing.  This handles partial lines and more than one line ready for
input.  The parameters specify how to recognize a "line"
processRoutine: function to call when a complete line is recognized.
lineLimit: maximum number of characters that can be in a line.
           For fixed length lines, set this to the expected length.
delimChar: Characters that delimit the end of the line.  
           If any character in this string is found it the input, it is 
           taken to be the end of the line.
replaceDelimit: Should the delimit character be replaced with '\0' before
                the parse routine is called?
partialLines: Should incomplete lines also be passed to the parser.

DEV_LINE_BUFFER_PTR devCreateLineBuffer(int lineLimit, char *delimChar,
					void (*processRoutine)(char *, void *),
					BOOLEAN replaceDelimit,
					BOOLEAN partialLines,
					void *clientData);

processOutput: routine to read characters from the device, parse the 
input and call the parse routine.

void devProcessOutput(DEV_PTR device, int fd, DEV_LINE_BUFFER_PTR lineBuffer, 
		      int chars_available);

WaitForResponse: Process events and wait for some event that sets the 
doneFlage.  If timeout time expires first, the return false.

BOOLEAN devWaitForResponse(DEV_PTR dev, int *doneFlag, long timeout);

#define devExitFromWait(doneFlag) doneFlag = NOT_WAITING;

devShutDown: shutdown all devices.

void devShutdown(void);

I/O functions.

writeN : Write n characters from a buffer to a given device.
Handle pipe brakes and interrupted system calls.

BOOLEAN devWriteN(int fd, const char *buf, int nChars);

readN: Read nchars of data from sd into buf. Continue to read until
nchars have been read.  Return 0 if end of file reached and -1 if
there was an error.  Handle pipe breaks.

int devReadN(DEV_PTR dev, int fd, char *buf, int nchars);

devCharsAvailable : Find out how many characters are available to be read.

long devCharsAvailable(int sd);

flushChars: Flush any characters from the input file descriptor.

void devFlushChars(DEV_PTR dev);

EZX
---
EZX is a wrapper to help create X11 interfaces.  It takes care of
initializing the X11 graphics environment and provides methods for
handling x11 events.

More documentation is still needed for these libraries.  
