diff --git a/cmd-queue.c b/cmd-queue.c index c0557528..4a819344 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -202,6 +202,7 @@ cmdq_continue(struct cmd_q *cmdq) enum cmd_retval retval; int empty, guard; char s[1024]; + int client_id; notify_disable(); @@ -228,7 +229,8 @@ cmdq_continue(struct cmd_q *cmdq) #ifdef TMATE_SLAVE if (!tmate_should_exec_cmd_locally(cmdq->cmd->entry)) { - tmate_client_cmd(s); + client_id = cmdq->client ? cmdq->client->id : -1; + tmate_client_cmd(client_id, s); cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry); continue; } diff --git a/server-client.c b/server-client.c index 6ce90dd7..66537c9d 100644 --- a/server-client.c +++ b/server-client.c @@ -45,6 +45,10 @@ void server_client_msg_identify( struct client *, struct msg_identify_data *, int); void server_client_msg_shell(struct client *); +#ifdef TMATE_SLAVE +u_int next_client_id; +#endif + /* Create a new client. */ void server_client_create(int fd) @@ -55,6 +59,11 @@ server_client_create(int fd) setblocking(fd, 0); c = xcalloc(1, sizeof *c); + +#ifdef TMATE_SLAVE + c->id = next_client_id++; +#endif + c->references = 0; imsg_init(&c->ibuf, fd); server_update_event(c); @@ -394,7 +403,7 @@ server_client_handle_key(struct client *c, int key) #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); + tmate_client_set_active_pane(c->id, key - '0', wp->id); #else window_unzoom(w); wp = window_pane_at_index(w, key - '0'); diff --git a/tmate-decoder.c b/tmate-decoder.c index 2b38df82..42b5283a 100644 --- a/tmate-decoder.c +++ b/tmate-decoder.c @@ -1,3 +1,4 @@ +#include #include "tmate.h" char *tmate_left_status, *tmate_right_status; @@ -242,7 +243,7 @@ static void tmate_pty_data(struct tmate_unpacker *uk) wp->window->flags |= WINDOW_SILENCE; } -static void tmate_cmd(struct tmate_unpacker *uk) +static void tmate_exec_cmd(struct tmate_unpacker *uk) { struct cmd_q *cmd_q; struct cmd_list *cmdlist; @@ -263,6 +264,28 @@ out: free(cmd_str); } +static void tmate_failed_cmd(struct tmate_unpacker *uk) +{ + struct client *c; + unsigned int i; + int client_id; + char *cause; + + client_id = unpack_int(uk); + cause = unpack_string(uk); + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c && c->id == client_id) { + *cause = toupper((u_char) *cause); + status_message_set(c, "%s", cause); + break; + } + } + + free(cause); +} + static void tmate_status(struct tmate_unpacker *uk) { struct client *c; @@ -292,7 +315,8 @@ static void handle_message(msgpack_object obj) case TMATE_HEADER: tmate_header(uk); break; case TMATE_SYNC_LAYOUT: tmate_sync_layout(uk); break; case TMATE_PTY_DATA: tmate_pty_data(uk); break; - case TMATE_CMD: tmate_cmd(uk); break; + case TMATE_EXEC_CMD: tmate_exec_cmd(uk); break; + case TMATE_FAILED_CMD: tmate_failed_cmd(uk); break; case TMATE_STATUS: tmate_status(uk); break; default: decoder_error(); } diff --git a/tmate-encoder.c b/tmate-encoder.c index 4e5e83da..8c06e4a5 100644 --- a/tmate-encoder.c +++ b/tmate-encoder.c @@ -81,17 +81,18 @@ int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd) return 0; } -void tmate_client_cmd(const char *cmd) +void tmate_client_cmd(int client_id, const char *cmd) { - pack(array, 2); - pack(int, TMATE_CLIENT_CMD); + pack(array, 3); + pack(int, TMATE_CLIENT_EXEC_CMD); + pack(int, client_id); pack(string, cmd); } -void tmate_client_set_active_pane(int win_id, int pane_id) +void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id) { char cmd[1024]; - sprintf(cmd, "select-pane -t %d.%d", win_id, pane_id); - tmate_client_cmd(cmd); + sprintf(cmd, "select-pane -t %d.%d", win_idx, pane_id); + tmate_client_cmd(client_id, cmd); } diff --git a/tmate.h b/tmate.h index 1644f0dd..acbf0801 100644 --- a/tmate.h +++ b/tmate.h @@ -18,7 +18,7 @@ enum tmate_client_commands { TMATE_REPLY_HEADER, TMATE_CLIENT_PANE_KEY, TMATE_CLIENT_RESIZE, - TMATE_CLIENT_CMD, + TMATE_CLIENT_EXEC_CMD, }; struct tmate_encoder { @@ -32,8 +32,8 @@ extern void tmate_encoder_init(struct tmate_encoder *encoder); extern void tmate_reply_header(unsigned long flags); 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 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); /* tmate-decoder.c */ @@ -47,7 +47,8 @@ enum tmate_commands { TMATE_HEADER, TMATE_SYNC_LAYOUT, TMATE_PTY_DATA, - TMATE_CMD, + TMATE_EXEC_CMD, + TMATE_FAILED_CMD, TMATE_STATUS, }; diff --git a/tmux.h b/tmux.h index 070e9433..7e37afa2 100644 --- a/tmux.h +++ b/tmux.h @@ -1300,6 +1300,10 @@ RB_HEAD(status_out_tree, status_out); /* Client connection. */ struct client { +#ifdef TMATE_SLAVE + int id; +#endif + struct imsgbuf ibuf; struct event event; int retcode;