Annotation of src/usr.bin/mg/kbd.c, Revision 1.6
1.6 ! art 1: /* $OpenBSD: kbd.c,v 1.5 2001/05/03 20:40:22 art Exp $ */
1.4 niklas 2:
1.1 deraadt 3: /*
1.3 millert 4: * Terminal independent keyboard handling.
1.1 deraadt 5: */
6:
7: #define EXTERN
1.3 millert 8:
9: #include "def.h"
10: #include "kbd.h"
11: #include "key.h"
1.1 deraadt 12:
13: #ifndef NO_MACRO
14: #include "macro.h"
1.3 millert 15: #endif /* !NO_MACRO */
1.1 deraadt 16:
1.3 millert 17: #ifdef DO_METAKEY
1.1 deraadt 18: #ifndef METABIT
19: #define METABIT 0x80
1.3 millert 20: #endif /* !METABIT */
21:
22: #ifndef NO_DPROMPT
23: #define PROMPTL 80
24: char prompt[PROMPTL], *promptp;
25: #endif /* !NO_DPROMPT */
1.1 deraadt 26:
1.3 millert 27: static int use_metakey = TRUE;
28: static int pushed = FALSE;
29: static int pushedc;
30:
31: MAP_ELEMENT *ele;
1.1 deraadt 32:
33: /*
34: * Toggle the value of use_metakey
35: */
1.2 millert 36: int
1.1 deraadt 37: do_meta(f, n)
1.2 millert 38: int f, n;
1.1 deraadt 39: {
1.2 millert 40: if (f & FFARG)
41: use_metakey = n > 0;
42: else
43: use_metakey = !use_metakey;
1.1 deraadt 44: ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
45: return TRUE;
46: }
1.3 millert 47: #endif /* DO_METAKEY */
1.1 deraadt 48:
1.3 millert 49: #ifdef BSMAP
50: static int bs_map = BSMAP;
1.1 deraadt 51: /*
52: * Toggle backspace mapping
53: */
1.2 millert 54: int
1.1 deraadt 55: bsmap(f, n)
1.2 millert 56: int f, n;
1.1 deraadt 57: {
1.2 millert 58: if (f & FFARG)
59: bs_map = n > 0;
60: else
61: bs_map = !bs_map;
1.1 deraadt 62: ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
63: return TRUE;
64: }
1.3 millert 65: #endif /* BSMAP */
1.1 deraadt 66:
1.2 millert 67: VOID
68: ungetkey(c)
69: int c;
1.1 deraadt 70: {
1.3 millert 71: #ifdef DO_METAKEY
1.2 millert 72: if (use_metakey && pushed && c == CCHR('['))
73: pushedc |= METABIT;
1.1 deraadt 74: else
1.3 millert 75: #endif /* DO_METAKEY */
1.1 deraadt 76: pushedc = c;
77: pushed = TRUE;
78: }
79:
1.2 millert 80: int
81: getkey(flag)
1.3 millert 82: int flag;
1.1 deraadt 83: {
1.3 millert 84: int c;
1.1 deraadt 85:
86: #ifndef NO_DPROMPT
1.2 millert 87: if (flag && !pushed) {
1.5 art 88: if (prompt[0] != '\0' && ttwait(2000)) {
1.3 millert 89: /* avoid problems with % */
90: ewprintf("%s", prompt);
91: /* put the cursor back */
92: update();
1.1 deraadt 93: epresf = KPROMPT;
94: }
1.2 millert 95: if (promptp > prompt)
96: *(promptp - 1) = ' ';
1.1 deraadt 97: }
1.3 millert 98: #endif /* !NO_DPROMPT */
1.2 millert 99: if (pushed) {
1.1 deraadt 100: c = pushedc;
101: pushed = FALSE;
1.2 millert 102: } else
103: c = getkbd();
1.3 millert 104: #ifdef BSMAP
1.2 millert 105: if (bs_map)
106: if (c == CCHR('H'))
107: c = CCHR('?');
108: else if (c == CCHR('?'))
109: c = CCHR('H');
1.3 millert 110: #endif /* BSMAP */
111: #ifdef DO_METAKEY
1.2 millert 112: if (use_metakey && (c & METABIT)) {
1.1 deraadt 113: pushedc = c & ~METABIT;
114: pushed = TRUE;
115: c = CCHR('[');
116: }
1.3 millert 117: #endif /* DO_METAKEY */
1.1 deraadt 118: #ifndef NO_DPROMPT
1.2 millert 119: if (flag && promptp < &prompt[PROMPTL - 5]) {
120: promptp = keyname(promptp, c);
121: *promptp++ = '-';
122: *promptp = '\0';
1.1 deraadt 123: }
1.3 millert 124: #endif /* !NO_DPROMPT */
1.1 deraadt 125: return c;
126: }
127:
128: /*
129: * doscan scans a keymap for a keyboard character and returns a pointer
130: * to the function associated with that character. Sets ele to the
131: * keymap element the keyboard was found in as a side effect.
132: */
1.2 millert 133: PF
134: doscan(map, c)
135: KEYMAP *map;
136: int c;
137: {
1.3 millert 138: MAP_ELEMENT *elec = &map->map_element[0];
139: MAP_ELEMENT *last = &map->map_element[map->map_num];
1.1 deraadt 140:
1.2 millert 141: while (elec < last && c > elec->k_num)
142: elec++;
1.3 millert 143:
144: /* used by prefix and binding code */
145: ele = elec;
1.2 millert 146: if (elec >= last || c < elec->k_base)
147: return map->map_default;
148: return elec->k_funcp[c - elec->k_base];
1.1 deraadt 149: }
150:
1.2 millert 151: int
1.1 deraadt 152: doin()
153: {
1.3 millert 154: KEYMAP *curmap;
155: PF funct;
1.1 deraadt 156:
157: #ifndef NO_DPROMPT
1.2 millert 158: *(promptp = prompt) = '\0';
1.3 millert 159: #endif /* !NO_DPROMPT */
1.2 millert 160: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
161: key.k_count = 0;
162: while ((funct = doscan(curmap, (key.k_chars[key.k_count++] =
1.6 ! art 163: getkey(TRUE)))) == NULL)
1.2 millert 164: curmap = ele->k_prefmap;
1.1 deraadt 165: #ifndef NO_MACRO
1.2 millert 166: if (macrodef && macrocount < MAXMACRO)
167: macro[macrocount++].m_funct = funct;
1.3 millert 168: #endif /* !NO_MACRO */
169: return (*funct)(0, 1);
1.1 deraadt 170: }
171:
1.2 millert 172: int
1.1 deraadt 173: rescan(f, n)
1.3 millert 174: int f, n;
1.1 deraadt 175: {
1.3 millert 176: int c;
177: KEYMAP *curmap;
178: int i;
179: PF fp = NULL;
180: int mode = curbp->b_nmodes;
1.2 millert 181:
182: for (;;) {
183: if (ISUPPER(key.k_chars[key.k_count - 1])) {
184: c = TOLOWER(key.k_chars[key.k_count - 1]);
185: curmap = curbp->b_modes[mode]->p_map;
186: for (i = 0; i < key.k_count - 1; i++) {
1.3 millert 187: if ((fp = doscan(curmap, (key.k_chars[i])))
1.6 ! art 188: != NULL)
1.2 millert 189: break;
190: curmap = ele->k_prefmap;
191: }
1.6 ! art 192: if (fp == NULL) {
! 193: if ((fp = doscan(curmap, c)) == NULL)
1.2 millert 194: while ((fp = doscan(curmap,
195: key.k_chars[key.k_count++] =
1.6 ! art 196: getkey(TRUE))) == NULL)
1.2 millert 197: curmap = ele->k_prefmap;
198: if (fp != rescan) {
199: #ifndef NO_MACRO
200: if (macrodef && macrocount <= MAXMACRO)
1.3 millert 201: macro[macrocount - 1].m_funct
202: = fp;
203: #endif /* !NO_MACRO */
204: return (*fp)(f, n);
1.2 millert 205: }
206: }
207: }
208: /* try previous mode */
209: if (--mode < 0)
210: return ABORT;
211: curmap = curbp->b_modes[mode]->p_map;
212: for (i = 0; i < key.k_count; i++) {
1.6 ! art 213: if ((fp = doscan(curmap, (key.k_chars[i]))) != NULL)
1.2 millert 214: break;
1.1 deraadt 215: curmap = ele->k_prefmap;
1.2 millert 216: }
1.6 ! art 217: if (fp == NULL) {
1.3 millert 218: while ((fp = doscan(curmap, key.k_chars[i++] =
1.6 ! art 219: getkey(TRUE))) == NULL)
1.2 millert 220: curmap = ele->k_prefmap;
221: key.k_count = i;
222: }
223: if (fp != rescan && i >= key.k_count - 1) {
1.1 deraadt 224: #ifndef NO_MACRO
1.2 millert 225: if (macrodef && macrocount <= MAXMACRO)
226: macro[macrocount - 1].m_funct = fp;
1.3 millert 227: #endif /* !NO_MACRO */
228: return (*fp)(f, n);
1.1 deraadt 229: }
230: }
1.2 millert 231: }
232:
233: int
234: universal_argument(f, n)
1.3 millert 235: int f, n;
1.2 millert 236: {
1.3 millert 237: KEYMAP *curmap;
238: PF funct;
239: int c;
240: int nn = 4;
1.2 millert 241:
242: if (f & FFUNIV)
243: nn *= n;
244: for (;;) {
245: key.k_chars[0] = c = getkey(TRUE);
246: key.k_count = 1;
247: if (c == '-')
248: return negative_argument(f, nn);
249: if (c >= '0' && c <= '9')
250: return digit_argument(f, nn);
251: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.6 ! art 252: while ((funct = doscan(curmap, c)) == NULL) {
1.2 millert 253: curmap = ele->k_prefmap;
254: key.k_chars[key.k_count++] = c = getkey(TRUE);
255: }
256: if (funct != universal_argument) {
1.1 deraadt 257: #ifndef NO_MACRO
1.2 millert 258: if (macrodef && macrocount < MAXMACRO - 1) {
259: if (f & FFARG)
260: macrocount--;
261: macro[macrocount++].m_count = nn;
262: macro[macrocount++].m_funct = funct;
263: }
1.3 millert 264: #endif /* !NO_MACRO */
265: return (*funct)(FFUNIV, nn);
1.2 millert 266: }
267: nn <<= 2;
1.1 deraadt 268: }
269: }
270:
1.2 millert 271: /* ARGSUSED */
272: int
273: digit_argument(f, n)
1.3 millert 274: int f, n;
1.1 deraadt 275: {
1.3 millert 276: KEYMAP *curmap;
277: PF funct;
278: int nn, c;
1.2 millert 279:
280: nn = key.k_chars[key.k_count - 1] - '0';
281: for (;;) {
282: c = getkey(TRUE);
283: if (c < '0' || c > '9')
284: break;
285: nn *= 10;
286: nn += c - '0';
287: }
288: key.k_chars[0] = c;
1.1 deraadt 289: key.k_count = 1;
290: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.6 ! art 291: while ((funct = doscan(curmap, c)) == NULL) {
1.2 millert 292: curmap = ele->k_prefmap;
293: key.k_chars[key.k_count++] = c = getkey(TRUE);
1.1 deraadt 294: }
295: #ifndef NO_MACRO
1.2 millert 296: if (macrodef && macrocount < MAXMACRO - 1) {
297: if (f & FFARG)
298: macrocount--;
299: else
300: macro[macrocount - 1].m_funct = universal_argument;
1.1 deraadt 301: macro[macrocount++].m_count = nn;
302: macro[macrocount++].m_funct = funct;
303: }
1.3 millert 304: #endif /* !NO_MACRO */
305: return (*funct)(FFOTHARG, nn);
1.1 deraadt 306: }
307:
1.2 millert 308: int
1.1 deraadt 309: negative_argument(f, n)
1.3 millert 310: int f, n;
1.1 deraadt 311: {
1.3 millert 312: KEYMAP *curmap;
313: PF funct;
314: int c;
315: int nn = 0;
1.2 millert 316:
317: for (;;) {
318: c = getkey(TRUE);
319: if (c < '0' || c > '9')
320: break;
321: nn *= 10;
322: nn += c - '0';
323: }
324: if (nn)
325: nn = -nn;
326: else
327: nn = -n;
328: key.k_chars[0] = c;
329: key.k_count = 1;
330: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.6 ! art 331: while ((funct = doscan(curmap, c)) == NULL) {
1.2 millert 332: curmap = ele->k_prefmap;
333: key.k_chars[key.k_count++] = c = getkey(TRUE);
334: }
1.1 deraadt 335: #ifndef NO_MACRO
1.2 millert 336: if (macrodef && macrocount < MAXMACRO - 1) {
337: if (f & FFARG)
338: macrocount--;
339: else
340: macro[macrocount - 1].m_funct = universal_argument;
341: macro[macrocount++].m_count = nn;
342: macro[macrocount++].m_funct = funct;
343: }
1.3 millert 344: #endif /* !NO_MACRO */
345: return (*funct)(FFNEGARG, nn);
1.1 deraadt 346: }
347:
348: /*
349: * Insert a character. While defining a macro, create a "LINE" containing
350: * all inserted characters.
351: */
1.2 millert 352: int
1.1 deraadt 353: selfinsert(f, n)
1.3 millert 354: int f, n;
1.1 deraadt 355: {
356: #ifndef NO_MACRO
1.3 millert 357: LINE *lp;
358: #endif /* !NO_MACRO */
359: int c;
360: int count;
1.1 deraadt 361:
1.2 millert 362: if (n < 0)
363: return FALSE;
364: if (n == 0)
365: return TRUE;
366: c = key.k_chars[key.k_count - 1];
1.1 deraadt 367: #ifndef NO_MACRO
1.2 millert 368: if (macrodef && macrocount < MAXMACRO) {
369: if (f & FFARG)
370: macrocount -= 2;
1.3 millert 371:
372: /* last command was insert -- tack on the end */
373: if (lastflag & CFINS) {
1.2 millert 374: macrocount--;
375: if (maclcur->l_size < maclcur->l_used + n) {
376: if ((lp = lallocx(maclcur->l_used + n)) == NULL)
377: return FALSE;
378: lp->l_fp = maclcur->l_fp;
379: lp->l_bp = maclcur->l_bp;
380: lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
1.3 millert 381: bcopy(maclcur->l_text, lp->l_text,
382: maclcur->l_used);
383: for (count = maclcur->l_used;
384: count < lp->l_used; count++)
1.2 millert 385: lp->l_text[count] = c;
1.3 millert 386: free((char *)maclcur);
1.2 millert 387: maclcur = lp;
388: } else {
389: maclcur->l_used += n;
390: for (count = maclcur->l_used - n;
391: count < maclcur->l_used; count++)
392: maclcur->l_text[count] = c;
393: }
394: } else {
395: macro[macrocount - 1].m_funct = insert;
396: if ((lp = lallocx(n)) == NULL)
397: return FALSE;
398: lp->l_bp = maclcur;
399: lp->l_fp = maclcur->l_fp;
400: maclcur->l_fp = lp;
401: maclcur = lp;
402: for (count = 0; count < n; count++)
403: lp->l_text[count] = c;
404: }
405: thisflag |= CFINS;
406: }
1.3 millert 407: #endif /* !NO_MACRO */
1.2 millert 408: if (c == '\n') {
409: do {
410: count = lnewline();
411: } while (--n && count == TRUE);
412: return count;
413: }
1.3 millert 414:
415: /* overwrite mode */
416: if (curbp->b_flag & BFOVERWRITE) {
1.2 millert 417: lchange(WFEDIT);
418: while (curwp->w_doto < llength(curwp->w_dotp) && n--)
419: lputc(curwp->w_dotp, curwp->w_doto++, c);
420: if (n <= 0)
421: return TRUE;
422: }
423: return linsert(n, c);
1.1 deraadt 424: }
425:
426: /*
1.3 millert 427: * This could be implemented as a keymap with everthing defined as self-insert.
1.1 deraadt 428: */
1.2 millert 429: int
1.1 deraadt 430: quote(f, n)
1.3 millert 431: int f, n;
1.1 deraadt 432: {
1.3 millert 433: int c;
1.1 deraadt 434:
1.2 millert 435: key.k_count = 1;
436: if ((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
437: key.k_chars[0] -= '0';
438: if ((c = getkey(TRUE)) >= '0' && c <= '7') {
439: key.k_chars[0] <<= 3;
440: key.k_chars[0] += c - '0';
441: if ((c = getkey(TRUE)) >= '0' && c <= '7') {
442: key.k_chars[0] <<= 3;
443: key.k_chars[0] += c - '0';
444: } else
445: ungetkey(c);
446: } else
447: ungetkey(c);
448: }
449: return selfinsert(f, n);
1.1 deraadt 450: }