/*
 * keytab.c -- contains the intial keymap tables
 *
 * Originally taken from tcsh.keytab.c
 */

#ifndef lint
static char *rcsid_keytab_c = "$Header: tcsh.keytab.c,v 1.4 88/07/30 20:08:56 tytso Exp $";
#endif lint

#include <sys/types.h>
#include <stdio.h>

#define TRUE 1
#define FALSE 0
typedef char 	bool;

struct keymap_entry {
	bool (*function)();
	caddr_t argument;
};

struct keymap_entry   *next_func_map, *cur_func_map;

bool	mult_num_reset;
int	mult_num;
	
/*
 * stuff related to function tables
 */

#define		DELETE_FUNC	127		/* for ^? */
#define		EOF_FUNC	128		/* for EOF */
#define		BAD_FUNC	129		/* bad chars func # */

extern bool	mark(), bol(), back(), intr(), dela(), eol(), frwd();
extern bool	delb(), exc(), dsrch(), rdsp(), exc(), next(), prev();
extern bool	quote(), rsrch(), srch(), twdl(), e_twdl(), numb();
extern bool	kill_line(), dele(), wlcase(), wucase(), wccase();
extern bool	yank(), prfx(), prfx_2(), prfx_3(), insrt(), space();
extern bool	no_op(), eof(), bad(), comp(), ldav();
extern bool	boh(), eoh(), wdback(), wdfrwd(), wddelp(), wddeln();
extern bool	undo(), hynk();
extern bool 	comp_print(), comp_insert();
extern bool	clear(), tcsh_reset(), set_starting_keymap();

struct keymap_entry  norm_func[]	= {
    			mark,	NULL, 		/* 0 ^@ */
			bol,	NULL, 		/* 1 ^A */
			back,	NULL, 		/* 2 ^B */
			intr,	NULL, 		/* 3 ^C */
			dela,	NULL, 		/* 4 ^D */
			eol,	NULL, 		/* 5 ^E */
			frwd,	NULL, 		/* 6 ^F */
			tcsh_reset,	NULL,	/* 7 ^G */
			delb,	NULL, 		/* 8 ^H */
			space,	NULL, 		/* 9 ^I */
			exc,	NULL, 		/* 10 ^J */
			dele,	NULL, 		/* 11 ^K */
			clear,	NULL,	 	/* 12 ^L */
			exc,	NULL, 		/* 13 ^M */
			next,	NULL, 		/* 14 ^N */
			bad,	NULL,		/* 15 ^O */
			prev,	NULL, 		/* 16 ^P */
			bad,	NULL, 		/* 17 ^Q */
			rsrch,	NULL, 		/* 18 ^R */
			bad,	NULL, 		/* 19 ^S */
			twdl,	NULL, 		/* 20 ^T */
			numb,	NULL, 		/* 21 ^U */
			quote,	NULL, 		/* 22 ^V */
			kill_line,	NULL,	/* 23 ^W */
#ifdef TIOCSTAT
			new_ldav,	NULL, 	/* 24 ^X */
#else
			ldav,	NULL, 		/* 24 ^X */
#endif
			yank,	NULL, 		/* 25 ^Y */
			comp,	NULL, 		/* 26 ^Z */
			/* prefix goes here.  Installed at init time */
			bad,	NULL, 		/* 27 esc */
			bad,	NULL, 		/* 28 */
			bad,	NULL, 		/* 29 */
			bad,	NULL, 		/* 30 */
			undo,	NULL,		/* 31 */
			space,	NULL,		/* 32 space */
			insrt,	NULL,		/* 33 ! */
			insrt,	NULL,		/* 34 double-quote */
			insrt,	NULL,		/* 35 # */
			insrt,	NULL,		/* 36 $ */
			insrt,	NULL,		/* 37 % */
			insrt,	NULL,		/* 38 & */
			insrt,	NULL,		/* 39 single-quote */
			insrt,	NULL,		/* 40 ( */
			insrt,	NULL,		/* 41 ) */
			insrt,	NULL,		/* 42 * */
			insrt,	NULL,		/* 43 + */
			insrt,	NULL,		/* 44 ,	NULL, */
			insrt,	NULL,		/* 45 - */
			insrt,	NULL,		/* 46 . */
			insrt,	NULL,		/* 47 / */
			insrt,	NULL,		/* 48 0 */
			insrt,	NULL,		/* 49 1 */
			insrt,	NULL,		/* 50 2 */
			insrt,	NULL,		/* 51 3 */
			insrt,	NULL,		/* 52 4 */
			insrt,	NULL,		/* 53 5 */
			insrt,	NULL,		/* 54 6 */
			insrt,	NULL,		/* 55 7 */
			insrt,	NULL,		/* 56 8 */
			insrt,	NULL,		/* 57 9 */
			insrt,	NULL,		/* 58 : */
			insrt,	NULL,		/* 59 ; */
			insrt,	NULL,		/* 60 < */
			insrt,	NULL,		/* 61 = */
			insrt,	NULL,		/* 62 > */
			insrt,	NULL,		/* 63 ? */
			insrt,	NULL,		/* 64 @ */
			insrt,	NULL,		/* 65 A */
			insrt,	NULL,		/* 66 B */
			insrt,	NULL,		/* 67 C */
			insrt,	NULL,		/* 68 D */
			insrt,	NULL,		/* 69 E */
			insrt,	NULL,		/* 70 F */
			insrt,	NULL,		/* 71 G */
			insrt,	NULL,		/* 72 H */
			insrt,	NULL,		/* 73 I */
			insrt,	NULL,		/* 74 J */
			insrt,	NULL,		/* 75 K */
			insrt,	NULL,		/* 76 L */
			insrt,	NULL,		/* 77 M */
			insrt,	NULL,		/* 78 N */
			insrt,	NULL,		/* 79 O */
			insrt,	NULL,		/* 80 P */
			insrt,	NULL,		/* 81 Q */
			insrt,	NULL,		/* 82 R */
			insrt,	NULL,		/* 83 S */
			insrt,	NULL,		/* 84 T */
			insrt,	NULL,		/* 85 U */
			insrt,	NULL,		/* 86 V */
			insrt,	NULL,		/* 87 W */
			insrt,	NULL,		/* 88 X */
			insrt,	NULL,		/* 89 Y */
			insrt,	NULL,		/* 90 Z */
			insrt,	NULL,		/* 91 [ */
			insrt,	NULL,		/* 92 \ */
			insrt,	NULL,		/* 93 ] */
			insrt,	NULL,		/* 94 ^ */
			insrt,	NULL,		/* 95 _ */
			insrt,	NULL,		/* 96 back-quote */
			insrt,	NULL,		/* 97 a */
			insrt,	NULL,		/* 98 b */
			insrt,	NULL,		/* 99 c */
			insrt,	NULL,		/* 100 d */
			insrt,	NULL,		/* 101 e */
			insrt,	NULL,		/* 102 f */
			insrt,	NULL,		/* 103 g */
			insrt,	NULL,		/* 104 h */
			insrt,	NULL,		/* 105 i */
			insrt,	NULL,		/* 106 j */
			insrt,	NULL,		/* 107 k */
			insrt,	NULL,		/* 108 l */
			insrt,	NULL,		/* 109 m */
			insrt,	NULL,		/* 110 n */
			insrt,	NULL,		/* 111 o */
			insrt,	NULL,		/* 112 p */
			insrt,	NULL,		/* 113 q */
			insrt,	NULL,		/* 114 r */
			insrt,	NULL,		/* 115 s */
			insrt,	NULL,		/* 116 t */
			insrt,	NULL,		/* 117 u */
			insrt,	NULL,		/* 118 v */
			insrt,	NULL,		/* 119 w */
			insrt,	NULL,		/* 120 x */
			insrt,	NULL,		/* 121 y */
			insrt,	NULL,		/* 122 z */
			insrt,	NULL,		/* 123 { */
			insrt,	NULL,		/* 124 | */
			insrt,	NULL,		/* 125 } */
			insrt,	NULL,		/* 126 ~ */
			delb,	NULL,		/* 127 delete */
			eof,	NULL, 		/* 128 special: eof */
			bad,	NULL		/* 129 special: bad */
		};


/* Everything for key-mapping is here */

extern char	*strdup();
extern struct name_table name_table[];
extern struct keymap_entry norm_func[];

struct keymap_entry *start_keymap;

keymap_initialize()
{
	int	i;
	struct keymap_entry	*prefix_map, *vt100_map;
	struct keymap_entry 	*make_keymap();
	register struct keymap_entry *kp;
	bool prfx();
	
	start_keymap = norm_func;
	
	/* Create meta keymap */
	prefix_map = kp = make_keymap();
	kp += '[';
	(kp++)->function = prfx; 	/* 91 [ */
	kp += 5;
	(kp++)->function = boh;		/* 97 a */
	(kp++)->function = wdback;	/* 98 b */
	(kp++)->function = wucase;	/* 99 c */
	(kp++)->function = wddeln;	/* 100 d */
	(kp++)->function = eoh;		/* 101 e */
	(kp++)->function = wdfrwd;	/* 102 f */
	kp++;
	(kp++)->function = wddelp;	/* 104 h */
	kp += 8;
	(kp++)->function = quote;	/* 113 q */
	kp++;
	(kp++)->function = srch;	/* 115 s */
	kp++;
	(kp++)->function = undo;	/* 117 u */
	kp += 3;
	(kp++)->function = hynk;	/* 121 y */
	(kp++)->function = bad;	/* 122 z */
	kp += 4;
	(kp++)->function = wddelp;     	/* 127 delete */

	/* Create vt100 keymap so arrow keys will work */
	vt100_map = kp = make_keymap();
	kp += 'A';
	(kp++)->function = prev;
	(kp++)->function = next;
	(kp++)->function = frwd;
	(kp++)->function = back;
	
	norm_func[27].function = prfx; 		/* Install meta table */
	norm_func[27].argument = (caddr_t) prefix_map;
	prefix_map[91].argument = (caddr_t) vt100_map;
}

/*
 * Create a new keymap, allocated and initialized
 */
struct keymap_entry *make_keymap()
{
	struct keymap_entry	*entry;
	int	i=0;
	
	entry = (struct keymap_entry *)
		calloc(sizeof(struct keymap_entry),130);
	for (i=0; i < 130; i++) {
		entry[i].function = bad;
		entry[i].argument = NULL;
	}
	entry[EOF_FUNC].function = eof;
	return(entry);
}

read_loop()
{
	register char	c;
	
    /*
     * Note that in this loop, (*tcsh_map)() may change tcsh_func!  Given the
     * current order of evaluation, this works properly.
     */
	do  {
	    if (mult_num_reset)  mult_num = 1;
	    else  mult_num_reset = TRUE;
	    c = tcsh_next_char(1);
	    if (c == -1) break;
	    if (c < 0x00 ) c = EOF_FUNC;
	    if (c > 0x7f)  {
		    c = BAD_FUNC;
	    }
	    cur_func_map = next_func_map;
	    next_func_map = start_keymap;
	}  while ((*(cur_func_map[c].function))(c, cur_func_map[c].argument));

}

extern bool		mult_num_reset;	/* reset multiplier num? */
extern bool		prev_del_reset;	/* reset prev delete flag? */

/*
 * prfx:
 * The prefix character for extended commands.
 * In addition to changing the cur_func_map, we must also insure that we
 * don't lose the repeat count, if any.
 *
 */

bool  prfx(c,arg)
	char	c;
	caddr_t	arg;
{
	next_func_map = (struct keymap_entry *) arg;
	mult_num_reset = FALSE;
	prev_del_reset = FALSE;
	return( TRUE );
}

/*
 * tcsh_reset:
 * Reset things to their normal state after an abort.
 */

bool  tcsh_reset( c )
    register  int		c;
{
	BELL();
	mult_num_reset = TRUE;
	prev_del_reset = TRUE;
	next_func_map = cur_func_map = start_keymap;
	return( TRUE );
}


