home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d352
/
mg.lha
/
MG
/
src.LZH
/
mg
/
kbd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-23
|
9KB
|
415 lines
/*
* Terminal independent keyboard handling.
*/
#include "no_macro.h"
#include "no_metakey.h"
#include "no_dprompt.h"
#include "bsmap.h"
#ifndef NO_METAKEY
#include "metabit.h"
#endif
#include "def.h"
#include "kbd.h"
#include "line.h"
#include "buffer.h"
#include "window.h"
#ifndef NO_MACRO
#include "macro.h"
#endif
#define EXTERN
#include "key.h"
#ifndef NO_METAKEY
int use_metakey = TRUE;
/*
* Toggle the value of use_metakey
*/
do_meta(f, n)
{
if (f & FFARG)
use_metakey = n > 0;
else
use_metakey = !use_metakey;
ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
return TRUE;
}
#endif
#ifdef BSMAP
static int bs_map = BSMAP;
/*
* Toggle backspace mapping
*/
bsmap(f, n)
{
if (f & FFARG)
bs_map = n > 0;
else
bs_map = !bs_map;
ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
return TRUE;
}
#endif
#ifndef NO_DPROMPT
#define PROMPTL 80
char prompt[PROMPTL], *promptp;
#endif
static int pushed = FALSE;
static int pushedc;
VOID
ungetkey(c)
int c;
{
#ifndef NO_METAKEY
if (use_metakey && pushed && c == CCHR('['))
pushedc |= METABIT;
else
#endif
pushedc = c;
pushed = TRUE;
}
int
getkey(flags)
int flags;
{
int c;
char *keyname();
#ifndef NO_MACRO
extern struct macro kbdmacro;
#endif
#ifndef NO_DPROMPT
if ((flags & PROMPT) && !pushed && !inmacro) {
if (prompt[0] != '\0' && ttwait()) {
ewprintf("%s", prompt); /* avoid problems with % */
update(); /* put the cursor back */
epresf = ERASE;
}
if (promptp > prompt)
*(promptp - 1) = ' ';
}
#endif
if (pushed) {
c = pushedc;
pushed = FALSE;
#ifndef NO_MACRO
} else if (inmacro) {
if (inmacro->m_cur - inmacro->m_text >= inmacro->m_count)
return CCHR('G');
else {
c = *(inmacro->m_cur++);
if (!(flags & CRFLAGS))
c = (c == SOFTCR ? CCHR('M') : c);
else if (flags & DISSCR) {
if (c == SOFTCR)
return getkey(flags);
else if (*inmacro->m_cur == SOFTCR)
inmacro->m_cur++;
} /* else flags & SEESCR, so we pass it as is */
}
#endif
} else
c = getkbd();
#ifndef NO_METAKEY
if (use_metakey && (c & METABIT)) {
pushedc = c & ~METABIT;
pushed = TRUE;
c = CCHR('[');
}
#endif
#ifndef NO_MACRO
if (macrodef && !inmacro)
add_key_to_macro((KCHAR) c, &kbdmacro);
#endif
#ifdef BSMAP
if (bs_map)
if (c == CCHR('H'))
c = CCHR('?');
else if (c == CCHR('?'))
c = CCHR('H');
#endif
#ifndef NO_DPROMPT
if ((flags & PROMPT) && promptp < &prompt[PROMPTL - 5]) {
promptp = keyname(promptp, c);
*promptp++ = '-';
*promptp = '\0';
}
#endif
return c;
}
/*
* doscan scans a keymap for a keyboard character and returns a pointer to
* the function associated with that character. Sets ele to the keymap
* element the keyboard was found in as a side effect.
*/
struct map_element *ele;
struct function
*
doscan(map, c)
register struct keymap *map;
register int c;
{
register struct map_element *elec = &map->map_element[0]; /* local register copy
* for faster access */
register struct map_element *last = &map->map_element[map->map_num];
while (elec < last && c > elec->k_num)
elec++;
ele = elec; /* used by prefix and binding code */
if (elec >= last || c < elec->k_base)
return map->map_default;
return &elec->k_entry[c - elec->k_base];
}
doin()
{
struct keymap *curmap;
struct function *funct;
#ifndef NO_DPROMPT
*(promptp = prompt) = '\0';
#endif
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
key.k_count = 0;
while ((funct =
doscan(curmap, (key.k_chars[key.k_count++] = getkey(PROMPT))))->f_type
== F_PREFIX)
curmap = (struct keymap *) funct->f_pref;
#ifndef NO_MACRO
if (funct->f_type == F_MACRO)
return runmacro((struct macro *) funct->f_macro, 0, 1, FALSE);
else
#endif
return (*(funct->f_funcp)) (0, 1);
}
rescan(f, n)
int f, n;
{
int c;
register struct keymap *curmap;
int i;
struct function *fp;
int mode = curbp->b_nmodes;
for (;;) {
if (ISUPPER(key.k_chars[key.k_count - 1])) {
c = TOLOWER(key.k_chars[key.k_count - 1]);
curmap = curbp->b_modes[mode]->p_map;
for (i = 0; i < key.k_count - 1; i++) {
if ((fp = doscan(curmap, (key.k_chars[i])))->f_type != F_PREFIX)
break;
curmap = (struct keymap *) fp->f_pref;
}
if (fp->f_type == F_PREFIX) {
if ((fp = doscan(curmap, c))->f_type == F_PREFIX)
while ((fp = doscan(curmap, key.k_chars[key.k_count++] =
getkey(PROMPT)))->f_type == F_PREFIX)
curmap = (struct keymap *) fp->f_pref;
#ifndef NO_MACRO
if (fp->f_type == F_MACRO)
return runmacro((struct macro *) fp->f_macro, f, n, FALSE);
else
#endif
if (fp->f_funcp != rescan)
return (*(fp->f_funcp)) (f, n);
}
}
/* try previous mode */
if (--mode < 0)
return ABORT;
curmap = curbp->b_modes[mode]->p_map;
for (i = 0; i < key.k_count; i++) {
if ((fp = doscan(curmap, (key.k_chars[i])))->f_type != F_PREFIX)
break;
curmap = (struct keymap *) fp->f_pref;
}
if (fp->f_type == F_PREFIX) {
while ((fp = doscan(curmap, key.k_chars[i++] = getkey(PROMPT)))->f_type
== F_PREFIX)
curmap = (struct keymap *) fp->f_pref;
key.k_count = i;
}
if (i >= key.k_count - 1)
#ifndef NO_MACRO
if (fp->f_type == F_MACRO)
return runmacro((struct macro *) fp->f_macro, f, n, FALSE);
else
#endif
if (fp->f_funcp != rescan)
return (*(fp->f_funcp)) (f, n);
}
}
universal_argument(f, n)
int f, n;
{
int c, nn = 4;
struct keymap *curmap;
struct function *funct;
if (f & FFUNIV)
nn *= n;
for (;;) {
key.k_chars[0] = c = getkey(PROMPT);
key.k_count = 1;
if (c == '-')
return negative_argument(f, 4);
if (c >= '0' && c <= '9')
return digit_argument(f, nn);
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
curmap = (struct keymap *) funct->f_pref;
key.k_chars[key.k_count++] = c = getkey(PROMPT);
}
#ifndef NO_MACRO
if (funct->f_type == F_MACRO)
return runmacro((struct macro *) funct->f_macro, FFUNIV, nn, FALSE);
else
#endif
if (funct->f_funcp != universal_argument)
return (*(funct->f_funcp)) (FFUNIV, nn);
nn *= 4;
}
}
/* ARGSUSED */
digit_argument(f, n)
int f, n;
{
int nn, c;
struct keymap *curmap;
struct function *funct;
nn = key.k_chars[key.k_count - 1] - '0';
for (;;) {
c = getkey(PROMPT);
if (c < '0' || c > '9')
break;
nn *= 10;
nn += c - '0';
}
key.k_chars[0] = c;
key.k_count = 1;
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
curmap = (struct keymap *) funct->f_pref;
key.k_chars[key.k_count++] = c = getkey(PROMPT);
}
#ifndef NO_MACRO
if (funct->f_type == F_MACRO)
return runmacro((struct macro *) funct->f_macro, FFOTHARG, nn, FALSE);
else
#endif
return (*(funct->f_funcp)) (FFOTHARG, nn);
}
negative_argument(f, n)
int f, n;
{
int nn = 0, c;
struct keymap *curmap;
struct function *funct;
for (;;) {
c = getkey(PROMPT);
if (c < '0' || c > '9')
break;
nn *= 10;
nn += c - '0';
}
if (nn)
nn = -nn;
else
nn = -n;
key.k_chars[0] = c;
key.k_count = 1;
curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
curmap = (struct keymap *) funct->f_pref;
key.k_chars[key.k_count++] = c = getkey(PROMPT);
}
#ifndef NO_MACRO
if (funct->f_type == F_MACRO)
return runmacro((struct macro *) funct->f_macro, FFOTHARG, nn, FALSE);
else
#endif
return (*(funct->f_funcp)) (FFNEGARG, nn);
}
/*
* Insert a character.
*/
selfinsert(f, n)
int f, n;
{
register int c;
int count;
VOID lchange();
if (n < 0)
return FALSE;
if (n == 0)
return TRUE;
c = key.k_chars[key.k_count - 1];
if (c == '\n') {
do {
count = lnewline();
} while (--n && count == TRUE);
return count;
}
if (curbp->b_flag & BFOVERWRITE) { /* Overwrite mode */
lchange(WFEDIT);
while (curwp->w_doto < llength(curwp->w_dotp) && n--)
lputc(curwp->w_dotp, curwp->w_doto++, c);
if (n <= 0)
return TRUE;
}
return linsert(n, c);
}
/*
* this could be implemented as a keymap with everthing defined as
* self-insert. (well, not quite - it needs to deal with ^Q###).
*/
quote(f, n)
{
register int c;
#ifndef NO_METAKEY
int save_metakey = use_metakey;
use_metakey = FALSE;
#endif
key.k_count = 1;
if ((key.k_chars[0] = getkey(PROMPT | DISSCR)) >= '0' && key.k_chars[0] <= '7') {
key.k_chars[0] -= '0';
if ((c = getkey(PROMPT | DISSCR)) >= '0' && c <= '7') {
key.k_chars[0] *= 8;
key.k_chars[0] += c - '0';
if ((c = getkey(PROMPT | DISSCR)) >= '0' && c <= '7') {
key.k_chars[0] *= 8;
key.k_chars[0] += c - '0';
} else
ungetkey(c);
} else
ungetkey(c);
}
#ifndef NO_METAKEY
use_metakey = save_metakey;
#endif
return selfinsert(f, n);
}