home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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);
- }
-