/**************************
 *			  *
 * Module: Cursor.c	  *
 *			  *
 * Moving the cursors. 	  *
 *			  *
 **************************/

/*#FOLD: Includes */
/************
 *
 * Includes:
 *
 ************/

#include <exec/types.h>
#include <intuition/intuition.h>
#include "src/Editor.h"
/*#ENDFD*/
/*#FOLD: Defines */
/***********
 *
 * Defines:
 *
 ***********/

#define CSI 0x9B
#define CUU 'A'
#define CUD 'B'
#define CUF 'C'
#define CUB 'D'
#define SU 'S'
#define SD 'T'
#define CHOME 'A'
#define CEND '@'

#define ESC 27
#define UNDO '?'
#define CFOLD 6
#define CENDF 5
#define DELLINE 2
#define DEL 127
#define BS 8
#define TAB 9
#define LF 10
#define CR 13
#define REPCOM 7
/*#ENDFD*/
/*#FOLD: External Functions */
/**********************
 *
 * External Functions:
 *
 **********************/

void SetDrMd(),RectFill(),printAll(),DisplayBeep(),undoLine();
void ScrollRaster(),cursorOnText(),printXpos(),printYpos();
void printFold(),printFlags(),cursorOnText();
struct Zline *nextLine(),*prevLine();
BOOL insertChar(),deleteChar(),backspaceChar(),insertLine(),deleteLine();
BOOL ActivateGadget();
UBYTE *executeCommand();
/*#ENDFD*/
/*#FOLD: External Variables */
/*********************
 *
 * External Variables:
 *
 *********************/

extern struct Editor *actualEditor;
extern UWORD SplitDec;
extern struct Gadget G_Command;
/*#ENDFD*/

/***************
 *		*
 * Functions: *
 *		*
 ***************/

/*#FOLD: restoreZlinenptr */
/************************************
 *
 * restoreZlinenptr:
 *
 * Restore the zlinesptr/nr field
 * for all lines in window plus
 * the next line.
 * The first line must be
 * correct!
 *
 ************************************/

void restoreZlinenptr()
{
	register UWORD n;
	register struct Zline **zptr,*z;
	register UWORD *pnr;
	UWORD znr;

	for (n = actualEditor->wch, zptr = actualEditor->zlinesptr,
					pnr = actualEditor->zlinesnr,
					z = *zptr++, znr = *pnr++; n; n--)
	{
		*zptr++	= (z = nextLine(z,&znr));
		*pnr++	= znr;
	}
}
/*#ENDFD*/
/*#FOLD: Cursor */
/**********************************
 *
 * Cursor:
 *
 * Set or erase the cursor
 * at the actual position.
 *
 **********************************/

void Cursor()
{
	register struct RastPort *rp;
	register LONG x,y;
	register LONG cw,ch;

	SetDrMd(rp = actualEditor->rp,COMPLEMENT);

	x = (actualEditor->xpos - actualEditor->leftpos - 1)
		*(cw = actualEditor->cw) + actualEditor->xoff;
	y = actualEditor->wdy
		*(ch = actualEditor->ch) + actualEditor->yoff;

	RectFill(rp,x,y,x + cw-1,y + ch-1);

	SetDrMd(rp,JAM2);
}
/*#ENDFD*/
/*#FOLD: scrollRight */
/*******************************
 *
 * scrollRight(num):
 *
 * Scroll the window contents
 * num characters to the right.
 *
 * num = number of characters.
 *
 *******************************/

void scrollRight(num)
register UWORD	  num;
{
	register UWORD y,ch,count;
	register struct Zline **z;
	UWORD wcw,xoff,leftpos;

	actualEditor->leftpos -= num;

	if (num >= actualEditor->wcw)
		printAll();
	else
	{
		/* Scrolling: */
		ScrollRaster(actualEditor->rp,
						 -num * (LONG)actualEditor->cw,0L,
						 (LONG)actualEditor->xoff,(LONG)actualEditor->yoff,
						 (LONG)actualEditor->xscr,(LONG)actualEditor->yscr);

		/* now list printAll(): */
		wcw = actualEditor->wcw;
		actualEditor->wcw = num + 1;
		SplitDec = 1;

		y		= actualEditor->yoff;
		ch		= actualEditor->ch;
		count	= actualEditor->wch;

		/* Output line: */
		for (z = actualEditor->zlinesptr; count-- && (*z != NULL);
				z++, y += ch)
			printLine(*z,y);

		SplitDec = 0;

		/* Display right border beside last character */
		leftpos	= actualEditor->leftpos;
		xoff		= actualEditor->xoff;
		actualEditor->wcw		  = 2;
		actualEditor->leftpos += (y = wcw - 2);
		actualEditor->xoff	 += actualEditor->cw * y;

		y		= actualEditor->yoff;
		count	= actualEditor->wch;

		/* Output line: */
		for (z = actualEditor->zlinesptr; count-- && (*z != NULL);
				z++, y += ch)
			printLine(*z,y);

		actualEditor->wcw		= wcw;
		actualEditor->leftpos= leftpos;
		actualEditor->xoff	= xoff;
	}
}
/*#ENDFD*/
/*#FOLD: scrollLeft */
/*******************************
 *
 * scrollLeft(num):
 *
 * Scroll the window contents
 * num characters left.
 *
 * num = number of characters.
 *
 *******************************/

void scrollLeft(num)
register UWORD  num;
{
	register UWORD y,ch,count;
	register struct Zline **z;
	UWORD wcw,xoff,leftpos;

	actualEditor->leftpos += num;

	if (num >= actualEditor->wcw)
		printAll();
	else
	{
		/* Scrolling: */
		ScrollRaster(actualEditor->rp,
						 num * (LONG)actualEditor->cw,0L,
						 (LONG)actualEditor->xoff,(LONG)actualEditor->yoff,
						 (LONG)actualEditor->xscr,(LONG)actualEditor->yscr);

		/* now list printAll(): */
		wcw		= actualEditor->wcw;
		leftpos	= actualEditor->leftpos;
		xoff		= actualEditor->xoff;
		actualEditor->wcw		  = num + 1;
		actualEditor->leftpos += (y = wcw - num - 1);
		actualEditor->xoff	 += actualEditor->cw * y;

		y		= actualEditor->yoff;
		ch		= actualEditor->ch;
		count	= actualEditor->wch;

		/* Output line: */
		for (z = actualEditor->zlinesptr; count-- && (*z != NULL);
				z++, y += ch)
			printLine(*z,y);

		actualEditor->wcw		= wcw;
		actualEditor->leftpos= leftpos;
		actualEditor->xoff	= xoff;
	}
}
/*#ENDFD*/
/*#FOLD: scrollUp */
/*******************************
 *
 * scrollUp(num):
 *
 * Scroll the window contents
 * num lines up.
 * Num lines must
 * exist!
 *
 * num = Number of the line.
 *
 *******************************/

void scrollUp (num)
register UWORD num;
{
	register struct Zline *z,**zptr,**zold;
	register UWORD n,wch = actualEditor->wch,y;
	UWORD znr,*pnr,*oldnr;

	if (num >= wch)
	{
		/* Display window without Scrolling */
		/* First look for top line: */
		n = wch;
		if (num > wch)
		{
			z = ZLINESPTR(n);
			znr = ZLINESNR(n);
			while (++n < num)
				z = nextLine(z,&znr);
		}
		else
		{
			z = ZLINESPTR(n - 1);
			znr = ZLINESNR(n - 1);
		}

		/* z points before the top line of the window */
		for (n = 0, zptr = actualEditor->zlinesptr,
			  pnr = actualEditor->zlinesnr; n <= wch; n++)
		{
			*zptr++ = (z = nextLine(z,&znr));
			*pnr++	= znr;
		}

		/* Now redisplay the window: */
		printAll();
	}
	else
	{
		/* Scrolling: */
		ScrollRaster(actualEditor->rp,
						 0L,num * (LONG)actualEditor->ch,
						 (LONG)actualEditor->xoff,(LONG)actualEditor->yoff,
						 (LONG)actualEditor->xscr,(LONG)actualEditor->yscr);

		/* zlinesptr/nr recalculated: */
		zptr = actualEditor->zlinesptr;
		zold = &(ZLINESPTR(num));
		pnr = actualEditor->zlinesnr;
		oldnr = &(ZLINESNR(num));
		for (n = 0; n <= wch - num; n++)
		{
			*zptr++ = *zold++;
			*pnr++  = *oldnr++;
		}

		z = *--zold;
		zold = zptr - 1;			/* mark for output! */
		znr = *--oldnr;
		oldnr = pnr - 1;
		while (n <= wch)
		{
			*zptr++ = (z = nextLine(z,&znr));
			*pnr++ = znr;
			n++;
		}

		/* Output new line: */
		for (n = num, y = actualEditor->yoff+(wch-num)*actualEditor->ch;
				(n && (*zold != NULL)); n--, zold++, y += actualEditor->ch)
			printLine(*zold,y);
	}
}
/*#ENDFD*/
/*#FOLD: scrollDown */
/*******************************
 *
 * scrollDown(num):
 *
 * Scroll the window contents
 * num lines down.
 * Num lines must
 * exist!
 *
 * num = number of lines.
 *
 *******************************/

void scrollDown (num)
register UWORD num;
{
	register struct Zline *z,**zptr,**zold;
	register UWORD n,wch = actualEditor->wch,y;
	UWORD znr,*pnr,*oldnr;

	if (num >= wch)
	{
		/* Display window without Scrolling */
		/* search backwards fo rtop line: */
		for (z = ZLINESPTR(0), znr = ZLINESNR(0), n = num - wch; n; n--)
			z = prevLine(z,&znr);

		/* z points to first line after bottom window edge. */
		for (n = 0, zptr = &(ZLINESPTR(wch)), pnr = &(ZLINESNR(wch));
				n <= wch; n++)
		{
			*zptr-- = z;
			*pnr-- = znr;
			z = prevLine(z,&znr);
		}

		/* Now redisplay the window: */
		printAll();
	}
	else
	{
		/* Scrolling: */
		ScrollRaster(actualEditor->rp,
						 0L,-num * (LONG)actualEditor->ch,
						 (LONG)actualEditor->xoff,(LONG)actualEditor->yoff,
						 (LONG)actualEditor->xscr,(LONG)actualEditor->yscr);

		/* zlinesptr recalculated: */
		zptr = &(ZLINESPTR(wch));
		zold = &(ZLINESPTR(wch - num));
		pnr = &(ZLINESNR(wch));
		oldnr = &(ZLINESNR(wch - num));
		for (n = 0; n <= wch - num; n++)
		{
			*zptr--	= *zold--;
			*pnr--	= *oldnr--;
		}

		for (z = *++zold, znr = *++oldnr, n = num; n; n--)
		{
			*zptr--	= (z = prevLine(z,&znr));
			*pnr--	= znr;
		}

		/* Output new line: */
		for (n = num, y = actualEditor->yoff; (n && (*zold != NULL));
				n--, zold++, y += actualEditor->ch)
			printLine(*zold,y);
	}
}
/*#ENDFD*/
/*#FOLD: cursorLeft */
/****************************************
 *
 * cursorLeft:
 *
 * moce cursor one position
 * left, False returned if cursor,
 * is in first column.
 *
 ****************************************/

BOOL cursorLeft()
{
	if (actualEditor->xpos > 1)
	{
		actualEditor->xpos--;
		if (actualEditor->xpos <= actualEditor->leftpos)
			scrollRight((UWORD)1);

		printXpos();
		return (TRUE);
	}
	else
		return (FALSE);
}
/*#ENDFD*/
/*#FOLD: cursorRight */
/*****************************************
 *
 * cursorRight:
 *
 * moce cursor one position
 * right, False returned if cursor,
 * is in last column.
 *
 *****************************************/

BOOL cursorRight()
{
	if (actualEditor->xpos < MAXWIDTH)
	{
		actualEditor->xpos++;
		if (actualEditor->xpos
			>= (actualEditor->leftpos + actualEditor->wcw))
			scrollLeft((UWORD)1);

		printXpos();
		return (TRUE);
	}
	else
		return (FALSE);
}
/*#ENDFD*/
/*#FOLD: cursorUp */
/*****************************************
 *
 * cursorUp:
 *
 * Move cursor one line up.
 * False returned when
 * on first line.
 *
 *****************************************/

BOOL cursorUp()
{
	UWORD help;

	if (actualEditor->wdy)
		actualEditor->wdy--;
	else
		if (prevLine(ZLINESPTR(0),&help))
			scrollDown((UWORD)1);
		else
			return (FALSE);

	actualEditor->ypos = ZLINESNR(actualEditor->wdy);
	printYpos();

	return (TRUE);
}
/*#ENDFD*/
/*#FOLD: cursorDown */
/******************************************
 * 
 * cursorDown:
 *
 * Move cursor one line down.
 * False returned when
 * on last line.
 *
 ******************************************/

BOOL cursorDown()
{
	if (ZLINESPTR(actualEditor->wdy + 1))
	{
		if (++actualEditor->wdy >= actualEditor->wch)
		{
			scrollUp((UWORD)1);
			actualEditor->wdy--;
		}
		actualEditor->ypos = ZLINESNR(actualEditor->wdy);
		printYpos();

		return (TRUE);
	}
	else
		return (FALSE);
}
/*#ENDFD*/
/*#FOLD: halfPageUp */
/**********************************
 *
 * halfPageUp:
 *
 * Move cursor on half page
 * up. The text is scrolled
 * half page down
 *
 * False returned when
 * in first line.
 *
 **********************************/

BOOL halfPageUp()
{
	register UWORD max,n;
	register struct Zline *z;
	UWORD help;

	max = actualEditor->wch / 2;
	for (n = 0, z = ZLINESPTR(0); n < max; n++)
		if (!(z = prevLine(z,&help)))
			break;

	if (n)
	{
		scrollDown(n);
		actualEditor->ypos = ZLINESNR(actualEditor->wdy);
		printYpos();

		return (TRUE);
	}
	else
		return (FALSE);
}
/*#ENDFD*/
/*#FOLD: halfPageDown */
/**********************************
 *
 * halfPageDown:
 *
 * Move cursor on half page
 * down. The text is scrolled
 * half page down.
 * 
 * False returned when
 * on last line.
 *
 **********************************/

BOOL halfPageDown()
{
	register UWORD max,n;
	register struct Zline *z;
	UWORD help;

	max = actualEditor->wch / 2;
	for (n = 0, z = ZLINESPTR(actualEditor->wch - 1); n < max; n++)
		if (!(z = nextLine(z,&help)))
			break;

	if (n)
	{
		scrollUp(n);
		actualEditor->ypos = ZLINESNR(actualEditor->wdy);
		printYpos();

		return (TRUE);
	}
	else
		return (FALSE);
}
/*#ENDFD*/
/*#FOLD: cursorHome */
/*************************************
 *
 * cursorHome:
 *
 * move cursor to first line.
 *
 *************************************/

BOOL cursorHome()
{
	actualEditor->xpos = 1;
	if (actualEditor->leftpos)
		scrollRight(actualEditor->leftpos);

	printXpos();

	return (TRUE);
}
/*#ENDFD*/
/*#FOLD: cursorEnd */
/***************************************
 *
 * cursorEnd:
 *
 * Set the cursor on the last line.
 *
 ***************************************/

BOOL cursorEnd()
{
	register UBYTE *ptr,*tab;
	register UWORD len,pos;
	register struct Zline *z;

	if (actualEditor->bufypos)
		pos = actualEditor->buflen + 1;
	else
		if (z = ZLINESPTR(actualEditor->wdy))
		{
			/* remove CR from lenght: */
			len = z->len;
			ptr = ((UBYTE *)(z + 1)) + len - 1;
			if (len)
				if (*ptr == CR)
					len--;
				else if (*ptr == LF)
					if (--len)
						if (*--ptr == CR)
							len--;

			if (actualEditor->tabs)
			{
				ptr = ((UBYTE *)(z + 1));
				tab = actualEditor->tabstring;
				pos = 1;

				while ((len--) && (pos < MAXWIDTH))
					if (*ptr++ == TAB)
						do
						{
							tab++;
							pos++;
						} while ((*tab) && (pos < MAXWIDTH));
					else
					{
						tab++;
						pos++;
					}
			}
			else
				pos = len + 1;
		}
		else
			return (FALSE);

	actualEditor->xpos = pos;
	if (pos >= (actualEditor->leftpos + actualEditor->wcw))
		scrollLeft(pos + 1 - (actualEditor->leftpos
									+ actualEditor->wcw));
	else if (pos <= actualEditor->leftpos)
		scrollRight(actualEditor->leftpos + 1 - pos);

	printXpos();

	return (TRUE);
}
/*#ENDFD*/
/*#FOLD: recalcTopOfWindow */
/***********************************
 *
 * recalcTopOfWindow(y)
 *
 * Calculate the cursor position
 * in line y of
 * line in window.
 * Get new Y-Position.
 *
 * y = Number of line [0,wdy[
 *
 ***********************************/

UWORD recalcTopOfWindow(y)
register UWORD				y;
{
	register struct Zline *z,*zp;
	register UWORD znrp;
	UWORD znr,oldy = y;

	z	 = ZLINESPTR(y);
	znr = ZLINESNR(y);
	while (y)
	{
		zp		= z;
		znrp	= znr;
		if ((z = prevLine(z,&znr)) == NULL)
			break;
		y--;
	}

	if (y)
	{
		ZLINESPTR(0) = zp;
		ZLINESNR(0)  = znrp;
	}
	else
	{
		ZLINESPTR(0) = z;
		ZLINESNR(0)  = znr;
	}

	return (oldy - y);
}
/*#ENDFD*/
/*#FOLD: cursorTop */
/*****************************
 *
 * cursorTop:
 *
 * Set Cursor to to of  Text
 * first line.
 *
 *****************************/

BOOL cursorTop()
{
	register struct Zline *z;
	UWORD n;
	register UWORD cnt;

	z	 = ZLINESPTR(0);
	n	 = ZLINESNR(0);
	cnt = 0;
	while (z = prevLine(z,&n))
		cnt++;

	if (cnt)
		scrollDown(cnt);
	actualEditor->ypos = ZLINESNR(actualEditor->wdy = 0);
	printYpos();

	return (TRUE);
}
/*#ENDFD*/
/*#FOLD: cursorBottom */
/*****************************
 *
 * cursorBottom:
 *
 * Set Cursor to bottom of text
 * last line.
 *
 *****************************/

BOOL cursorBottom()
{
	register struct Zline *z;
	UWORD n;
	register UWORD wch,cnt;

	if	(z	= ZLINESPTR(wch =	actualEditor->wch	- 1))
	{
		n	 =	ZLINESNR(wch);
		cnt = 0;
		while (z = nextLine(z,&n))
			cnt++;

		if (cnt)
			scrollUp(cnt);

		actualEditor->ypos =	ZLINESNR(actualEditor->wdy	= wch);
	}
	else
	{
		actualEditor->ypos =	ZLINESNR(actualEditor->wdy	= wch);
		cursorOnText();
	}

	printYpos();

	return (TRUE);
}
/*#ENDFD*/
/*#FOLD: enterFold */
/***************************
 *
 * enterFold:
 *
 * Step one fold in.
 *
 ***************************/

void enterFold()
{
	register struct Zline *z;

	if (actualEditor->maxfold < ZLF_FOLD)
	{
		actualEditor->maxfold++;
		if (z = ZLINESPTR(actualEditor->wdy))
			if ((z = z->succ)->succ)
				/* If there is a following line: */
				if (((ZLINESPTR(actualEditor->wdy)->flags & ZLF_FOLD)
					 	< (z->flags & ZLF_FOLD))
					&& ((z->flags & ZLF_FOLD) == actualEditor->maxfold))
				{
					/* When this begins a new fold: */
					actualEditor->minfold = actualEditor->maxfold;
					ZLINESPTR(0)	= z;
					ZLINESNR(0)		= ZLINESNR(actualEditor->wdy) + 1;
					actualEditor->wdy = 0;
				}

		actualEditor->wdy = recalcTopOfWindow(actualEditor->wdy);
		restoreZlinenptr();
		printAll();
		actualEditor->ypos = ZLINESNR(actualEditor->wdy);
		printYpos();
		printFold();
	}
}
/*#ENDFD*/
/*#FOLD: exitFold */
/*****************************
 *
 * exitFold:
 *
 * Step one fold out.
 *
 *****************************/

void exitFold()
{
	register UWORD wdy;

	if (actualEditor->maxfold)
	{
		actualEditor->maxfold--;
		if (actualEditor->minfold > actualEditor->maxfold)
			actualEditor->minfold = actualEditor->maxfold;

		wdy = actualEditor->wdy;
		if (ZLINESPTR(wdy) == NULL)
			actualEditor->wdy = wdy = 0;

		if (ZLINESPTR(wdy))
			if (((ZLINESPTR(wdy)->flags & ZLF_FOLD) > actualEditor->maxfold)
			|| ((ZLINESPTR(wdy)->flags & ZLF_FOLD) < actualEditor->minfold))
				ZLINESPTR(wdy) = prevLine(ZLINESPTR(wdy),&(ZLINESNR(wdy)));

		actualEditor->wdy = recalcTopOfWindow(wdy);
		restoreZlinenptr();
		printAll();
		cursorOnText();
		printYpos();
		printFold();
	}
}
/*#ENDFD*/
/*#FOLD: handleKeys */
/*******************************
 *
 * handleKeys(buf,len):
 *
 * Handles keyboard messages.
 * Give FALSE, if
 * the Editor commands
 * elset TRUE.
 *
 * buf ^ buffer with character.
 * len = number of characters.
 *
 *******************************/

BOOL handleKeys(buf,len)
register UBYTE	*buf;
register WORD		  len;
{
	register UBYTE first;

	while (len > 0)
	{
		first = *buf;
		buf++;
		len--;
		if ((first == CSI) && (len > 0))
		{
			len--;
			switch (*buf++)
			{
				case CUU:
					cursorUp();
					break;
				case CUD:
					cursorDown();
					break;
				case CUF:
					cursorRight();
					break;
				case CUB:
					cursorLeft();
					break;
				case SU:
					halfPageDown();
					break;
				case SD:
					halfPageUp();
					break;
				case ' ':
					if (len > 0)
					{
						len--;
						switch (*buf++)
						{
							case CHOME:
								cursorHome();
								break;
							case CEND:
								cursorEnd();
								break;
							default:
								if (! insertChar((UBYTE)CSI))
									DisplayBeep(NULL);
								buf -= 2;
								len += 2;
						}
						break;
					}
					else
						goto noCSI;
				case UNDO:
					if ((len > 0) && (*buf == '~'))
					{
						buf++;
						len--;
						undoLine();
						break;
					}
					/* Else: default */
				default:
noCSI:
					/* No command-Sequence! */
					if (! insertChar((UBYTE)CSI))
						DisplayBeep(NULL);

					buf--;
					len++;
					break;
			}	/* switch (first) */
		}
		else
			switch (first)
			{
				case ESC:
					/* Rest of buf transferred: */
					{
						register UBYTE *sibuf;
						register UWORD cnt;

						sibuf	= actualEditor->gc_SIBuffer;
						while (len)
						{
							*sibuf++ = *buf++;
							len--;
						}
						*sibuf = 0;

						cnt = (sibuf - actualEditor->gc_SIBuffer);
						actualEditor->gc_GadgetSI.BufferPos	= cnt;
						actualEditor->gc_GadgetSI.NumChars	= cnt;
						actualEditor->gc_GadgetSI.DispPos	= 0;
					}

					/* Gagdet aktivated: */
					if (!ActivateGadget(&(actualEditor->G_Command),
											  actualEditor->window,NULL))
						DisplayBeep(NULL);
					break;
				case REPCOM:
				{
					register UBYTE *ptr;
					register SHORT pos,hw;

					if (ptr = executeCommand(actualEditor->gc_SIBuffer))
						if (ptr == -1L)
							return (FALSE);
						else
						{
							if	(ptr >= 0x80000000)
								ptr =	NULL - ptr;

							/* Cursor in StringGadget in error set */
							pos = ptr - actualEditor->gc_SIBuffer;
							actualEditor->gc_GadgetSI.BufferPos = pos;
							if (pos < actualEditor->gc_GadgetSI.DispCount)
								actualEditor->gc_GadgetSI.DispPos = 0;
							else
								actualEditor->gc_GadgetSI.DispPos = pos
										- actualEditor->gc_GadgetSI.DispCount / 2;

							/* Gagdet aktivated: */
							ActivateGadget(&(actualEditor->G_Command),
											  	actualEditor->window,NULL);
							DisplayBeep(NULL);

							/* return now: */
							return (TRUE);
						}

					break;
				}
				case CFOLD:
					enterFold();
					break;
				case CENDF:
					exitFold();
					break;
				case DELLINE:
					if (! deleteLine())
						DisplayBeep(NULL);
					break;
				case DEL:
					if (! deleteChar())
						DisplayBeep(NULL);
					break;
				case BS:
					if (! backspaceChar())
						DisplayBeep(NULL);
					break;
				case LF:
				case CR:
					if (! insertLine((UBYTE) LF))
						DisplayBeep(NULL);
					break;
				default:
					if (! insertChar(first))
						DisplayBeep(NULL);

			}	/* switch (first) */
	}			/* while (len) */

	return (TRUE);
}
/*#ENDFD*/
