+++ /dev/null
-/* $OpenBSD: kbd.c,v 1.25 2012/04/12 04:47:59 lum Exp $ */
-
-/* This file is in the public domain. */
-
-/*
- * Terminal independent keyboard handling.
- */
-
-#include "def.h"
-#include "kbd.h"
-#include "key.h"
-#include "macro.h"
-
-#ifndef METABIT
-#define METABIT 0x80
-#endif /* !METABIT */
-
-#ifndef NO_DPROMPT
-#define PROMPTL 80
-char prompt[PROMPTL] = "", *promptp = prompt;
-#endif /* !NO_DPROMPT */
-
-static int mgwrap(PF, int, int);
-
-static int use_metakey = TRUE;
-static int pushed = FALSE;
-static int pushedc;
-
-struct map_element *ele;
-
-struct key key;
-
-/*
- * Toggle the value of use_metakey
- */
-int
-do_meta(int f, int n)
-{
- if (f & FFARG)
- use_metakey = n > 0;
- else
- use_metakey = !use_metakey;
- ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
- return (TRUE);
-}
-
-static int bs_map = 0;
-
-/*
- * Toggle backspace mapping
- */
-int
-bsmap(int f, int n)
-{
- if (f & FFARG)
- bs_map = n > 0;
- else
- bs_map = !bs_map;
- ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
- return (TRUE);
-}
-
-void
-ungetkey(int c)
-{
- if (use_metakey && pushed && c == CCHR('['))
- pushedc |= METABIT;
- else
- pushedc = c;
- pushed = TRUE;
-}
-
-int
-getkey(int flag)
-{
- int c;
-
-#ifndef NO_DPROMPT
- if (flag && !pushed) {
- if (prompt[0] != '\0' && ttwait(2000)) {
- /* avoid problems with % */
- ewprintf("%s", prompt);
- /* put the cursor back */
- update();
- epresf = KCLEAR;
- }
- if (promptp > prompt)
- *(promptp - 1) = ' ';
- }
-#endif /* !NO_DPROMPT */
- if (pushed) {
- c = pushedc;
- pushed = FALSE;
- } else
- c = ttgetc();
-
- if (bs_map) {
- if (c == CCHR('H'))
- c = CCHR('?');
- else if (c == CCHR('?'))
- c = CCHR('H');
- }
- if (use_metakey && (c & METABIT)) {
- pushedc = c & ~METABIT;
- pushed = TRUE;
- c = CCHR('[');
- }
-#ifndef NO_DPROMPT
- if (flag && promptp < &prompt[PROMPTL - 5]) {
- promptp = getkeyname(promptp,
- sizeof(prompt) - (promptp - prompt) - 1, c);
- *promptp++ = '-';
- *promptp = '\0';
- }
-#endif /* !NO_DPROMPT */
- 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.
- */
-PF
-doscan(KEYMAP *map, int c, KEYMAP **newmap)
-{
- struct map_element *elec = &map->map_element[0];
- struct map_element *last = &map->map_element[map->map_num];
- PF ret;
-
- while (elec < last && c > elec->k_num)
- elec++;
-
- /* used by prefix and binding code */
- ele = elec;
- if (elec >= last || c < elec->k_base)
- ret = map->map_default;
- else
- ret = elec->k_funcp[c - elec->k_base];
- if (ret == NULL && newmap != NULL)
- *newmap = elec->k_prefmap;
-
- return (ret);
-}
-
-int
-doin(void)
-{
- KEYMAP *curmap;
- PF funct;
-
-#ifndef NO_DPROMPT
- *(promptp = prompt) = '\0';
-#endif /* !NO_DPROMPT */
- curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
- key.k_count = 0;
- while ((funct = doscan(curmap, (key.k_chars[key.k_count++] =
- getkey(TRUE)), &curmap)) == NULL)
- /* nothing */;
-
- if (macrodef && macrocount < MAXMACRO)
- macro[macrocount++].m_funct = funct;
-
- return (mgwrap(funct, 0, 1));
-}
-
-int
-rescan(int f, int n)
-{
- int c;
- KEYMAP *curmap;
- int i;
- PF fp = NULL;
- int md = 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[md]->p_map;
- for (i = 0; i < key.k_count - 1; i++) {
- if ((fp = doscan(curmap, (key.k_chars[i]),
- &curmap)) != NULL)
- break;
- }
- if (fp == NULL) {
- if ((fp = doscan(curmap, c, NULL)) == NULL)
- while ((fp = doscan(curmap,
- key.k_chars[key.k_count++] =
- getkey(TRUE), &curmap)) == NULL)
- /* nothing */;
- if (fp != rescan) {
- if (macrodef && macrocount <= MAXMACRO)
- macro[macrocount - 1].m_funct
- = fp;
- return (mgwrap(fp, f, n));
- }
- }
- }
- /* try previous mode */
- if (--md < 0)
- return (ABORT);
- curmap = curbp->b_modes[md]->p_map;
- for (i = 0; i < key.k_count; i++) {
- if ((fp = doscan(curmap, (key.k_chars[i]), &curmap)) != NULL)
- break;
- }
- if (fp == NULL) {
- while ((fp = doscan(curmap, key.k_chars[i++] =
- getkey(TRUE), &curmap)) == NULL)
- /* nothing */;
- key.k_count = i;
- }
- if (fp != rescan && i >= key.k_count - 1) {
- if (macrodef && macrocount <= MAXMACRO)
- macro[macrocount - 1].m_funct = fp;
- return (mgwrap(fp, f, n));
- }
- }
-}
-
-int
-universal_argument(int f, int n)
-{
- KEYMAP *curmap;
- PF funct;
- int c, nn = 4;
-
- if (f & FFUNIV)
- nn *= n;
- for (;;) {
- key.k_chars[0] = c = getkey(TRUE);
- key.k_count = 1;
- if (c == '-')
- return (negative_argument(f, nn));
- if (c >= '0' && c <= '9')
- return (digit_argument(f, nn));
- curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
- while ((funct = doscan(curmap, c, &curmap)) == NULL) {
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- if (funct != universal_argument) {
- if (macrodef && macrocount < MAXMACRO - 1) {
- if (f & FFARG)
- macrocount--;
- macro[macrocount++].m_count = nn;
- macro[macrocount++].m_funct = funct;
- }
- return (mgwrap(funct, FFUNIV, nn));
- }
- nn <<= 2;
- }
-}
-
-/* ARGSUSED */
-int
-digit_argument(int f, int n)
-{
- KEYMAP *curmap;
- PF funct;
- int nn, c;
-
- nn = key.k_chars[key.k_count - 1] - '0';
- for (;;) {
- c = getkey(TRUE);
- 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, &curmap)) == NULL) {
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- if (macrodef && macrocount < MAXMACRO - 1) {
- if (f & FFARG)
- macrocount--;
- else
- macro[macrocount - 1].m_funct = universal_argument;
- macro[macrocount++].m_count = nn;
- macro[macrocount++].m_funct = funct;
- }
- return (mgwrap(funct, FFOTHARG, nn));
-}
-
-int
-negative_argument(int f, int n)
-{
- KEYMAP *curmap;
- PF funct;
- int c;
- int nn = 0;
-
- for (;;) {
- c = getkey(TRUE);
- 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, &curmap)) == NULL) {
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- if (macrodef && macrocount < MAXMACRO - 1) {
- if (f & FFARG)
- macrocount--;
- else
- macro[macrocount - 1].m_funct = universal_argument;
- macro[macrocount++].m_count = nn;
- macro[macrocount++].m_funct = funct;
- }
- return (mgwrap(funct, FFNEGARG, nn));
-}
-
-/*
- * Insert a character. While defining a macro, create a "LINE" containing
- * all inserted characters.
- */
-int
-selfinsert(int f, int n)
-{
- struct line *lp;
- int c;
- int count;
-
- if (n < 0)
- return (FALSE);
- if (n == 0)
- return (TRUE);
- c = key.k_chars[key.k_count - 1];
-
- if (macrodef && macrocount < MAXMACRO) {
- if (f & FFARG)
- macrocount -= 2;
-
- /* last command was insert -- tack on the end */
- if (lastflag & CFINS) {
- macrocount--;
- /* Ensure the line can handle the new characters */
- if (maclcur->l_size < maclcur->l_used + n) {
- if (lrealloc(maclcur, maclcur->l_used + n) ==
- FALSE)
- return (FALSE);
- }
- maclcur->l_used += n;
- /* Copy in the new data */
- for (count = maclcur->l_used - n;
- count < maclcur->l_used; count++)
- maclcur->l_text[count] = c;
- } else {
- macro[macrocount - 1].m_funct = insert;
- if ((lp = lalloc(n)) == NULL)
- return (FALSE);
- lp->l_bp = maclcur;
- lp->l_fp = maclcur->l_fp;
- maclcur->l_fp = lp;
- maclcur = lp;
- for (count = 0; count < n; count++)
- lp->l_text[count] = c;
- }
- thisflag |= CFINS;
- }
- if (c == '\n') {
- do {
- count = lnewline();
- } while (--n && count == TRUE);
- return (count);
- }
-
- /* overwrite mode */
- if (curbp->b_flag & BFOVERWRITE) {
- 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 everything defined as self-insert.
- */
-int
-quote(int f, int n)
-{
- int c;
-
- key.k_count = 1;
- if ((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
- key.k_chars[0] -= '0';
- if ((c = getkey(TRUE)) >= '0' && c <= '7') {
- key.k_chars[0] <<= 3;
- key.k_chars[0] += c - '0';
- if ((c = getkey(TRUE)) >= '0' && c <= '7') {
- key.k_chars[0] <<= 3;
- key.k_chars[0] += c - '0';
- } else
- ungetkey(c);
- } else
- ungetkey(c);
- }
- return (selfinsert(f, n));
-}
-
-/*
- * Wraper function to count invocation repeats.
- * We ignore any function whose sole purpose is to get us
- * to the intended function.
- */
-static int
-mgwrap(PF funct, int f, int n)
-{
- static PF ofp;
-
- if (funct != rescan &&
- funct != negative_argument &&
- funct != digit_argument &&
- funct != universal_argument) {
- if (funct == ofp)
- rptcount++;
- else
- rptcount = 0;
- ofp = funct;
- }
-
- return ((*funct)(f, n));
-}