[BACK]Return to kbd.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

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: }