Annotation of src/usr.bin/mg/kbd.c, Revision 1.7
1.7 ! art 1: /* $OpenBSD: kbd.c,v 1.6 2001/05/23 16:14:00 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
1.7 ! art 134: doscan(map, c, newmap)
1.2 millert 135: KEYMAP *map;
136: int c;
1.7 ! art 137: KEYMAP **newmap;
1.2 millert 138: {
1.3 millert 139: MAP_ELEMENT *elec = &map->map_element[0];
140: MAP_ELEMENT *last = &map->map_element[map->map_num];
1.7 ! art 141: PF ret;
1.1 deraadt 142:
1.2 millert 143: while (elec < last && c > elec->k_num)
144: elec++;
1.3 millert 145:
146: /* used by prefix and binding code */
147: ele = elec;
1.2 millert 148: if (elec >= last || c < elec->k_base)
1.7 ! art 149: ret = map->map_default;
! 150: else
! 151: ret = elec->k_funcp[c - elec->k_base];
! 152: if (ret == NULL && newmap != NULL)
! 153: *newmap = elec->k_prefmap;
! 154:
! 155: return ret;
1.1 deraadt 156: }
157:
1.2 millert 158: int
1.1 deraadt 159: doin()
160: {
1.3 millert 161: KEYMAP *curmap;
162: PF funct;
1.1 deraadt 163:
164: #ifndef NO_DPROMPT
1.2 millert 165: *(promptp = prompt) = '\0';
1.3 millert 166: #endif /* !NO_DPROMPT */
1.2 millert 167: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
168: key.k_count = 0;
169: while ((funct = doscan(curmap, (key.k_chars[key.k_count++] =
1.7 ! art 170: getkey(TRUE)), &curmap)) == NULL)
! 171: /*nothing*/;
1.1 deraadt 172: #ifndef NO_MACRO
1.2 millert 173: if (macrodef && macrocount < MAXMACRO)
174: macro[macrocount++].m_funct = funct;
1.3 millert 175: #endif /* !NO_MACRO */
176: return (*funct)(0, 1);
1.1 deraadt 177: }
178:
1.2 millert 179: int
1.1 deraadt 180: rescan(f, n)
1.3 millert 181: int f, n;
1.1 deraadt 182: {
1.3 millert 183: int c;
184: KEYMAP *curmap;
185: int i;
186: PF fp = NULL;
187: int mode = curbp->b_nmodes;
1.2 millert 188:
189: for (;;) {
190: if (ISUPPER(key.k_chars[key.k_count - 1])) {
191: c = TOLOWER(key.k_chars[key.k_count - 1]);
192: curmap = curbp->b_modes[mode]->p_map;
193: for (i = 0; i < key.k_count - 1; i++) {
1.7 ! art 194: if ((fp = doscan(curmap, (key.k_chars[i]), &curmap))
1.6 art 195: != NULL)
1.2 millert 196: break;
197: }
1.6 art 198: if (fp == NULL) {
1.7 ! art 199: if ((fp = doscan(curmap, c, NULL)) == NULL)
1.2 millert 200: while ((fp = doscan(curmap,
201: key.k_chars[key.k_count++] =
1.7 ! art 202: getkey(TRUE), &curmap)) == NULL)
! 203: /*nothing*/;
1.2 millert 204: if (fp != rescan) {
205: #ifndef NO_MACRO
206: if (macrodef && macrocount <= MAXMACRO)
1.3 millert 207: macro[macrocount - 1].m_funct
208: = fp;
209: #endif /* !NO_MACRO */
210: return (*fp)(f, n);
1.2 millert 211: }
212: }
213: }
214: /* try previous mode */
215: if (--mode < 0)
216: return ABORT;
217: curmap = curbp->b_modes[mode]->p_map;
218: for (i = 0; i < key.k_count; i++) {
1.7 ! art 219: if ((fp = doscan(curmap, (key.k_chars[i]), &curmap)) != NULL)
1.2 millert 220: break;
221: }
1.6 art 222: if (fp == NULL) {
1.3 millert 223: while ((fp = doscan(curmap, key.k_chars[i++] =
1.7 ! art 224: getkey(TRUE), &curmap)) == NULL)
! 225: /*nothing*/;
1.2 millert 226: key.k_count = i;
227: }
228: if (fp != rescan && i >= key.k_count - 1) {
1.1 deraadt 229: #ifndef NO_MACRO
1.2 millert 230: if (macrodef && macrocount <= MAXMACRO)
231: macro[macrocount - 1].m_funct = fp;
1.3 millert 232: #endif /* !NO_MACRO */
233: return (*fp)(f, n);
1.1 deraadt 234: }
235: }
1.2 millert 236: }
237:
238: int
239: universal_argument(f, n)
1.3 millert 240: int f, n;
1.2 millert 241: {
1.3 millert 242: KEYMAP *curmap;
243: PF funct;
244: int c;
245: int nn = 4;
1.2 millert 246:
247: if (f & FFUNIV)
248: nn *= n;
249: for (;;) {
250: key.k_chars[0] = c = getkey(TRUE);
251: key.k_count = 1;
252: if (c == '-')
253: return negative_argument(f, nn);
254: if (c >= '0' && c <= '9')
255: return digit_argument(f, nn);
256: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.7 ! art 257: while ((funct = doscan(curmap, c, &curmap)) == NULL) {
1.2 millert 258: key.k_chars[key.k_count++] = c = getkey(TRUE);
259: }
260: if (funct != universal_argument) {
1.1 deraadt 261: #ifndef NO_MACRO
1.2 millert 262: if (macrodef && macrocount < MAXMACRO - 1) {
263: if (f & FFARG)
264: macrocount--;
265: macro[macrocount++].m_count = nn;
266: macro[macrocount++].m_funct = funct;
267: }
1.3 millert 268: #endif /* !NO_MACRO */
269: return (*funct)(FFUNIV, nn);
1.2 millert 270: }
271: nn <<= 2;
1.1 deraadt 272: }
273: }
274:
1.2 millert 275: /* ARGSUSED */
276: int
277: digit_argument(f, n)
1.3 millert 278: int f, n;
1.1 deraadt 279: {
1.3 millert 280: KEYMAP *curmap;
281: PF funct;
282: int nn, c;
1.2 millert 283:
284: nn = key.k_chars[key.k_count - 1] - '0';
285: for (;;) {
286: c = getkey(TRUE);
287: if (c < '0' || c > '9')
288: break;
289: nn *= 10;
290: nn += c - '0';
291: }
292: key.k_chars[0] = c;
1.1 deraadt 293: key.k_count = 1;
294: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.7 ! art 295: while ((funct = doscan(curmap, c, &curmap)) == NULL) {
1.2 millert 296: key.k_chars[key.k_count++] = c = getkey(TRUE);
1.1 deraadt 297: }
298: #ifndef NO_MACRO
1.2 millert 299: if (macrodef && macrocount < MAXMACRO - 1) {
300: if (f & FFARG)
301: macrocount--;
302: else
303: macro[macrocount - 1].m_funct = universal_argument;
1.1 deraadt 304: macro[macrocount++].m_count = nn;
305: macro[macrocount++].m_funct = funct;
306: }
1.3 millert 307: #endif /* !NO_MACRO */
308: return (*funct)(FFOTHARG, nn);
1.1 deraadt 309: }
310:
1.2 millert 311: int
1.1 deraadt 312: negative_argument(f, n)
1.3 millert 313: int f, n;
1.1 deraadt 314: {
1.3 millert 315: KEYMAP *curmap;
316: PF funct;
317: int c;
318: int nn = 0;
1.2 millert 319:
320: for (;;) {
321: c = getkey(TRUE);
322: if (c < '0' || c > '9')
323: break;
324: nn *= 10;
325: nn += c - '0';
326: }
327: if (nn)
328: nn = -nn;
329: else
330: nn = -n;
331: key.k_chars[0] = c;
332: key.k_count = 1;
333: curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
1.7 ! art 334: while ((funct = doscan(curmap, c, &curmap)) == NULL) {
1.2 millert 335: key.k_chars[key.k_count++] = c = getkey(TRUE);
336: }
1.1 deraadt 337: #ifndef NO_MACRO
1.2 millert 338: if (macrodef && macrocount < MAXMACRO - 1) {
339: if (f & FFARG)
340: macrocount--;
341: else
342: macro[macrocount - 1].m_funct = universal_argument;
343: macro[macrocount++].m_count = nn;
344: macro[macrocount++].m_funct = funct;
345: }
1.3 millert 346: #endif /* !NO_MACRO */
347: return (*funct)(FFNEGARG, nn);
1.1 deraadt 348: }
349:
350: /*
351: * Insert a character. While defining a macro, create a "LINE" containing
352: * all inserted characters.
353: */
1.2 millert 354: int
1.1 deraadt 355: selfinsert(f, n)
1.3 millert 356: int f, n;
1.1 deraadt 357: {
358: #ifndef NO_MACRO
1.3 millert 359: LINE *lp;
360: #endif /* !NO_MACRO */
361: int c;
362: int count;
1.1 deraadt 363:
1.2 millert 364: if (n < 0)
365: return FALSE;
366: if (n == 0)
367: return TRUE;
368: c = key.k_chars[key.k_count - 1];
1.1 deraadt 369: #ifndef NO_MACRO
1.2 millert 370: if (macrodef && macrocount < MAXMACRO) {
371: if (f & FFARG)
372: macrocount -= 2;
1.3 millert 373:
374: /* last command was insert -- tack on the end */
375: if (lastflag & CFINS) {
1.2 millert 376: macrocount--;
377: if (maclcur->l_size < maclcur->l_used + n) {
378: if ((lp = lallocx(maclcur->l_used + n)) == NULL)
379: return FALSE;
380: lp->l_fp = maclcur->l_fp;
381: lp->l_bp = maclcur->l_bp;
382: lp->l_fp->l_bp = lp->l_bp->l_fp = lp;
1.3 millert 383: bcopy(maclcur->l_text, lp->l_text,
384: maclcur->l_used);
385: for (count = maclcur->l_used;
386: count < lp->l_used; count++)
1.2 millert 387: lp->l_text[count] = c;
1.3 millert 388: free((char *)maclcur);
1.2 millert 389: maclcur = lp;
390: } else {
391: maclcur->l_used += n;
392: for (count = maclcur->l_used - n;
393: count < maclcur->l_used; count++)
394: maclcur->l_text[count] = c;
395: }
396: } else {
397: macro[macrocount - 1].m_funct = insert;
398: if ((lp = lallocx(n)) == NULL)
399: return FALSE;
400: lp->l_bp = maclcur;
401: lp->l_fp = maclcur->l_fp;
402: maclcur->l_fp = lp;
403: maclcur = lp;
404: for (count = 0; count < n; count++)
405: lp->l_text[count] = c;
406: }
407: thisflag |= CFINS;
408: }
1.3 millert 409: #endif /* !NO_MACRO */
1.2 millert 410: if (c == '\n') {
411: do {
412: count = lnewline();
413: } while (--n && count == TRUE);
414: return count;
415: }
1.3 millert 416:
417: /* overwrite mode */
418: if (curbp->b_flag & BFOVERWRITE) {
1.2 millert 419: lchange(WFEDIT);
420: while (curwp->w_doto < llength(curwp->w_dotp) && n--)
421: lputc(curwp->w_dotp, curwp->w_doto++, c);
422: if (n <= 0)
423: return TRUE;
424: }
425: return linsert(n, c);
1.1 deraadt 426: }
427:
428: /*
1.3 millert 429: * This could be implemented as a keymap with everthing defined as self-insert.
1.1 deraadt 430: */
1.2 millert 431: int
1.1 deraadt 432: quote(f, n)
1.3 millert 433: int f, n;
1.1 deraadt 434: {
1.3 millert 435: int c;
1.1 deraadt 436:
1.2 millert 437: key.k_count = 1;
438: if ((key.k_chars[0] = getkey(TRUE)) >= '0' && key.k_chars[0] <= '7') {
439: key.k_chars[0] -= '0';
440: if ((c = getkey(TRUE)) >= '0' && c <= '7') {
441: key.k_chars[0] <<= 3;
442: key.k_chars[0] += c - '0';
443: if ((c = getkey(TRUE)) >= '0' && c <= '7') {
444: key.k_chars[0] <<= 3;
445: key.k_chars[0] += c - '0';
446: } else
447: ungetkey(c);
448: } else
449: ungetkey(c);
450: }
451: return selfinsert(f, n);
1.1 deraadt 452: }