/*
 * Name:	MicroEMACS
 * 		Amiga virtual terminal keyboard, default console keymap.
 * Version:	31
 * Last edit:	20-Apr-86
 * Created:	19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
 *			Supports all the default console device
 *			(RAW:) input codes for the Amiga keyboard.
 * Modified:	20-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
 *		[UT-14A] Added processing for GR_to_META, so
 *			characters in the alternate character set
 *			can automatically map to META characters.
 *			This is a rather nice thing to have...
 */
#include	"def.h"

#define	ESC	0x1B			/* Escape, arrows et al.	*/
#define	CSI	0x9B			/* Amiga CSI			*/

/*
 * The function keys on the Amiga send back
 * escape sequences of the form <ESC>[code~, where code
 * is a one or two-character code for the key.  To make
 * it easier to decode, we place the internal key values
 * for these codes in this table.
 */

short	consolemap[] = {
	KF1,		KF2,		KF3,		KF4,
	KF5,		KF6,		KF7,		KF8,
	KF9,		KF10,		KSF1,		KSF2,
	KSF3,		KSF4,		KSF5,		KSF6,
	KSF7,		KSF8,		KSF9,		KSF10
};
#define	NFUNCKEYS ((sizeof consolemap)/(sizeof consolemap[0]))

/*
 * Names for the keys with basic keycode
 * between KFIRST and KLAST (inclusive). This is used by
 * the key name routine in "kbd.c".  KFIRST is KRANDOM, which
 * we don't bind anything useful to.
 */
char	*keystrings[] = {
	NULL,		"F1",		"F2",		"F3",
	"F4",		"F5",		"F6",		"F7",
	"F8",		"F9",		"F10",		"Shift-F1",
	"Shift-F2",	"Shift-F3",	"Shift-F4",	"Shift-F5",
	"Shift-F6",	"Shift-F7",	"Shift-F8",	"Shift-F9",
	"Shift-F10",	"Up",		"Shift-Up",	"Down",
	"Shift-Down",	"Left",		"Shift-Left",	"Right",
	"Shift-Right",	"Help",		NULL,		NULL
};

/*
 * Read in a key, doing the low level mapping
 * of ASCII code to 11 bit code. This level deals with
 * mapping the special keys into their spots in the C1
 * control area. The C0 controls go right through, and
 * get remapped by "getkey".
 *
 * If GR_to_META is TRUE, characters in the Amiga alternate
 * character set get mapped to META characters.  If FALSE,
 * they get sent straight through.
 */

#ifdef AS_DISTRIBUTED
extern	int	GR_to_META;	/* defined in "kbd.c" */
#else
int	GR_to_META = TRUE;	/* not in *MY* "kbd.c"; Fred Fish */
#endif

getkbd()
{
	register int	c;
	register int	n;
loop:
	c = ttgetc();
	if (c == CSI) {
		c = ttgetc();
		/* Unshifted arrow keys */
		if (c == 'A')
			return (KUP);
		if (c == 'B')
			return (KDOWN);
		if (c == 'C')
			return (KRIGHT);
		if (c == 'D')
			return (KLEFT);
		if (c == 'T')
			return (KSUP);
		if (c == 'S')
			return (KSDOWN);
		if (c == '?') {
			ttgetc();		/* discard '~' */
			return (KHELP);
		}

		/* Shifted left, right */
		if (c == ' ') {
			c = ttgetc();
			if (c == 'A' || c == '@')
				return (c == 'A') ? (KSLEFT) : (KSRIGHT);
			goto loop;		/* try again, sucker */
		}

		/* Function keys	*/
		if (c >= '0' && c <= '9') {
			n = 0;
			do {
				n = 10*n + c - '0';
				c = ttgetc();
			} while (c>='0' && c. The
 * value is from the ITS EMACS manual. The
 * hard update is done because the top line in
 * the window is zapped.
 */
backpage(f, n, k)
register int	n;
{
	register LINE	*lp;

	if (f == FALSE) {
		n = curwp->w_ntrows - 2;	/* Default scroll.	*/
		if (n <= 0)			/* Don't blow up if the	*/
			n = 1;			/* window is tiny.	*/
	} else if (n < 0)
		return (forwpage(f, -n, KRANDOM));
#if	CVMVAS
	else					/* Convert from pages	*/
		n *= curwp->w_ntrows;		/* to lines.		*/
#endif
	lp = curwp->w_linep;
	while (n-- && lback(lp)!=curbp->b_linep)
		lp = lback(lp);
	curwp->w_linep = lp;
	curwp->w_dotp  = lp;
	curwp->w_doto  = 0;
	curwp->w_flag |= WFHARD;
	return (TRUE);
}

/*
 * Set the mark in the current window
 * to the value of dot. A message is written to
 * the echo line unless we are running in a keyboard
 * macro, when it would be silly.
 */
setmark(f, n, k)
{
	isetmark();
	if (kbdmop == NULL)
		eprintf("[Mark set]");
	return (TRUE);
}

/* 
 * So other commands can set the mark easily.  (daveb)
 */
isetmark()
{
	curwp->w_markp = curwp->w_dotp;
	curwp->w_marko = curwp->w_doto;
}


/*
 * Swap the values of "dot" and "mark" in
 * the current window. This is pretty easy, because
 * all of the hard work gets done by the standard routine
 * that moves the mark about. The only possible
 * error is "no mark".
 */
swapmark(f, n, k)
{
	register LINE	*odotp;
	register int	odoto;

	if (curwp->w_markp == NULL) {
		eprintf("No mark in this window");
		return (FALSE);
	}
	odotp = curwp->w_dotp;
	odoto = curwp->w_doto;
	curwp->w_dotp  = curwp->w_markp;
	curwp->w_doto  = curwp->w_marko;
	curwp->w_markp = odotp;
	curwp->w_marko = odoto;
	curwp->w_flag |= WFMOVE;
	return (TRUE);
}

/*
 * Go to a specific line, mostly for
 * looking up errors in C programs, which give the
 * error a line number. If an argument is present, then
 * it is the line number, else prompt for a line number
 * to use.
 */
gotoline(f, n, k)
register int	n;
{
	register LINE	*clp;
	register int	s;
	char		buf[32];

	if (f == FALSE) {
		if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
			return (s);
		n = atoi(buf);
	}
	