From 5fce53f904d4b44afee48ef50e2ef840677525d5 Mon Sep 17 00:00:00 2001 From: Nicolas Viennot Date: Wed, 30 Dec 2015 13:39:36 -0500 Subject: [PATCH] Sending raw tmux keycodes --- Makefile.am | 1 + server-client.c | 8 ++- tmate-daemon-decoder.c | 2 +- tmate-daemon-encoder.c | 25 ++++++++- tmate-daemon-legacy.c | 120 +++++++++++++++++++++++++++++++++++++++++ tmate-protocol.h | 3 +- tmate.h | 7 ++- 7 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 tmate-daemon-legacy.c diff --git a/Makefile.am b/Makefile.am index 29262b4a..2efb517d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -178,6 +178,7 @@ dist_tmate_slave_SOURCES = \ tmate-debug.c \ tmate-daemon-decoder.c \ tmate-daemon-encoder.c \ + tmate-daemon-legacy.c \ tmate-msgpack.c \ tmate-proxy.c \ tmate-slave.c \ diff --git a/server-client.c b/server-client.c index a60ba776..a761bb27 100644 --- a/server-client.c +++ b/server-client.c @@ -589,14 +589,12 @@ server_client_handle_key(struct client *c, key_code key) if (c->flags & CLIENT_READONLY) return; -#ifdef TMATE_SLAVE - wp = window_pane_at_index(w, key - '0'); - if (wp != NULL && window_pane_visible(wp)) - tmate_client_set_active_pane(c->id, key - '0', wp->id); -#else window_unzoom(w); wp = window_pane_at_index(w, key - '0'); if (wp != NULL && window_pane_visible(wp)) +#ifdef TMATE_SLAVE + tmate_client_set_active_pane(c->id, key - '0', wp->id); +#else window_set_active_pane(w, wp); #endif server_clear_identify(c); diff --git a/tmate-daemon-decoder.c b/tmate-daemon-decoder.c index d7c72243..6e4abe5d 100644 --- a/tmate-daemon-decoder.c +++ b/tmate-daemon-decoder.c @@ -23,7 +23,7 @@ static void tmate_header(struct tmate_session *session, client_version = unpack_string(uk); } - tmate_notice("new master, client version: %s, protocol version: %d", + tmate_notice("Daemon header: client version: %s, protocol version: %d", client_version, session->client_protocol_version); #if 0 diff --git a/tmate-daemon-encoder.c b/tmate-daemon-encoder.c index 35538405..d5a1fce3 100644 --- a/tmate-daemon-encoder.c +++ b/tmate-daemon-encoder.c @@ -81,7 +81,7 @@ void tmate_client_resize(u_int sx, u_int sy) pack(int, sy); } -void tmate_client_pane_key(int pane_id, int key) +void tmate_client_legacy_pane_key(__unused int pane_id, int key) { /* * We don't specify the pane id because the current active pane is @@ -89,10 +89,31 @@ void tmate_client_pane_key(int pane_id, int key) */ pack(array, 2); - pack(int, TMATE_IN_PANE_KEY); + pack(int, TMATE_IN_LEGACY_PANE_KEY); pack(int, key); } +void tmate_client_pane_key(int pane_id, key_code key) +{ + if (key == KEYC_NONE || key == KEYC_UNKNOWN) + return; + + /* Mouse keys not supported yet */ + if (KEYC_IS_MOUSE(key)) + return; + + if (tmate_session->client_protocol_version < 5) { + int legacy_key = tmate_translate_legacy_key(key); + tmate_client_legacy_pane_key(pane_id, legacy_key); + return; + } + + pack(array, 3); + pack(int, TMATE_IN_PANE_KEY); + pack(int, pane_id); + pack(uint64, key); +} + extern const struct cmd_entry cmd_bind_key_entry; extern const struct cmd_entry cmd_unbind_key_entry; extern const struct cmd_entry cmd_set_option_entry; diff --git a/tmate-daemon-legacy.c b/tmate-daemon-legacy.c new file mode 100644 index 00000000..569c1347 --- /dev/null +++ b/tmate-daemon-legacy.c @@ -0,0 +1,120 @@ +#include "tmate.h" + +#define LEGACY_KEYC_NONE 0xfff +#define LEGACY_KEYC_BASE 0x1000 + +#define LEGACY_KEYC_ESCAPE 0x2000 +#define LEGACY_KEYC_CTRL 0x4000 +#define LEGACY_KEYC_SHIFT 0x8000 +#define LEGACY_KEYC_PREFIX 0x10000 + +enum legacy_key_code { + LEGACY_KEYC_MOUSE = LEGACY_KEYC_BASE, + LEGACY_KEYC_BSPACE, + LEGACY_KEYC_F1, + LEGACY_KEYC_F2, + LEGACY_KEYC_F3, + LEGACY_KEYC_F4, + LEGACY_KEYC_F5, + LEGACY_KEYC_F6, + LEGACY_KEYC_F7, + LEGACY_KEYC_F8, + LEGACY_KEYC_F9, + LEGACY_KEYC_F10, + LEGACY_KEYC_F11, + LEGACY_KEYC_F12, + LEGACY_KEYC_F13, + LEGACY_KEYC_F14, + LEGACY_KEYC_F15, + LEGACY_KEYC_F16, + LEGACY_KEYC_F17, + LEGACY_KEYC_F18, + LEGACY_KEYC_F19, + LEGACY_KEYC_F20, + LEGACY_KEYC_IC, + LEGACY_KEYC_DC, + LEGACY_KEYC_HOME, + LEGACY_KEYC_END, + LEGACY_KEYC_NPAGE, + LEGACY_KEYC_PPAGE, + LEGACY_KEYC_BTAB, + LEGACY_KEYC_UP, + LEGACY_KEYC_DOWN, + LEGACY_KEYC_LEFT, + LEGACY_KEYC_RIGHT, + LEGACY_KEYC_KP_SLASH, + LEGACY_KEYC_KP_STAR, + LEGACY_KEYC_KP_MINUS, + LEGACY_KEYC_KP_SEVEN, + LEGACY_KEYC_KP_EIGHT, + LEGACY_KEYC_KP_NINE, + LEGACY_KEYC_KP_PLUS, + LEGACY_KEYC_KP_FOUR, + LEGACY_KEYC_KP_FIVE, + LEGACY_KEYC_KP_SIX, + LEGACY_KEYC_KP_ONE, + LEGACY_KEYC_KP_TWO, + LEGACY_KEYC_KP_THREE, + LEGACY_KEYC_KP_ENTER, + LEGACY_KEYC_KP_ZERO, + LEGACY_KEYC_KP_PERIOD, + LEGACY_KEYC_FOCUS_IN, + LEGACY_KEYC_FOCUS_OUT, +}; + +int tmate_translate_legacy_key(key_code key) +{ + int lkey; + + switch(key & KEYC_MASK_KEY) { + case KEYC_BSPACE: lkey = LEGACY_KEYC_BSPACE; break; + case KEYC_F1: lkey = LEGACY_KEYC_F1; break; + case KEYC_F2: lkey = LEGACY_KEYC_F2; break; + case KEYC_F3: lkey = LEGACY_KEYC_F3; break; + case KEYC_F4: lkey = LEGACY_KEYC_F4; break; + case KEYC_F5: lkey = LEGACY_KEYC_F5; break; + case KEYC_F6: lkey = LEGACY_KEYC_F6; break; + case KEYC_F7: lkey = LEGACY_KEYC_F7; break; + case KEYC_F8: lkey = LEGACY_KEYC_F8; break; + case KEYC_F9: lkey = LEGACY_KEYC_F9; break; + case KEYC_F10: lkey = LEGACY_KEYC_F10; break; + case KEYC_F11: lkey = LEGACY_KEYC_F11; break; + case KEYC_F12: lkey = LEGACY_KEYC_F12; break; + case KEYC_IC: lkey = LEGACY_KEYC_IC; break; + case KEYC_DC: lkey = LEGACY_KEYC_DC; break; + case KEYC_HOME: lkey = LEGACY_KEYC_HOME; break; + case KEYC_END: lkey = LEGACY_KEYC_END; break; + case KEYC_NPAGE: lkey = LEGACY_KEYC_NPAGE; break; + case KEYC_PPAGE: lkey = LEGACY_KEYC_PPAGE; break; + case KEYC_BTAB: lkey = LEGACY_KEYC_BTAB; break; + case KEYC_UP: lkey = LEGACY_KEYC_UP; break; + case KEYC_DOWN: lkey = LEGACY_KEYC_DOWN; break; + case KEYC_LEFT: lkey = LEGACY_KEYC_LEFT; break; + case KEYC_RIGHT: lkey = LEGACY_KEYC_RIGHT; break; + case KEYC_KP_SLASH: lkey = LEGACY_KEYC_KP_SLASH; break; + case KEYC_KP_STAR: lkey = LEGACY_KEYC_KP_STAR; break; + case KEYC_KP_MINUS: lkey = LEGACY_KEYC_KP_MINUS; break; + case KEYC_KP_SEVEN: lkey = LEGACY_KEYC_KP_SEVEN; break; + case KEYC_KP_EIGHT: lkey = LEGACY_KEYC_KP_EIGHT; break; + case KEYC_KP_NINE: lkey = LEGACY_KEYC_KP_NINE; break; + case KEYC_KP_PLUS: lkey = LEGACY_KEYC_KP_PLUS; break; + case KEYC_KP_FOUR: lkey = LEGACY_KEYC_KP_FOUR; break; + case KEYC_KP_FIVE: lkey = LEGACY_KEYC_KP_FIVE; break; + case KEYC_KP_SIX: lkey = LEGACY_KEYC_KP_SIX; break; + case KEYC_KP_ONE: lkey = LEGACY_KEYC_KP_ONE; break; + case KEYC_KP_TWO: lkey = LEGACY_KEYC_KP_TWO; break; + case KEYC_KP_THREE: lkey = LEGACY_KEYC_KP_THREE; break; + case KEYC_KP_ENTER: lkey = LEGACY_KEYC_KP_ENTER; break; + case KEYC_KP_ZERO: lkey = LEGACY_KEYC_KP_ZERO; break; + case KEYC_KP_PERIOD: lkey = LEGACY_KEYC_KP_PERIOD; break; + case KEYC_FOCUS_IN: lkey = LEGACY_KEYC_FOCUS_IN; break; + case KEYC_FOCUS_OUT: lkey = LEGACY_KEYC_FOCUS_OUT; break; + default: lkey = key & KEYC_MASK_KEY; + } + + if (key & KEYC_ESCAPE) lkey |= LEGACY_KEYC_ESCAPE; + if (key & KEYC_CTRL) lkey |= LEGACY_KEYC_CTRL; + if (key & KEYC_SHIFT) lkey |= LEGACY_KEYC_SHIFT; + + return lkey; +} diff --git a/tmate-protocol.h b/tmate-protocol.h index 48b20d66..2e9f9ff8 100644 --- a/tmate-protocol.h +++ b/tmate-protocol.h @@ -69,11 +69,12 @@ enum tmate_daemon_out_msg_types { enum tmate_daemon_in_msg_types { TMATE_IN_NOTIFY, - TMATE_IN_PANE_KEY, + TMATE_IN_LEGACY_PANE_KEY, TMATE_IN_RESIZE, TMATE_IN_EXEC_CMD, TMATE_IN_SET_ENV, TMATE_IN_READY, + TMATE_IN_PANE_KEY, }; /* diff --git a/tmate.h b/tmate.h index 45a092c4..d0486fcc 100644 --- a/tmate.h +++ b/tmate.h @@ -92,7 +92,8 @@ extern void printflike(1, 2) tmate_notify(const char *fmt, ...); extern void printflike(2, 3) tmate_notify_later(int timeout, const char *fmt, ...); extern void tmate_client_resize(u_int sx, u_int sy); -extern void tmate_client_pane_key(int pane_id, int key); +extern void tmate_legacy_client_pane_key(int pane_id, int key); +extern void tmate_client_pane_key(int pane_id, key_code key); extern void tmate_client_cmd(int client_id, const char *cmd); extern void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id); extern int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd); @@ -100,6 +101,10 @@ extern void tmate_send_env(const char *name, const char *value); extern void tmate_send_client_ready(void); extern void tmate_send_mc_obj(msgpack_object *obj); +/* tmate-daemon-legacy.c */ + +extern int tmate_translate_legacy_key(key_code key); + /* tmate-daemon-decoder.c */ #define TMATE_HLIMIT 2000