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