/* Convert a key code into string format, with prefix if necessary. */ const char * key_string_lookup_key(key_code key) { static char out[24]; char tmp[8]; u_int i; struct utf8_data ud; *out = '\0'; /* Handle no key. */ if (key == KEYC_NONE) return ("None"); /* Handle special keys. */ if (key == KEYC_UNKNOWN) return ("Unknown"); if (key == KEYC_MOUSE) return ("Mouse"); /* * Special case: display C-@ as C-Space. Could do this below in * the (key >= 0 && key <= 32), but this way we let it be found * in key_string_table, for the unlikely chance that we might * change its name. */ if ((key & KEYC_MASK_KEY) == 0) key = ' ' | KEYC_CTRL | (key & KEYC_MASK_MOD); /* Fill in the modifiers. */ if (key & KEYC_CTRL) strlcat(out, "C-", sizeof out); if (key & KEYC_ESCAPE) strlcat(out, "M-", sizeof out); if (key & KEYC_SHIFT) strlcat(out, "S-", sizeof out); key &= KEYC_MASK_KEY; /* Try the key against the string table. */ for (i = 0; i < nitems(key_string_table); i++) { if (key == key_string_table[i].key) break; } if (i != nitems(key_string_table)) { strlcat(out, key_string_table[i].string, sizeof out); return (out); } /* Is this a UTF-8 key? */ if (key > 127 && key < KEYC_BASE) { if (utf8_split(key, &ud) == UTF8_DONE) { memcpy(out, ud.data, ud.size); out[ud.size] = '\0'; return (out); } } /* Invalid keys are errors. */ if (key == 127 || key > 255) { snprintf(out, sizeof out, "Invalid#%llx", key); return (out); } /* Check for standard or control key. */ if (key <= 32) { if (key == 0 || key > 26) xsnprintf(tmp, sizeof tmp, "C-%c", (int)(64 + key)); else xsnprintf(tmp, sizeof tmp, "C-%c", (int)(96 + key)); } else if (key >= 32 && key <= 126) { tmp[0] = key; tmp[1] = '\0'; } else if (key >= 128) xsnprintf(tmp, sizeof tmp, "\\%llo", key); strlcat(out, tmp, sizeof out); return (out); }
/* Translate a key code into an output key sequence. */ void input_key(struct window_pane *wp, key_code key, struct mouse_event *m) { const struct input_key_ent *ike; u_int i; size_t dlen; char *out; key_code justkey; struct utf8_data ud; log_debug("writing key 0x%llx (%s) to %%%u", key, key_string_lookup_key(key), wp->id); /* If this is a mouse key, pass off to mouse function. */ if (KEYC_IS_MOUSE(key)) { if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id) input_key_mouse(wp, m); return; } /* * If this is a normal 7-bit key, just send it, with a leading escape * if necessary. If it is a UTF-8 key, split it and send it. */ justkey = (key & ~KEYC_ESCAPE); if (justkey <= 0x7f) { if (key & KEYC_ESCAPE) bufferevent_write(wp->event, "\033", 1); ud.data[0] = justkey; bufferevent_write(wp->event, &ud.data[0], 1); return; } if (justkey > 0x7f && justkey < KEYC_BASE) { if (utf8_split(justkey, &ud) != UTF8_DONE) return; if (key & KEYC_ESCAPE) bufferevent_write(wp->event, "\033", 1); bufferevent_write(wp->event, ud.data, ud.size); return; } /* * Then try to look this up as an xterm key, if the flag to output them * is set. */ if (options_get_number(wp->window->options, "xterm-keys")) { if ((out = xterm_keys_lookup(key)) != NULL) { bufferevent_write(wp->event, out, strlen(out)); free(out); return; } } /* Otherwise look the key up in the table. */ for (i = 0; i < nitems(input_keys); i++) { ike = &input_keys[i]; if ((ike->flags & INPUTKEY_KEYPAD) && !(wp->screen->mode & MODE_KKEYPAD)) continue; if ((ike->flags & INPUTKEY_CURSOR) && !(wp->screen->mode & MODE_KCURSOR)) continue; if ((key & KEYC_ESCAPE) && (ike->key | KEYC_ESCAPE) == key) break; if (ike->key == key) break; } if (i == nitems(input_keys)) { log_debug("key 0x%llx missing", key); return; } dlen = strlen(ike->data); log_debug("found key 0x%llx: \"%s\"", key, ike->data); /* Prefix a \033 for escape. */ if (key & KEYC_ESCAPE) bufferevent_write(wp->event, "\033", 1); bufferevent_write(wp->event, ike->data, dlen); }