/*
 * kbd.h: type definitions for symbol.c and kbd.c for mg experimental
 */

#ifndef	KBD_H
#define	KBD_H

/*
 * function holds a union of all the things that a keystroke can point to.
 */
struct function {
#ifdef	NOTDEF
	union {
		int             (*ff_funcp) ();	/* function pointer */
		struct macro   *ff_macro;	/* Macro string */
		struct keymap  *ff_pref;	/* Prefix map */
	}               f_funct;
#define	f_funcp	f_funct.ff_funcp
#define	f_macro	f_funct.ff_macro
#define f_pref	f_funct.ff_pref
#endif
	int             (*f_funcp) PROTO((int, int));
	char            f_type;
};

#define	f_macro	f_funcp
#define f_pref	f_funcp

/* Typenames for mg_type */
#define	F_CFUNCT	0
#define	F_MACRO		1
#define	F_PREFIX	2

/*
 * This is a single element of a keymap, giving the function pointers for all
 * keys between base and num in that map.
 */
struct map_element {
	KCHAR           k_base;	/* first key in element	 */
	KCHAR           k_num;	/* last key in element	 */
	struct function *k_entry;	/* entries for this element */
};

/* Kludge to make conversion easier */
#define	k_funcp		k_entry->f_funct.ff_funcp

/*
 * A keymap has max elements in it, of which num are used. The elements are
 * sorted by k_base, and it is guaranteed that map_element[n].k_base <
 * map_element[n].k_num. Breaking this rule will cause strange things to
 * happen.
 * 
 * predefined keymaps are NOT type struct keymap because final array needs
 * dimension.  If any changes are made to this struct, they must be reflected
 * in all keymap declarations.
 */

#define KEYMAPE(NUM)	{\
	short	map_num;\
	short	map_max;\
	struct function *map_default;\
	struct map_element map_element[NUM];\
}
/* elements used		 */
/* elements allocated		 */
/* default function		 */
/* realy [e_max]		 */

struct keymap
                KEYMAPE(1);

#define none	ctrlg

/* number of map_elements to grow an overflowed keymap by */
#define IMAPEXT 0
#define MAPGROW 3
#define MAPINIT (MAPGROW+1)

/*
 * max number of default bindings added to avoid creating new element;
 * 
 * Note: this uses up more memory than is optimal. On the other hand, the keymap
 * code is designed so that it leaks memory. So we trade away extra space
 * here, in return for (hopefully) not reallocating maps & elements later,
 * which would waste their memory.
 */
#define MAPELEDEF 3

struct maps {
	struct keymap  *p_map;
	char           *p_name;
};

extern struct maps map_table[];

struct functnames {
	int             (*n_funct) ();
	char           *n_name;
};

extern struct map_element *ele;
extern struct functnames functnames[];
extern int      nfunct;

#ifdef	NO_PROTO
extern struct function *doscan();
extern int      (*
		                 name_function()) ();
extern char    *function_name();
extern int      complete_function();
extern struct keymap *name_map();
extern char    *map_name();
extern struct maps *name_mode();
#else
struct function *
                doscan(struct keymap * map, int c);
struct keymap  *
                name_map(char *name);
struct maps    *
                name_mode(char *name);
char           *
                map_name(struct keymap * map);
int
                bindkey(struct keymap * map, char *fname, KCHAR * keys, int kcount);
#endif
#endif
