home *** CD-ROM | disk | FTP | other *** search
- /*
- * Terminal independent keyboard handling.
- */
- #include "def.h"
- #include "kbd.h"
-
- #define EXTERN
- #include "key.h"
-
- #ifndef NO_MACRO
- #include "macro.h"
- #endif
-
- #ifdef DO_METAKEY
- #ifndef METABIT
- #define METABIT 0x80
- #endif
-
- 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;
- {
- #ifdef DO_METAKEY
- if(use_metakey && pushed && c==CCHR('[')) pushedc |= METABIT;
- else
- #endif
- pushedc = c;
- pushed = TRUE;
- }
-
- int getkey(flag)
- int flag;
- {
- int c;
- char *keyname();
-
- #ifndef NO_DPROMPT
- if(flag && !pushed) {
- if(prompt[0]!='\0' && ttwait()) {
- ewprintf("%s", prompt); /* avoid problems with % */
- update(); /* put the cursor back */
- epresf = KPROMPT;
- }
- if(promptp > prompt) *(promptp-1) = ' ';
- }
- #endif
- if(pushed) {
- c = pushedc;
- pushed = FALSE;
- } else c = getkbd();
- #ifdef BSMAP
- if(bs_map)
- if(c==CCHR('H')) c=CCHR('?');
- else if(c==CCHR('?')) c=CCHR('H');
- #endif
- #ifdef DO_METAKEY
- if(use_metakey && (c&METABIT)) {
- pushedc = c & ~METABIT;
- pushed = TRUE;
- c = CCHR('[');
- }
- #endif
- #ifndef NO_DPROMPT
- if(flag && 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.
- */
-
- MAP_ELEMENT *ele;
-
- PF doscan(map, c)
- register KEYMAP *map;
- register int c;
- {
- register MAP_ELEMENT *elec = &map->map_element[0]; /* local register copy for faster access */
- register 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_funcp[c - elec->k_base];
- }
-
- doin()
- {
- KEYMAP *curmap;
- PF 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(TRUE))))
- == prefix)
- curmap = ele->k_prefmap;
- #ifndef NO_MACRO
- if(macrodef && macrocount < MAXMACRO)
- macro[macrocount++].m_funct = funct;
- #endif
- return (*funct)(0, 1);
- }
-
- rescan(f, n)
- int f, n;
- {
- int c;
- register KEYMAP *curmap;
- int i;
- PF 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]))) != prefix) break;
- curmap = ele->k_prefmap;
- }
- if(fp==prefix) {
- if((fp = doscan(curmap, c)) == prefix)
- while((fp=doscan(curmap,key.k_chars[key.k_count++] =
- getkey(TRUE))) == prefix)
- curmap = ele->k_prefmap;
- if(fp!=rescan) {
- #ifndef NO_MACRO
- if(macrodef && macrocount <= MAXMACRO)
- macro[macrocount-1].m_funct = fp;
- #endif
- return (*fp)(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]))) != prefix) break;
- curmap = ele->k_prefmap;
- }
- if(fp==prefix) {
- while((fp=doscan(curmap,key.k_chars[i++]=getkey(TRUE)))
- == prefix)
- curmap = ele->k_prefmap;
- key.k_count = i;
- }
- if(fp!=rescan && i>=key.k_count-1) {
- #ifndef NO_MACRO
- if(macrodef && macrocount <= MAXMACRO)
- macro[macrocount-1].m_funct = fp;
- #endif
- return (*fp)(f, n);
- }
- }
- }
-
- universal_argument(f, n)
- int f, n;
- {
- int c, nn=4;
- KEYMAP *curmap;
- PF funct;
-
- 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)) == prefix) {
- curmap = ele->k_prefmap;
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- if(funct != universal_argument) {
- #ifndef NO_MACRO
- if(macrodef && macrocount < MAXMACRO-1) {
- if(f&FFARG) macrocount--;
- macro[macrocount++].m_count = nn;
- macro[macrocount++].m_funct = funct;
- }
- #endif
- return (*funct)(FFUNIV, nn);
- }
- nn <<= 2;
- }
- }
-
- /*ARGSUSED*/
- digit_argument(f, n)
- int f, n;
- {
- int nn, c;
- KEYMAP *curmap;
- PF funct;
-
- 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)) == prefix) {
- curmap = ele->k_prefmap;
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- #ifndef NO_MACRO
- 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;
- }
- #endif
- return (*funct)(FFOTHARG, nn);
- }
-
- negative_argument(f, n)
- int f, n;
- {
- int nn = 0, c;
- KEYMAP *curmap;
- PF funct;
-
- 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)) == prefix) {
- curmap = ele->k_prefmap;
- key.k_chars[key.k_count++] = c = getkey(TRUE);
- }
- #ifndef NO_MACRO
- 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;
- }
- #endif
- return (*funct)(FFNEGARG, nn);
- }
-
- /*
- * Insert a character. While defining a macro, create a "LINE" containing
- * all inserted characters.
- */
-
- selfinsert(f, n)
- int f, n;
- {
- register int c;
- int count;
- VOID lchange();
- #ifndef NO_MACRO
- LINE *lp;
- int insert();
- #endif
-
- if (n < 0) return FALSE;
- if (n == 0) return TRUE;
- c = key.k_chars[key.k_count-1];
- #ifndef NO_MACRO
- if(macrodef && macrocount < MAXMACRO) {
- if(f & FFARG) macrocount -= 2;
- if(lastflag & CFINS) { /* last command was insert -- tack on end */
- macrocount--;
- if(maclcur->l_size < maclcur->l_used + n) {
- if((lp = lallocx(maclcur->l_used + n)) == NULL)
- return FALSE;
- lp->l_fp = maclcur->l_fp;
- lp->l_bp = maclcur->l_bp;
- lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
- bcopy(maclcur->l_text, lp->l_text, maclcur->l_used);
- for(count = maclcur->l_used; count < lp->l_used; count++)
- lp->l_text[count] = c;
- free((char *)maclcur);
- maclcur = lp;
- } else {
- maclcur->l_used += n;
- 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 = lallocx(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;
- }
- #endif
- 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.
- */
- quote(f, n)
- {
- register 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);
- }
-