
                        ===================
                          RawIN.lib V1.00
                           Documentation
                         - June 13, 1992 -
                        ===================


        Copyright (c) 1992 by Sam Yee.  All rights reserved.



=====================================================================
COPYRIGHT
=========

The link-time library RawIN.lib and its documentation are written and
copyrighted by Sam Yee.  They may be distributed freely providing the
following restrictions are satisfied:

o Distributors may not charge more than the cost of a diskette used
  for the distribution of this library.

o Distributors may only distribute the unmodified copy of the
  original library, along with its documentation, and copyright
  notices intact.

o This program is not to be used for commercial purposes unless, a
  copy of the final release is mailed to me, along with any major
  updates that still use the RawIN.lib file.


=====================================================================
DISCLAIMER
==========

This library and the test program and its documentation is provided
"as is".  No warranties are made with respect to the accuracy,
reliability, performance or operation of this software and
information.  You are using this program at your own risk.  The
author is not liable for any damages that may have been caused by
using this software.


=====================================================================
INTRODUCTION
============

Have you ever wanted to write a program that runs in the CLI, taking
input from the user and at the same time checking for other things,
like signals and messages from other processes?  You found out that
you couldn't use AmigaDOS's Read() function or C's built-in input
functions, like scanf(), or getchar() to get the job done.  Some of
you may have tried using the WaitForChar() function in conjunction
with the Read() function, but reading a line cannot be completed
until the user presses the carriage return.  I have writen numerous
utilities for bulletin board systems (BBSs) and have found that using
Read() or other synchronous input functions are inappropriate for
such applications.  These synchronous functions do not return until
they accomplish their tasks.  For example, if you send a break signal
to a process to tell it to quit, and this process is getting input
from the user, the program would not exit until the user has pressed
a carriage return.  This is a big problem if the BBS is attempting to
terminate a user who is running this program and whose time has
expired.  This is where RawIN.lib comes in.  It allows you to get
input from the user and at the same time check for other special
events (such as abort signals).  It also provides a set of command
history routines.  A synchronous version of the input routine is also
provided, and it's called RawGets().  Finally, RawIN.lib provides
functions to handle single character input much like in a RAW:
window.


=====================================================================
USER MANUAL
===========

Read the RawINTest.c file to get a better idea of how most of the
following functions work together.  You should put RawIN.lib into the
directory where your other link-time libraries are.  If you are using
SAS/C, you can link the library with the following command line
arguments:

blink lib:c.o,prog.o to prog lib lib:RawIN.lib,lib:lc.lib,lib:amiga.lib

The autodocs is as follows.
---------------------------------------------------------------------

NAME
    AbortRead -- Abort a read packet.

SYNOPSIS
    void AbortRead(port);

    struct MsgPort *port;

FUNCTIONS
    Attempt to abort a read packet.  Up to date there is no safe way
    to abort a packet, with or without system calls.  This function
    is included for compatibility with future versions of the library
    only.  This function does not exit until the read you started
    with StartAsyncRead() (look below) is completed.  Do not call
    this routine if there are no reads pending.

INPUT
    port = The same message port you supplied to StartAsyncRead.

SEE ALSO
    StartAsyncread

---------------------------------------------------------------------

NAME
    AllocLine -- Allocate a line structure to be used for raw input.

SYNOPSIS
    line = AllocLine(buf_size,hist_size)

    struct Line *line;
    ULONG buf_size;
    ULONG hist_size;

FUNCTIONS
    Allocate and prepare a line structure.  Allocate all necessary
    buffers.  Initialize all variables, etc.

INPUT
    buf_size = Size to allocate for command buffer.
    hist_size = Number of history lines.  The history buffers are not
                allocated at this point.

RESULT
    line = Allocated Line structure. NULL if unsuccessful.

SEE ALSO
    FreeLine

---------------------------------------------------------------------

NAME
    BuildLine -- Inserts a character into the command buffer if
                 applicable.  Some control codes will change the
                 state of the buffer.

SYNOPSIS
    rc = BuildLine(outfh,line,c,max)

    int rc;
    BPTR outfh;
    struct Line *line;
    char c;
    long max;

FUNCTION
    This routine takes the input character and stores it into the
    buffer and echoes it back onto the screen if the buffer is
    non-full.  Control codes such as cursor movements will alter the
    state of the buffer.

INPUTS
    outfh = File handle for output, if 0L then no output.
    line = The line in which the character is to affect.
    c = The character to store in/affect the buffer.
    max = The maximum number of characters this buffer can allow.
          If -1L, use the default.

RESULT
    rc = Return code indicating whether the user has completed the
         command buffer by press a carriage return.  If non-zero,
         it means that a carriage return has been pressed.

SEE ALSO
    ResetLine

---------------------------------------------------------------------

NAME
    DeleteHistory -- Delete the specified history line.

SYNOPSIS
    void DeleteHistory(line,num)

    struct Line *line;
    long num;

FUNCTIONS
    Remove the specified history node from the history list.

INPUT
    line = Line structure where the history list is found.
    num = History number to remove.  The first one is 1, and the last
          one is -1L.

RESULT
    none

EXAMPLE
    struct Line *line;
    ...
    while(line->hist_linecount)		/* delete all history lines */
	DeleteHistory(line,1);

SEE ALSO
    MakeHistory
    ShowHistory
    GetHistory

---------------------------------------------------------------------

NAME
    FreeLine -- Deallocate all the buffers allocated by a Line
                structure.

SYNOPSIS
    void FreeLine(line)

    struct Line *line;

FUNCTIONS
    Simply free all the memory associated with a Line structure,
    including itself.

INPUT
    line = Line structure whose contents to be freed.

RESULT
    none

SEE ALSO
    AllocLine

---------------------------------------------------------------------

NAME
    GetHistory -- Travers the history list to find the specified
                  history buffer.

SYNOPSIS
    history = GetHistory(line,num)

    struct History *history;
    struct Line *line;
    long num;

FUNCTIONS
    This routine will find the numbered history line buffer you
    specify.  It will search through the whole history list.

INPUTS
    line = The line structure to search for the specified history.
    num = The history number to search.

RESULT
    history = Pointer to the history structure node if found, else
    NULL.

EXAMPLE
    struct Line *line;
    struct History *history;
    ...
    history = GetHistory(line,1);
    if (history)
	printf("%s\n",history->buf);

SEE ALSO
    MakeHistory
    ShowHistory
    DeleteHistory

---------------------------------------------------------------------

NAME
    MakeHistory -- Add a buffer to the history list.

SYNOPSIS
    void MakeHistory(line,buf,len)

    struct Line *line;
    char *buf;
    long len;

FUNCTIONS
    This routine will add a new history line into history list.  If
    the current number of history lines is at maximum, the oldest
    history line will be deleted, and the new one added.  After the
    user enters a command line buffer, it automatically adds it to
    the history list.

INPUT
    line = Line structure in which to put the new history.
    buf = Buffer to add to history list.
    len = Length of buffer, if -1L it'll use strlen(buf).
          If len == 0, buf is not added to the history list.

RESULT
    none
   
EXAMPLE
    struct Line *line;
    ...
    MakeHistory(line,"New history line coming in...",-1L);

SEE ALSO
    DeleteHistory
    GetHistory
    ShowHistory

---------------------------------------------------------------------

NAME
    RawGets -- Synchronously get a command buffer from the standard
               input handler.

SYNOPSIS
    count = RawGets(buf,buflen,defsize,hotkey,caps,quiet)

    long count;
    char *buf;
    ULONG buflen;
    ULONG defsize;
    char hotkey;
    char caps;
    char quiet;

FUNCTION
    Get a line of input from the user.  This routine will not return
    until either the user has pressed a carriage return, or pressed
    ^C.  Note that this routine does not need any initialization
    routines (like AllocLine or RawMode, etc.) to be called prior to
    it's usage.  All the initilization calls are done within itself.
    Note that this routine does not support command line history.

EXAMPLE
    void main(void)
    {
	char	name[30],
		pass[30],
		comp[30],
		key[2];

	printf("Enter your name => ");
	RawGets(name,30,0,0,0,0);
	printf("Enter your password => ");
	RawGets(pass,30,0,0,0,1);
	printf("Enter your computer type => ");
	strcpy(comp,"Amiga!");	/* if user just presses return,
				   "Amiga!" is accepted */
	RawGets(comp,30,strlen(comp),0,0,0);
	printf("Press any key to continue...");
	RawGets(key,2,0,1,0,1);
    }

INPUT
    buflen = Length of buffer, including the null-termination char.
             0.
    defsize = The default size of the buffer to display.
    hotkey = If non-zero return when the user has typed one
             character.
    caps = If non-zero capitalizes everything the users types.
    quiet = If non-zero do not echo back what the user typed.

RESULT
    count = Number of characters entered by the user.
            0 if the user pressed return on a blank line.
           -1 if the user has pressed ^C.
           -2 if the standard input handler will no
              longer send us anymore input.  Your program should exit
              as soon as possible.  For example,
              1> myprog <PIPE:
              2> echo >PIPE: testing...
              When CLI process 2 opens, sends data, and closes the
              pipe, RawGets() in process 1 will return 10 (size of
              "testing...") on the first read, while -2 on the
              second.  If process 1 calls RawGets() again, it will be
              stuck in a tight loop draining the CPU, until something
              shows up in the pipe again.  RawGets() returning -2 is
              the analagous to dos.library's Read() return 0.

---------------------------------------------------------------------

NAME
    RawMode -- Turn the standard input file handle into raw mode.

SYNOPSIS
    void RawMode(mode)

    long mode;

FUNCTION
    This routine sends a ACTION_SCREEN_MODE packet to the standard
    input file handle to tell it to go into raw mode.  In raw mode,
    characters can be read one at a time, without making the user
    press return for the line to be accepted.

INPUTS
    long = -1L to go into raw mode, 0L to go into cooked mode.

RESULT
    none

---------------------------------------------------------------------

NAME
    ReadDone -- Check if we are done reading.

SYNOPSIS
    bool = ReadDone(packet)

    struct StandardPacket *packet;
    char bool;

FUNCTION
    This routine checks if the input handler has sent everything that
    it can send us.  You should only call this routine after you have
    called StartAsyncRead().  Note that ReadDone() has the same
    effect of having 0L returned from dos.library's Read() function.

INPUT
    packet = Packet which was supplied to StartAsyncRead().

RESULT
    bool = If true, it means that we are done with further reading.
           The program should exit.

---------------------------------------------------------------------

NAME
    ResetLine -- Prepare a Line structure for the next use.

SYNOPSIS
    void ResetLine(line)

    struct Line *line;

FUNCTIONS
    Reset all indices, etc. so that Line structure can be used again.

INPUT
    line = Line to reset.

RESULT
    none

---------------------------------------------------------------------

NAME
    ShowHistory -- Display the whole history buffers in a specified
                   range and order.

SYNOPSIS
    void ShowHistory(outfh,line,hist_start,hist_lines,reverse)

    BPTR outfh;
    struct Line *line;
    long hist_start;
    long hist_lines;
    char reverse;

FUNCTIONS
    Display the numbered history lines in the order and range
    specified.  If the order is reverse, the last line will be
    displayed first, and the first displayed last.

INPUT
    outfh = File handle to send the output to.
    line = Line structure where the history lines are found.
    hist_start = The location where history lines start to display.
		 1 is first, -1 is last.
    hist_lines = The number of history lines to display.  If -1,
                 display all.
    reverse = If non-zero display in descending order, else
              otherwise.

RESULT
    none

SEE ALSO
    MakeHistory
    GetHistory
    DeleteHistory

---------------------------------------------------------------------

NAME
    StartAsyncRead -- Start an asynchronous read from the standard
                      input.

SYNOPSIS
    void StartAsyncRead(packet,port,c)

    struct StandardPacket *packet;
    struct MsgPort *port;
    char *c;

FUNCTION
    A ACTION_READ packet is sent to the input handler to tell it we
    want to get a character.  A message is sent back to the message
    port you specified when such a character is typed.

INPUTS
    packet = Packet to send to the handler.  This packet need not be
             initialized by you, as the routine does it.
    port = Message port to send a message to when a read is done.
    c = Address in which a character is to be put in.

RESULT
    none

---------------------------------------------------------------------


=====================================================================
COMMAND LINE EDITING FEATURES
=============================

Key                ANSI     Effect
---------------------------------------------------------------------
Cursor-left        ^[[D     move one character to the left
Cursor-right       ^[[C     move one character to the right
Shift-cursor-left  ^[[ A,^A move to the beginning of the line
Shift-cursor-right ^[[ @,^Z move to the end of the line
Backspace          ^H       delete last character
Del                127      delete the character under the cursor
Return/Enter       ^M       process command line
                   ^W       move cursor one tab stop to the right
                   ^X       delete current line
                   ^K       delete everything from the cursor forward
                            to the end of the line
                   ^U       delete everything from the cursor
                            backward to the start of the line
Cursor-up          ^[[A     move backward in the history buffer
                            (earlier lines)
Cursor-down        ^[[B     move forward in the history buffer
                            (latter lines)
Shift-cursor-up    ^[[T,^R  search backward through history buffer
                            for given command line or fragment
Shift-cursor-down  ^[[S     move to the bottom of the history buffer,
                            with cusor on blank line
                   ^F       move to last word
                   ^G       move to next word
                   ^V       move halfway backward toward the start of
                            the line
                   ^B       move halfway forward toward the end of
                            the line
                   ^E       delete the word under the cursor
---------------------------------------------------------------------
NOTE: 1. ^x is Ctrl-x (Hold down the control "Ctrl" key and type x)
      2. Some terminal programs do not support shifted cursor keys.


=====================================================================
REQUIREMENTS
============

The test program and the library runs on any Amiga with OS 1.2 or
higher.


=====================================================================
LAST WORDS
==========

No fee is required for usage of this program, but I will accept any
donations of money.  If you donate over $5 and request it, I will
send you the latest version of RawIN.lib, including the source code.
Please let me know if you find this library useful, so that will give
me incentive to write other similiar libraries.

Donations, comments, and bug reports should be sent to:

Home Address: Sam Yee
              c/o Utilities
              4595 Nanaimo St.
              Vancouver, B.C.
              Canada  V5N-5J5

    Internet: samy@sfu.ca (starting September '92)
              flui@sfu.ca (before September '92)
              samy@wiz.outb.wimsey.bc.ca

     FidoNet: 1:153/765 (Terra Firma BBS! 604-434-3665)

