ToolLib -- Library of routines useful when writing APW shell utilities

ToolLib is a library of routines that may be useful in your efforts to produce
APW shell utilities.  There are four families of routines in the library -
spinning cursor, error message management, class 1 string conversion, and
keyboard scanning.  Each routine within each family will be described.


Accessing the routines - Pascal
-------------------------------

To access any of the library routines from within a Pascal program, you must
first determine how your Pascal compiler is able to use any externally defined
routines.  Usually this is done with the use of a 'Uses' statement.  A sample
interface file is supplied in the PIncludes directory of the Libraries
directory on the disk.  This file may need to be modified for use with your
particular compiler.  (Since I don't normally use Pascal, I'll leave it up to
you to set things up correctly.  After all, what d'ya expect for free???) ;-)


Accessing the routines - C
--------------------------

To access any of the library routines from within a C program, you must
#include <ToolLib.h> to notify the compiler of the correct calling conventions
for the routines.

When linking your program together, include '-lib 2/ToolLib' in your LinkIIGS
command line.


Spinning Cursor routines
========================

Five procedures in the library let you control the appearance and action of the
spinning cursor.  The rotating bar says "I am currently processing."  These
routines all use Pascal calling conventions and Pascal-style strings.


The InitCursorCtl procedure
---------------------------

The InitCursorCtl procedure initializes the CursorCtl unit.  Call this
procedure once prior to calling the RotateCursor or SpinCursor procedures
described later.  Note that InitCursorCtl doesn't need to be called if you use
only Hide_Cursor and Show_Cursor.  If RotateCursor or SpinCursor are called
prior to InitCursorCtl being called, they will call InitCursorCtl themselves.

If the parameter 'delaycount' is 0, InitCursorCtl sets a default delaycount of
32.  This delaycount is used to determine when to update the rotating bar image
on the screen.  The lower the number, the quicker the spin will be.  (The
reason that the 'delaycount' parameter must be a 32-bit value is to make it
easier to port MPW-style tools to the APW environment.  Under MPW, this value
is a handle of an 'acur' resource, hence the 32-bit width.)

InitCursorCtl initializes data structures and variables, and then exits by
calling Show_Cursor to display the first character in the rotating cursor
sequence.

-> Pascal:
    Procedure InitCursorCtl(delayCount : LongInt);

-> C:
    pascal void InitCursorCtl(delayCount)
    long    delayCount;


The Show_Cursor procedure
-------------------------

This function removes the default inverse space cursor from the screen and
replaces it with the first frame of the animated cursor.  It then outputs a
backspace so that any subsequent characters will automatically overwrite
the cursor character.

-> Pascal:
    Procedure Show_Cursor;

-> C:
    pascal void Show_Cursor()


The RotateCursor procedure
--------------------------

RotateCursor is called to rotate the "I am active" "spinning wheel" cursor.
The next cursor ("frame") is used when (counter MOD delaycount) (as
specified in the InitCursorCtl call) = 0 (counter is some kind of
incrementing or decrementing index maintained by the caller).  A positive
counter sequences forward through the cursors (e.g., it rotates the cursor
"clockwise"), and a negative cursor sequences through the cursors backwards
(e.g., it rotates the cursor counterclockwise).

-> Pascal:
    Procedure RotateCursor(Counter : LongInt);

-> C:
    pascal void RotateCursor(counter)
    unsigned long   counter;


The SpinCursor procedure
------------------------

SpinCursor is similar in function to RotateCursor, except that instead of
passing a counter, an increment is passed and added to a counter maintained
within the CursorCtl unit itself. SpinCursor is provided for those users who
do not happen to have a convenient counter handy but still want to use the
spinning cursor.  A positive increment sequences forward through the cursors
(rotating the cursor clockwise), and a negative increment sequences backward
through the cursors (rotating the cursor counterclockwise).  A zero value for
the increment resets the counter to zero. Note, it is the sign of the
increment, and not the sign of the counter that determines the sequencing
direction of the cursor (and hence the spin direction of the cursor).

-> Pascal:
    Procedure SpinCursor(Increment : Integer);

-> C:
    pascal void SpinCursor(increment)
    unsigned short  increment;


The Hide_Cursor procedure
-------------------------

Hides the current character of the spinning cursor.  Use this routine when
you wish to revert to the standard inverse space cursor.

-> Pascal:
    Procedure Hide_Cursor;

-> C:
    pascal void Hide_Cursor()


Error Message File Manager
==========================

Three procedures in the library let you retrieve the text of error messages in
the SysErrs file (located in the 4/ directory of your APW development
environment).


The InitErrMgr procedure
------------------------

Initializes the error manager.  If toolErrFilename is not null, this will
open the resource fork of that file to allow access to tool-specific error
messages.  If sysErrFilename is not null, this will open the resource fork
of that file instead of the standard APW error message file. If
showToolErrNbrs is TRUE, then any call to GetSysErrText will show the
decimal and hexadecimal error number in parentheses after the text of the
error message.  If this is false, all that GetSysErrText will provide is
the text of the message.
    
To use the error manager, your tool must start up the Resource Manager
prior to calling InitErrMgr.  This function will NOT do it for you.

-> Pascal:
    Procedure InitErrMgr(toolErrFilename, sysErrFilename : Str255;
                         showToolErrMbrs : Boolean);

-> C:
    void InitErrMgr(toolErrFilename, sysErrFilename, showToolErrNbrs);
    char    *toolErrFilename;
    char    *sysErrFilename;
    boolean showToolErrNbrs;


The CloseErrMgr procedure
-------------------------
This simply closes any resources files opened by InitErrMgr.  It is not
absolutely required that you call this function prior to exiting your tool,
but it is available.  If it is not called, the Resource Manager will
automatically close any files opened.  You must shutdown the Resource
Manager yourself.

-> Pascal:
    Procedure CloseErrMgr;

-> C:
    extern void CloseErrMgr()


The GetSysErrText procedure
---------------------------

GetSysErrText performs a resource lookup for the supplied errNbr.  It does
this by calculating which resource number to use from the system resource
file or the tool-specific error file.

The function places the error message text in the buffer pointed to by
errMsg.  The C version also returns a pointer to a standard C string
representing the error message associated with the given error number.  If
there is message text available for the given error number, the string will
have the following format:

    ### {tool name}: {message text}
    
If no specific message is available, the string will have the following
format:

    ### {tool name}: Error {decimal error number} ($xxxx)

where $xxxx is the hexadecimal error code.

-> Pascal:
    Procedure GetSysErrText(errNbr : Integer; errMsg : StringPtr);

-> C:
    char *GetSysErrText(errNbr,errMsg)
    unsigned    errNbr;
    StringPtr   errMsg;


GS/OS Class 1 string conversion procedures
==========================================

The library contains two routines that convert between GS/OS class 1 strings
and C strings, and one routine use to convert slashes within a pathname to
colons.  These will probably be more useful to C programmers, but they
are also available to Pascal programmers who desire to use them.  These
routines will only be known to the compiler if the file GSOS.h is included
prior to including ToolLib.h (actually, the macro __GSOS__ must be defined
prior to including ToolLib.h, to ensure that the type GSString255 has been
defined).


The c2gsstr procedure
---------------------

This function accepts a null terminated C string and copies it to a
GS/OS-style string (length word followed by the characters of the string).
On return, the function returns the pointer to the pathname structure.

-> C:
    extern GSString255 *c2gsstr(str, pathGS)
    char        *str;
    GSString255 *pathGS;


The gs2cstr procedure
---------------------

This function converts a GS/OS-style string (word length followed by the
characters of the string) to a normal, null terminated C string.  On exit
it returns a pointer to the string (which is the same as that specified
on entry).

-> C:
    extern char *gs2cstr(pathGS, str)
    GSString255 pathGS;
    char        *str;


The colonize procedure
----------------------

Normalizes a filename string so that it contains only colons as pathname
separators.  If there are no separators in the filename, the name is left
unchanged.  If the filename contains no slashes, the filename is left
unchanged.

-> C:
    extern void colonize(fileName)
    char    *fileName;


Keyboard scanning routines
==========================

The keyboard scanning routines can be used to test for a Command-. keypress,
and to automatically handle a spacebar press (used to pause the output of a
utility).


The pause function
------------------

This function should be called periodically by an APW tool to check for
a pending keypress and/or command-. (abort signal).  If the command-.
keypress is pending, the function will return a non-zero value
(signifying TRUE).  If any other keypress is pending, the function
will display an hourglass character on the screen and pause until
another key is pressed.
    
The value returned is either non-zero (TRUE), indicating that command-.
has been pressed and the tool should abort, or 0 (false), indicating
that processing should proceed.

-> Pascal:
    Function Pause : Boolean;

-> C:
    extern int pause()


The Wait function
-----------------

This function operates similarly to the pause() function, except that
it forces a keypress prior to returning to the caller.  That is, it
waits in a loop until a keypress occurs.  The values returned are the 
same as described for the pause() function.

-> Pascal:
    Function Wait : Boolean;

-> C:
    extern int wait()
