[BACK]Return to xterm-keys.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/xterm-keys.c, Revision 1.11

1.11    ! nicm        1: /* $OpenBSD: xterm-keys.c,v 1.10 2011/06/23 10:02:49 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/types.h>
                     20:
                     21: #include <string.h>
                     22:
                     23: #include "tmux.h"
                     24:
                     25: /*
                     26:  * xterm-style function keys append one of the following values before the last
                     27:  * character:
                     28:  *
                     29:  * 2 Shift
1.5       nicm       30:  * 3 Alt
                     31:  * 4 Shift + Alt
                     32:  * 5 Ctrl
                     33:  * 6 Shift + Ctrl
                     34:  * 7 Alt + Ctrl
1.1       nicm       35:  * 8 Shift + Alt + Ctrl
                     36:  *
                     37:  * Rather than parsing them, just match against a table.
                     38:  *
1.10      nicm       39:  * There are three forms for F1-F4 (\\033O_P and \\033O1;_P and \\033[1;_P).
                     40:  * We accept any but always output the latter (it comes first in the table).
1.1       nicm       41:  */
                     42:
                     43: int    xterm_keys_match(const char *, const char *, size_t);
                     44: int    xterm_keys_modifiers(const char *, const char *, size_t);
                     45:
                     46: struct xterm_keys_entry {
                     47:        int              key;
                     48:        const char      *template;
                     49: };
                     50:
1.8       nicm       51: const struct xterm_keys_entry xterm_keys_table[] = {
1.1       nicm       52:        { KEYC_F1,      "\033[1;_P" },
1.10      nicm       53:        { KEYC_F1,      "\033O1;_P" },
1.3       nicm       54:        { KEYC_F1,      "\033O_P" },
1.1       nicm       55:        { KEYC_F2,      "\033[1;_Q" },
1.10      nicm       56:        { KEYC_F2,      "\033O1;_Q" },
1.3       nicm       57:        { KEYC_F2,      "\033O_Q" },
1.1       nicm       58:        { KEYC_F3,      "\033[1;_R" },
1.10      nicm       59:        { KEYC_F3,      "\033O1;_R" },
1.3       nicm       60:        { KEYC_F3,      "\033O_R" },
1.1       nicm       61:        { KEYC_F4,      "\033[1;_S" },
1.10      nicm       62:        { KEYC_F4,      "\033O1;_S" },
1.3       nicm       63:        { KEYC_F4,      "\033O_S" },
1.1       nicm       64:        { KEYC_F5,      "\033[15;_~" },
                     65:        { KEYC_F6,      "\033[17;_~" },
                     66:        { KEYC_F7,      "\033[18;_~" },
                     67:        { KEYC_F8,      "\033[19;_~" },
                     68:        { KEYC_F9,      "\033[20;_~" },
                     69:        { KEYC_F10,     "\033[21;_~" },
                     70:        { KEYC_F11,     "\033[23;_~" },
                     71:        { KEYC_F12,     "\033[24;_~" },
                     72:        { KEYC_F13,     "\033[25;_~" },
                     73:        { KEYC_F14,     "\033[26;_~" },
                     74:        { KEYC_F15,     "\033[28;_~" },
                     75:        { KEYC_F16,     "\033[29;_~" },
                     76:        { KEYC_F17,     "\033[31;_~" },
                     77:        { KEYC_F18,     "\033[32;_~" },
                     78:        { KEYC_F19,     "\033[33;_~" },
                     79:        { KEYC_F20,     "\033[34;_~" },
                     80:        { KEYC_UP,      "\033[1;_A" },
                     81:        { KEYC_DOWN,    "\033[1;_B" },
                     82:        { KEYC_RIGHT,   "\033[1;_C" },
                     83:        { KEYC_LEFT,    "\033[1;_D" },
                     84:        { KEYC_HOME,    "\033[1;_H" },
                     85:        { KEYC_END,     "\033[1;_F" },
                     86:        { KEYC_PPAGE,   "\033[5;_~" },
                     87:        { KEYC_NPAGE,   "\033[6;_~" },
                     88:        { KEYC_IC,      "\033[2;_~" },
                     89:        { KEYC_DC,      "\033[3;_~" },
1.11    ! nicm       90:
        !            91:        { '!',          "\033[27;_;33~" },
        !            92:        { '#',          "\033[27;_;35~" },
        !            93:        { '(',          "\033[27;_;40~" },
        !            94:        { ')',          "\033[27;_;41~" },
        !            95:        { '+',          "\033[27;_;43~" },
        !            96:        { ',',          "\033[27;_;44~" },
        !            97:        { '-',          "\033[27;_;45~" },
        !            98:        { '.',          "\033[27;_;46~" },
        !            99:        { '0',          "\033[27;_;48~" },
        !           100:        { '1',          "\033[27;_;49~" },
        !           101:        { '2',          "\033[27;_;50~" },
        !           102:        { '3',          "\033[27;_;51~" },
        !           103:        { '4',          "\033[27;_;52~" },
        !           104:        { '5',          "\033[27;_;53~" },
        !           105:        { '6',          "\033[27;_;54~" },
        !           106:        { '7',          "\033[27;_;55~" },
        !           107:        { '8',          "\033[27;_;56~" },
        !           108:        { '9',          "\033[27;_;57~" },
        !           109:        { ':',          "\033[27;_;58~" },
        !           110:        { ';',          "\033[27;_;59~" },
        !           111:        { '<',          "\033[27;_;60~" },
        !           112:        { '=',          "\033[27;_;61~" },
        !           113:        { '>',          "\033[27;_;62~" },
        !           114:        { '?',          "\033[27;_;63~" },
        !           115:        { '\'',         "\033[27;_;39~" },
        !           116:        { '\r',         "\033[27;_;13~" },
        !           117:        { '\t',         "\033[27;_;9~" },
1.1       nicm      118: };
                    119:
1.5       nicm      120: /*
1.4       nicm      121:  * Match key against buffer, treating _ as a wildcard. Return -1 for no match,
                    122:  * 0 for match, 1 if the end of the buffer is reached (need more data).
                    123:  */
1.1       nicm      124: int
                    125: xterm_keys_match(const char *template, const char *buf, size_t len)
                    126: {
                    127:        size_t  pos;
                    128:
1.4       nicm      129:        if (len == 0)
1.1       nicm      130:                return (0);
                    131:
                    132:        pos = 0;
                    133:        do {
                    134:                if (*template != '_' && buf[pos] != *template)
1.4       nicm      135:                        return (-1);
1.1       nicm      136:        } while (pos++ != len && *++template != '\0');
                    137:
1.4       nicm      138:        if (*template != '\0')  /* partial */
                    139:                return (1);
                    140:
                    141:        return (0);
1.1       nicm      142: }
                    143:
                    144: /* Find modifiers based on template. */
                    145: int
                    146: xterm_keys_modifiers(const char *template, const char *buf, size_t len)
                    147: {
                    148:        size_t  idx;
1.6       nicm      149:        int     param, modifiers;
1.1       nicm      150:
                    151:        idx = strcspn(template, "_");
                    152:        if (idx >= len)
                    153:                return (0);
1.6       nicm      154:        param = buf[idx] - '1';
                    155:
                    156:        modifiers = 0;
                    157:        if (param & 1)
                    158:                modifiers |= KEYC_SHIFT;
                    159:        if (param & 2)
                    160:                modifiers |= KEYC_ESCAPE;
                    161:        if (param & 4)
                    162:                modifiers |= KEYC_CTRL;
1.7       nicm      163:        if (param & 8)
                    164:                modifiers |= KEYC_ESCAPE;
1.6       nicm      165:        return (modifiers);
1.1       nicm      166: }
                    167:
1.4       nicm      168: /*
                    169:  * Lookup key from a buffer against the table. Returns 0 for found (and the
                    170:  * key), -1 for not found, 1 for partial match.
                    171:  */
1.1       nicm      172: int
1.4       nicm      173: xterm_keys_find(const char *buf, size_t len, size_t *size, int *key)
1.1       nicm      174: {
1.8       nicm      175:        const struct xterm_keys_entry   *entry;
                    176:        u_int                            i;
1.1       nicm      177:
                    178:        for (i = 0; i < nitems(xterm_keys_table); i++) {
                    179:                entry = &xterm_keys_table[i];
1.4       nicm      180:                switch (xterm_keys_match(entry->template, buf, len)) {
                    181:                case 0:
                    182:                        *size = strlen(entry->template);
                    183:                        *key = entry->key;
                    184:                        *key |= xterm_keys_modifiers(entry->template, buf, len);
                    185:                        return (0);
                    186:                case 1:
                    187:                        return (1);
                    188:                }
1.1       nicm      189:        }
1.4       nicm      190:        return (-1);
1.1       nicm      191: }
                    192:
                    193: /* Lookup a key number from the table. */
                    194: char *
                    195: xterm_keys_lookup(int key)
                    196: {
1.8       nicm      197:        const struct xterm_keys_entry   *entry;
                    198:        u_int                            i;
                    199:        int                              modifiers;
                    200:        char                            *out;
1.1       nicm      201:
1.6       nicm      202:        modifiers = 1;
                    203:        if (key & KEYC_SHIFT)
                    204:                modifiers += 1;
                    205:        if (key & KEYC_ESCAPE)
                    206:                modifiers += 2;
                    207:        if (key & KEYC_CTRL)
                    208:                modifiers += 4;
1.1       nicm      209:
                    210:        /*
                    211:         * If the key has no modifiers, return NULL and let it fall through to
                    212:         * the normal lookup.
                    213:         */
1.6       nicm      214:        if (modifiers == 1)
1.1       nicm      215:                return (NULL);
                    216:
                    217:        /* Otherwise, find the key in the table. */
                    218:        key &= ~(KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL);
                    219:        for (i = 0; i < nitems(xterm_keys_table); i++) {
                    220:                entry = &xterm_keys_table[i];
                    221:                if (key == entry->key)
                    222:                        break;
                    223:        }
                    224:        if (i == nitems(xterm_keys_table))
                    225:                return (NULL);
1.5       nicm      226:
1.1       nicm      227:        /* Copy the template and replace the modifier. */
                    228:        out = xstrdup(entry->template);
                    229:        out[strcspn(out, "_")] = '0' + modifiers;
                    230:        return (out);
                    231: }