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

Annotation of src/usr.bin/tmux/input-keys.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD$ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2007 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 <stdint.h>
        !            22: #include <stdlib.h>
        !            23: #include <string.h>
        !            24:
        !            25: #include "tmux.h"
        !            26:
        !            27: struct input_key_ent {
        !            28:        int              key;
        !            29:        const char      *data;
        !            30:
        !            31:        int              flags;
        !            32: #define INPUTKEY_KEYPAD 0x1    /* keypad key */
        !            33: #define INPUTKEY_CURSOR 0x2    /* cursor key */
        !            34: #define INPUTKEY_CTRL 0x4      /* may be modified with ctrl */
        !            35: #define INPUTKEY_XTERM 0x4     /* may have xterm argument appended */
        !            36: };
        !            37:
        !            38: struct input_key_ent input_keys[] = {
        !            39:        /* Function keys. */
        !            40:        { KEYC_F1,     "\033OP",   INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            41:        { KEYC_F2,     "\033OQ",   INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            42:        { KEYC_F3,     "\033OR",   INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            43:        { KEYC_F4,     "\033OS",   INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            44:        { KEYC_F5,     "\033[15~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            45:        { KEYC_F6,     "\033[17~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            46:        { KEYC_F7,     "\033[18~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            47:        { KEYC_F8,     "\033[19~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            48:        { KEYC_F9,     "\033[20~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            49:        { KEYC_F10,    "\033[21~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            50:        { KEYC_F11,    "\033[23~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            51:        { KEYC_F12,    "\033[24~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            52:        { KEYC_F13,    "\033[25~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            53:        { KEYC_F14,    "\033[26~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            54:        { KEYC_F15,    "\033[28~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            55:        { KEYC_F16,    "\033[29~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            56:        { KEYC_F17,    "\033[31~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            57:        { KEYC_F18,    "\033[32~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            58:        { KEYC_F19,    "\033[33~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            59:        { KEYC_F20,    "\033[34~", INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            60:        { KEYC_IC,     "\033[2~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            61:        { KEYC_DC,     "\033[3~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            62:        { KEYC_HOME,   "\033[1~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            63:        { KEYC_END,    "\033[4~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            64:        { KEYC_NPAGE,  "\033[6~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            65:        { KEYC_PPAGE,  "\033[5~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
        !            66:        { KEYC_BTAB,   "\033[Z",   INPUTKEY_CTRL },
        !            67:
        !            68:        /* Arrow keys. Cursor versions must come first. */
        !            69:        { KEYC_ADDCTL(KEYC_UP),    "\033Oa", 0 },
        !            70:        { KEYC_ADDCTL(KEYC_DOWN),  "\033Ob", 0 },
        !            71:        { KEYC_ADDCTL(KEYC_RIGHT), "\033Oc", 0 },
        !            72:        { KEYC_ADDCTL(KEYC_LEFT),  "\033Od", 0 },
        !            73:
        !            74:        { KEYC_ADDSFT(KEYC_UP),    "\033[a", 0 },
        !            75:        { KEYC_ADDSFT(KEYC_DOWN),  "\033[b", 0 },
        !            76:        { KEYC_ADDSFT(KEYC_RIGHT), "\033[c", 0 },
        !            77:        { KEYC_ADDSFT(KEYC_LEFT),  "\033[d", 0 },
        !            78:
        !            79:        { KEYC_UP,     "\033OA",   INPUTKEY_CURSOR },
        !            80:        { KEYC_DOWN,   "\033OB",   INPUTKEY_CURSOR },
        !            81:        { KEYC_RIGHT,  "\033OC",   INPUTKEY_CURSOR },
        !            82:        { KEYC_LEFT,   "\033OD",   INPUTKEY_CURSOR },
        !            83:
        !            84:        { KEYC_UP,     "\033[A",   0 },
        !            85:        { KEYC_DOWN,   "\033[B",   0 },
        !            86:        { KEYC_RIGHT,  "\033[C",   0 },
        !            87:        { KEYC_LEFT,   "\033[D",   0 },
        !            88:
        !            89:        /* Keypad keys. Keypad versions must come first. */
        !            90:        { KEYC_KP0_1,  "/", INPUTKEY_KEYPAD },
        !            91:        { KEYC_KP0_2,  "*", INPUTKEY_KEYPAD },
        !            92:        { KEYC_KP0_3,  "-", INPUTKEY_KEYPAD },
        !            93:        { KEYC_KP1_0,  "7", INPUTKEY_KEYPAD },
        !            94:        { KEYC_KP1_1,  "8", INPUTKEY_KEYPAD },
        !            95:        { KEYC_KP1_2,  "9", INPUTKEY_KEYPAD },
        !            96:        { KEYC_KP1_3,  "+", INPUTKEY_KEYPAD },
        !            97:        { KEYC_KP2_0,  "4", INPUTKEY_KEYPAD },
        !            98:        { KEYC_KP2_1,  "5", INPUTKEY_KEYPAD },
        !            99:        { KEYC_KP2_2,  "6", INPUTKEY_KEYPAD },
        !           100:        { KEYC_KP3_0,  "1", INPUTKEY_KEYPAD },
        !           101:        { KEYC_KP3_1,  "2", INPUTKEY_KEYPAD },
        !           102:        { KEYC_KP3_2,  "3", INPUTKEY_KEYPAD },
        !           103:        { KEYC_KP3_3,  "\n", INPUTKEY_KEYPAD }, /* this can be CRLF too? */
        !           104:        { KEYC_KP4_0,  "0", INPUTKEY_KEYPAD },
        !           105:        { KEYC_KP4_2,  ".", INPUTKEY_KEYPAD },
        !           106:        { KEYC_KP0_1,  "\033Oo", 0 },
        !           107:        { KEYC_KP0_2,  "\033Oj", 0 },
        !           108:        { KEYC_KP0_3,  "\033Om", 0 },
        !           109:        { KEYC_KP1_0,  "\033Ow", 0 },
        !           110:        { KEYC_KP1_1,  "\033Ox", 0 },
        !           111:        { KEYC_KP1_2,  "\033Oy", 0 },
        !           112:        { KEYC_KP1_3,  "\033Ok", 0 },
        !           113:        { KEYC_KP2_0,  "\033Ot", 0 },
        !           114:        { KEYC_KP2_1,  "\033Ou", 0 },
        !           115:        { KEYC_KP2_2,  "\033Ov", 0 },
        !           116:        { KEYC_KP3_0,  "\033Oq", 0 },
        !           117:        { KEYC_KP3_1,  "\033Or", 0 },
        !           118:        { KEYC_KP3_2,  "\033Os", 0 },
        !           119:        { KEYC_KP3_3,  "\033OM", 0 },
        !           120:        { KEYC_KP4_0,  "\033Op", 0 },
        !           121:        { KEYC_KP4_2,  "\033On", 0 },
        !           122: };
        !           123:
        !           124: /* Translate a key code from client into an output key sequence. */
        !           125: void
        !           126: input_key(struct window_pane *wp, int key)
        !           127: {
        !           128:        struct input_key_ent   *ike;
        !           129:        u_int                   i;
        !           130:        char                    ch;
        !           131:        size_t                  dlen;
        !           132:        int                     xterm_keys;
        !           133:
        !           134:        log_debug2("writing key 0x%x", key);
        !           135:
        !           136:        if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) {
        !           137:                if (KEYC_ISESC(key))
        !           138:                        buffer_write8(wp->out, '\033');
        !           139:                buffer_write8(wp->out, (uint8_t) KEYC_REMOVEESC(key));
        !           140:                return;
        !           141:        }
        !           142:
        !           143:        for (i = 0; i < nitems(input_keys); i++) {
        !           144:                ike = &input_keys[i];
        !           145:
        !           146:                if ((ike->flags & INPUTKEY_KEYPAD) &&
        !           147:                    !(wp->screen->mode & MODE_KKEYPAD))
        !           148:                        continue;
        !           149:                if ((ike->flags & INPUTKEY_CURSOR) &&
        !           150:                    !(wp->screen->mode & MODE_KCURSOR))
        !           151:                        continue;
        !           152:
        !           153:                if (KEYC_ISESC(key) && KEYC_ADDESC(ike->key) == key)
        !           154:                        break;
        !           155:                if (KEYC_ISSFT(key) && KEYC_ADDSFT(ike->key) == key)
        !           156:                        break;
        !           157:                if (KEYC_ISCTL(key) && KEYC_ADDCTL(ike->key) == key) {
        !           158:                        if (ike->flags & INPUTKEY_CTRL)
        !           159:                                break;
        !           160:                }
        !           161:                if (ike->key == key)
        !           162:                        break;
        !           163:        }
        !           164:        if (i == nitems(input_keys)) {
        !           165:                log_debug2("key 0x%x missing", key);
        !           166:                return;
        !           167:        }
        !           168:        dlen = strlen(ike->data);
        !           169:
        !           170:        log_debug2("found key 0x%x: \"%s\"", key, ike->data);
        !           171:
        !           172:        /*
        !           173:         * If in xterm keys mode, work out and append the modifier as an
        !           174:         * argument.
        !           175:         */
        !           176:        xterm_keys = options_get_number(&wp->window->options, "xterm-keys");
        !           177:        if (xterm_keys && ike->flags & INPUTKEY_XTERM) {
        !           178:                ch = '\0';
        !           179:                if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key))
        !           180:                        ch = '8';
        !           181:                else if (KEYC_ISESC(key) && KEYC_ISCTL(key))
        !           182:                        ch = '7';
        !           183:                else if (KEYC_ISSFT(key) && KEYC_ISCTL(key))
        !           184:                        ch = '6';
        !           185:                else if (KEYC_ISCTL(key))
        !           186:                        ch = '5';
        !           187:                else if (KEYC_ISSFT(key) && KEYC_ISESC(key))
        !           188:                        ch = '4';
        !           189:                else if (KEYC_ISESC(key))
        !           190:                        ch = '3';
        !           191:                else if (KEYC_ISSFT(key))
        !           192:                        ch = '2';
        !           193:                if (ch != '\0') {
        !           194:                        buffer_write(wp->out, ike->data, dlen - 1);
        !           195:                        buffer_write8(wp->out, ';');
        !           196:                        buffer_write8(wp->out, ch);
        !           197:                        buffer_write8(wp->out, ike->data[dlen - 1]);
        !           198:                } else
        !           199:                        buffer_write(wp->out, ike->data, dlen);
        !           200:                return;
        !           201:        }
        !           202:
        !           203:        /*
        !           204:         * Not in xterm mode. Prefix a \033 for escape, and set bit 5 of the
        !           205:         * last byte for ctrl.
        !           206:         */
        !           207:        if (KEYC_ISESC(key))
        !           208:                buffer_write8(wp->out, '\033');
        !           209:        if (KEYC_ISCTL(key) && ike->flags & INPUTKEY_CTRL) {
        !           210:                buffer_write(wp->out, ike->data, dlen - 1);
        !           211:                buffer_write8(wp->out, ike->data[dlen - 1] ^ 0x20);
        !           212:                return;
        !           213:        }
        !           214:        buffer_write(wp->out, ike->data, dlen);
        !           215: }
        !           216:
        !           217: /* Handle input mouse. */
        !           218: void
        !           219: input_mouse(struct window_pane *wp, u_char b, u_char x, u_char y)
        !           220: {
        !           221:        if (wp->screen->mode & MODE_MOUSE) {
        !           222:                buffer_write(wp->out, "\033[M", 3);
        !           223:                buffer_write8(wp->out, b + 32);
        !           224:                buffer_write8(wp->out, x + 33);
        !           225:                buffer_write8(wp->out, y + 33);
        !           226:        }
        !           227: }