[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.1

1.1     ! nicm        1: /* $OpenBSD: input-keys.c,v 1.4 2009/10/11 07:01:10 nicm Exp $ */
        !             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
        !            30:  * 3 Alt
        !            31:  * 4 Shift + Alt
        !            32:  * 5 Ctrl
        !            33:  * 6 Shift + Ctrl
        !            34:  * 7 Alt + Ctrl
        !            35:  * 8 Shift + Alt + Ctrl
        !            36:  *
        !            37:  * Rather than parsing them, just match against a table.
        !            38:  *
        !            39:  * There are two forms for F1-F4 (\\033O_P or \\033[1;_P). We accept either but
        !            40:  * always output the latter (it comes first in the table).
        !            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:
        !            51: struct xterm_keys_entry xterm_keys_table[] = {
        !            52:        { KEYC_F1,      "\033[1;_P" },
        !            53:        { KEYC_F1,      "\033[O_P" },
        !            54:        { KEYC_F2,      "\033[1;_Q" },
        !            55:        { KEYC_F2,      "\033[O_Q" },
        !            56:        { KEYC_F3,      "\033[1;_R" },
        !            57:        { KEYC_F3,      "\033[O_R" },
        !            58:        { KEYC_F4,      "\033[1;_S" },
        !            59:        { KEYC_F4,      "\033[O_S" },
        !            60:        { KEYC_F5,      "\033[15;_~" },
        !            61:        { KEYC_F6,      "\033[17;_~" },
        !            62:        { KEYC_F7,      "\033[18;_~" },
        !            63:        { KEYC_F8,      "\033[19;_~" },
        !            64:        { KEYC_F9,      "\033[20;_~" },
        !            65:        { KEYC_F10,     "\033[21;_~" },
        !            66:        { KEYC_F11,     "\033[23;_~" },
        !            67:        { KEYC_F12,     "\033[24;_~" },
        !            68:        { KEYC_F13,     "\033[25;_~" },
        !            69:        { KEYC_F14,     "\033[26;_~" },
        !            70:        { KEYC_F15,     "\033[28;_~" },
        !            71:        { KEYC_F16,     "\033[29;_~" },
        !            72:        { KEYC_F17,     "\033[31;_~" },
        !            73:        { KEYC_F18,     "\033[32;_~" },
        !            74:        { KEYC_F19,     "\033[33;_~" },
        !            75:        { KEYC_F20,     "\033[34;_~" },
        !            76:        { KEYC_UP,      "\033[1;_A" },
        !            77:        { KEYC_DOWN,    "\033[1;_B" },
        !            78:        { KEYC_RIGHT,   "\033[1;_C" },
        !            79:        { KEYC_LEFT,    "\033[1;_D" },
        !            80:        { KEYC_HOME,    "\033[1;_H" },
        !            81:        { KEYC_END,     "\033[1;_F" },
        !            82:        { KEYC_PPAGE,   "\033[5;_~" },
        !            83:        { KEYC_NPAGE,   "\033[6;_~" },
        !            84:        { KEYC_IC,      "\033[2;_~" },
        !            85:        { KEYC_DC,      "\033[3;_~" },
        !            86: };
        !            87:
        !            88: /* Match key against buffer, treating _ as a wildcard. */
        !            89: int
        !            90: xterm_keys_match(const char *template, const char *buf, size_t len)
        !            91: {
        !            92:        size_t  pos;
        !            93:
        !            94:        if (len == 0 || len < strlen(template))
        !            95:                return (0);
        !            96:
        !            97:        pos = 0;
        !            98:        do {
        !            99:                if (*template != '_' && buf[pos] != *template)
        !           100:                        return (0);
        !           101:        } while (pos++ != len && *++template != '\0');
        !           102:
        !           103:        return (1);
        !           104: }
        !           105:
        !           106: /* Find modifiers based on template. */
        !           107: int
        !           108: xterm_keys_modifiers(const char *template, const char *buf, size_t len)
        !           109: {
        !           110:        size_t  idx;
        !           111:
        !           112:        idx = strcspn(template, "_");
        !           113:        if (idx >= len)
        !           114:                return (0);
        !           115:        switch (buf[idx]) {
        !           116:        case '2':
        !           117:                return (KEYC_SHIFT);
        !           118:        case '3':
        !           119:                return (KEYC_ESCAPE);
        !           120:        case '4':
        !           121:                return (KEYC_SHIFT|KEYC_ESCAPE);
        !           122:        case '5':
        !           123:                return (KEYC_CTRL);
        !           124:        case '6':
        !           125:                return (KEYC_SHIFT|KEYC_CTRL);
        !           126:        case '7':
        !           127:                return (KEYC_ESCAPE|KEYC_CTRL);
        !           128:        case '8':
        !           129:                return (KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL);
        !           130:        }
        !           131:        return (0);
        !           132: }
        !           133:
        !           134: /* Lookup key from buffer against table. */
        !           135: int
        !           136: xterm_keys_find(const char *buf, size_t len, size_t *size)
        !           137: {
        !           138:        struct xterm_keys_entry *entry;
        !           139:        u_int                    i;
        !           140:
        !           141:        for (i = 0; i < nitems(xterm_keys_table); i++) {
        !           142:                entry = &xterm_keys_table[i];
        !           143:                if (xterm_keys_match(entry->template, buf, len))
        !           144:                        break;
        !           145:        }
        !           146:        if (i == nitems(xterm_keys_table))
        !           147:                return (KEYC_NONE);
        !           148:        *size = strlen(entry->template);
        !           149:        log_debug("XXX %x %x", entry->key, xterm_keys_modifiers(entry->template, buf, len));
        !           150:        return (entry->key | xterm_keys_modifiers(entry->template, buf, len));
        !           151: }
        !           152:
        !           153: /* Lookup a key number from the table. */
        !           154: char *
        !           155: xterm_keys_lookup(int key)
        !           156: {
        !           157:        struct xterm_keys_entry *entry;
        !           158:        u_int                    i;
        !           159:        int                      modifiers;
        !           160:        char                    *out;
        !           161:
        !           162: #define KEY_MODIFIERS(key, modifiers) \
        !           163:        (((key) & (KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL)) == (modifiers))
        !           164:        modifiers = 0;
        !           165:        if (KEY_MODIFIERS(key, KEYC_SHIFT))
        !           166:                modifiers = 2;
        !           167:        else if (KEY_MODIFIERS(key, KEYC_ESCAPE))
        !           168:                modifiers = 3;
        !           169:        else if (KEY_MODIFIERS(key, KEYC_SHIFT|KEYC_ESCAPE))
        !           170:                modifiers = 4;
        !           171:        else if (KEY_MODIFIERS(key, KEYC_CTRL))
        !           172:                modifiers = 5;
        !           173:        else if (KEY_MODIFIERS(key, KEYC_SHIFT|KEYC_CTRL))
        !           174:                modifiers = 6;
        !           175:        else if (KEY_MODIFIERS(key, KEYC_ESCAPE|KEYC_CTRL))
        !           176:                modifiers = 7;
        !           177:        else if (KEY_MODIFIERS(key, KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL))
        !           178:                modifiers = 8;
        !           179: #undef KEY_MODIFIERS
        !           180:
        !           181:        /*
        !           182:         * If the key has no modifiers, return NULL and let it fall through to
        !           183:         * the normal lookup.
        !           184:         */
        !           185:        if (modifiers == 0)
        !           186:                return (NULL);
        !           187:
        !           188:        /* Otherwise, find the key in the table. */
        !           189:        key &= ~(KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL);
        !           190:        for (i = 0; i < nitems(xterm_keys_table); i++) {
        !           191:                entry = &xterm_keys_table[i];
        !           192:                if (key == entry->key)
        !           193:                        break;
        !           194:        }
        !           195:        if (i == nitems(xterm_keys_table))
        !           196:                return (NULL);
        !           197:
        !           198:        /* Copy the template and replace the modifier. */
        !           199:        out = xstrdup(entry->template);
        !           200:        out[strcspn(out, "_")] = '0' + modifiers;
        !           201:        return (out);
        !           202: }