diff --git a/cmd-queue.c b/cmd-queue.c index c5f75f40..c0557528 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -23,6 +23,7 @@ #include #include "tmux.h" +#include "tmate.h" /* Create new command queue. */ struct cmd_q * @@ -225,6 +226,14 @@ cmdq_continue(struct cmd_q *cmdq) cmdq->time = time(NULL); cmdq->number++; +#ifdef TMATE_SLAVE + if (!tmate_should_exec_cmd_locally(cmdq->cmd->entry)) { + tmate_client_cmd(s); + cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry); + continue; + } +#endif + guard = cmdq_guard(cmdq, "begin"); retval = cmdq->cmd->entry->exec(cmdq->cmd, cmdq); if (guard) { diff --git a/server-client.c b/server-client.c index edcc8b64..6ce90dd7 100644 --- a/server-client.c +++ b/server-client.c @@ -282,11 +282,14 @@ server_client_status_timer(void) } } -#ifndef TMATE_SLAVE /* Check for mouse keys. */ void server_client_check_mouse(struct client *c, struct window_pane *wp) { +#ifdef TMATE_SLAVE + /* TODO Support mouse */ + return; +#else struct session *s = c->session; struct options *oo = &s->options; struct mouse_event *m = &c->tty.mouse; @@ -334,8 +337,8 @@ server_client_check_mouse(struct client *c, struct window_pane *wp) /* Update last and pass through to client. */ window_pane_mouse(wp, c->session, m); -} #endif +} /* Is this fast enough to probably be a paste? */ int @@ -357,9 +360,6 @@ server_client_assume_paste(struct session *s) void server_client_handle_key(struct client *c, int key) { -#ifdef TMATE_SLAVE - tmate_client_key(key); -#else struct session *s; struct window *w; struct window_pane *wp; @@ -390,10 +390,17 @@ server_client_handle_key(struct client *c, int key) if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') { 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(w->id, wp->id); +#else window_unzoom(w); wp = window_pane_at_index(w, key - '0'); if (wp != NULL && window_pane_visible(wp)) window_set_active_pane(w, wp); +#endif server_clear_identify(c); return; } @@ -485,7 +492,6 @@ server_client_handle_key(struct client *c, int key) /* Dispatch the command. */ key_bindings_dispatch(bd, c); -#endif } /* Client functions that need to happen every loop. */ diff --git a/tmate-encoder.c b/tmate-encoder.c index 810eb8af..d85ffe80 100644 --- a/tmate-encoder.c +++ b/tmate-encoder.c @@ -20,14 +20,13 @@ void tmate_encoder_init(struct tmate_encoder *encoder) msgpack_packer_init(&encoder->pk, encoder, &msgpack_write); } -#define pack(what, ...) msgpack_pack_##what(&tmate_encoder->pk, __VA_ARGS__) +#define msgpack_pack_string(pk, str) do { \ + int __strlen = strlen(str); \ + msgpack_pack_raw(pk, __strlen); \ + msgpack_pack_raw_body(pk, str, __strlen); \ +} while(0) -void tmate_client_key(int key) -{ - pack(array, 2); - pack(int, TMATE_CLIENT_KEY); - pack(int, key); -} +#define pack(what, ...) msgpack_pack_##what(&tmate_encoder->pk, __VA_ARGS__) void tmate_client_resize(u_int sx, u_int sy) { @@ -37,3 +36,46 @@ void tmate_client_resize(u_int sx, u_int sy) pack(int, sx); pack(int, sy); } + +void tmate_client_pane_key(int pane_id, int key) +{ + /* + * We don't specify the pane id because the current active pane is + * behind, so we'll let master send the key to its active pane. + */ + + pack(array, 2); + pack(int, TMATE_CLIENT_PANE_KEY); + pack(int, key); +} + +static const struct cmd_entry *local_cmds[] = { + &cmd_detach_client_entry, + &cmd_attach_session_entry, + NULL +}; + +int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd) +{ + const struct cmd_entry **ptr; + + for (ptr = local_cmds; *ptr; ptr++) + if (*ptr == cmd) + return 1; + return 0; +} + +void tmate_client_cmd(const char *cmd) +{ + pack(array, 2); + pack(int, TMATE_CLIENT_CMD); + pack(string, cmd); +} + +void tmate_client_set_active_pane(int win_id, int pane_id) +{ + char cmd[1024]; + + sprintf(cmd, "select-pane -t %d.%d", win_id, pane_id); + tmate_client_cmd(cmd); +} diff --git a/tmate.h b/tmate.h index 4bbe0118..34099217 100644 --- a/tmate.h +++ b/tmate.h @@ -14,9 +14,10 @@ /* tmate-encoder.c */ -enum tmate_notifications { - TMATE_CLIENT_KEY, +enum tmate_client_commands { + TMATE_CLIENT_PANE_KEY, TMATE_CLIENT_RESIZE, + TMATE_CLIENT_CMD, }; struct tmate_encoder { @@ -30,8 +31,11 @@ extern void tmate_encoder_init(struct tmate_encoder *encoder); extern void tmate_write_header(void); extern void tmate_write_pane(int pane, const char *data, size_t size); -extern void tmate_client_key(int key); 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_client_cmd(const char *cmd); +extern void tmate_client_set_active_pane(int win_id, int pane_id); +extern int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd); /* tmate-decoder.c */ diff --git a/tty-keys.c b/tty-keys.c index 14a06a4b..c0663378 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -26,7 +26,6 @@ #include #include "tmux.h" -#include "tmate.h" /* * Handle keys input from the outside terminal. tty_default_*_keys[] are a base diff --git a/window.c b/window.c index 6c0466cf..a8beaa28 100644 --- a/window.c +++ b/window.c @@ -30,6 +30,7 @@ #include #include "tmux.h" +#include "tmate.h" /* * Each window is attached to a number of panes, each of which is a pty. This @@ -1039,10 +1040,13 @@ window_pane_reset_mode(struct window_pane *wp) wp->flags |= PANE_REDRAW; } -#ifndef TMATE_SLAVE void window_pane_key(struct window_pane *wp, struct session *sess, int key) { +#ifdef TMATE_SLAVE + tmate_client_pane_key(wp->id, key); +#else + struct window_pane *wp2; if (!window_pane_visible(wp)) @@ -1065,12 +1069,17 @@ window_pane_key(struct window_pane *wp, struct session *sess, int key) input_key(wp2, key); } } +#endif } void window_pane_mouse( struct window_pane *wp, struct session *sess, struct mouse_event *m) { +#ifdef TMATE_SLAVE + /* TODO Deal with mouse */ + return; +#else if (!window_pane_visible(wp)) return; @@ -1087,8 +1096,8 @@ window_pane_mouse( wp->mode->mouse(wp, sess, m); } else if (wp->fd != -1) input_mouse(wp, sess, m); -} #endif +} int window_pane_visible(struct window_pane *wp)