diff --git a/CHANGES b/CHANGES index 94b021f0..dedf3859 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +03 October 2007 + +* (nicm) Move command parsing into the client. Also rename some messages and + tidy up a few bits. Lots more tidying up needed :-/. + 02 October 2007 * (nicm) Redraw client status lines on rename. @@ -90,5 +95,5 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.22 2007-10-02 17:45:05 nicm Exp $ +$Id: CHANGES,v 1.23 2007-10-03 10:18:31 nicm Exp $ diff --git a/Makefile b/Makefile index d953f085..d421d88e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.10 2007-10-03 00:13:46 nicm Exp $ +# $Id: Makefile,v 1.11 2007-10-03 10:18:31 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean @@ -17,8 +17,8 @@ DEBUG= META?= \002 # C-b SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ - xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c window.c \ - session.c local.c log.c client.c client-msg.c client-cmd.c op.c op-list.c + xmalloc.c xmalloc-debug.c cmd.c input.c input-keys.c screen.c window.c \ + session.c local.c log.c client.c client-msg.c client-fn.c op.c op-list.c YACC= yacc -d diff --git a/TODO b/TODO index 1f0e1057..5e47d696 100644 --- a/TODO +++ b/TODO @@ -27,8 +27,8 @@ - decide about customised status line - rethink data structures. window->index is O(n), could have a w->idx member or use queues/trees and avoid NULLs? -- client could pass tty fd up to server and then do nothing. what problems - would this cause? +- client could pass term/tty fd up to server and then do nothing. what problems + would this cause? -- need access to all terminfo data at once... signals? - cleanup/redesign IPC IPC is arse-about-face: too much overhead. 8-byte header for each packet... hrm. already scanning output for \e, could add an extra @@ -52,3 +52,4 @@ - fix resize (width problems with multiple clients?) - handle tmux in tmux (check $TMUX and abort) - check for some reqd terminfo caps on startup +- sort out the pause mess diff --git a/client-cmd.c b/client-cmd.c deleted file mode 100644 index 62c84978..00000000 --- a/client-cmd.c +++ /dev/null @@ -1,119 +0,0 @@ -/* $Id: client-cmd.c,v 1.7 2007-10-02 15:38:09 nicm Exp $ */ - -/* - * Copyright (c) 2007 Nicholas Marriott - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "tmux.h" - -int client_cmd_prefix = META; - -int client_cmd_fn_msg(int, struct client_ctx *, char **); -int client_cmd_fn_select(int, struct client_ctx *, char **); -int client_cmd_fn_detach(int, struct client_ctx *, char **); -int client_cmd_fn_meta(int, struct client_ctx *, char **); - -struct cmd { - int key; - int (*fn)(int, struct client_ctx *, char **); - int arg; -}; - -struct cmd client_cmd_table[] = { - { '0', client_cmd_fn_select, 0 }, - { '1', client_cmd_fn_select, 1 }, - { '2', client_cmd_fn_select, 2 }, - { '3', client_cmd_fn_select, 3 }, - { '4', client_cmd_fn_select, 4 }, - { '5', client_cmd_fn_select, 5 }, - { '6', client_cmd_fn_select, 6 }, - { '7', client_cmd_fn_select, 7 }, - { '8', client_cmd_fn_select, 8 }, - { '9', client_cmd_fn_select, 9 }, - { 'C', client_cmd_fn_msg, MSG_CREATE }, - { 'c', client_cmd_fn_msg, MSG_CREATE }, - { 'D', client_cmd_fn_detach, 0 }, - { 'd', client_cmd_fn_detach, 0 }, - { 'N', client_cmd_fn_msg, MSG_NEXT }, - { 'n', client_cmd_fn_msg, MSG_NEXT }, - { 'P', client_cmd_fn_msg, MSG_PREVIOUS }, - { 'p', client_cmd_fn_msg, MSG_PREVIOUS }, - { 'R', client_cmd_fn_msg, MSG_REFRESH }, - { 'r', client_cmd_fn_msg, MSG_REFRESH }, - { 'L', client_cmd_fn_msg, MSG_LAST }, - { 'l', client_cmd_fn_msg, MSG_LAST }, - { 'W', client_cmd_fn_msg, MSG_WINDOWLIST }, - { 'w', client_cmd_fn_msg, MSG_WINDOWLIST }, - { 'I', client_cmd_fn_msg, MSG_WINDOWINFO }, - { 'i', client_cmd_fn_msg, MSG_WINDOWINFO }, - { META, client_cmd_fn_meta, 0 }, -}; -#define NCLIENTCMD (sizeof client_cmd_table / sizeof client_cmd_table[0]) - -int -client_cmd_dispatch(int key, struct client_ctx *cctx, char **error) -{ - struct cmd *cmd; - u_int i; - - for (i = 0; i < NCLIENTCMD; i++) { - cmd = client_cmd_table + i; - if (cmd->key == key) - return (cmd->fn(cmd->arg, cctx, error)); - } - return (0); -} - -/* Handle generic command. */ -int -client_cmd_fn_msg(int arg, struct client_ctx *cctx, unused char **error) -{ - client_write_server(cctx, arg, NULL, 0); - - return (0); -} - -/* Handle select command. */ -int -client_cmd_fn_select(int arg, struct client_ctx *cctx, unused char **error) -{ - struct select_data data; - - data.idx = arg; - client_write_server(cctx, MSG_SELECT, &data, sizeof data); - - return (0); -} - -/* Handle detach command. */ -int -client_cmd_fn_detach( - unused int arg, unused struct client_ctx *cctx, unused char **error) -{ - return (-1); -} - -/* Handle meta command. */ -int -client_cmd_fn_meta(unused int arg, struct client_ctx *cctx, unused char **error) -{ - uint8_t key = META; - - client_write_server(cctx, MSG_INPUT, &key, sizeof key); - - return (0); -} diff --git a/client-fn.c b/client-fn.c new file mode 100644 index 00000000..8aecd463 --- /dev/null +++ b/client-fn.c @@ -0,0 +1,67 @@ +/* $Id: client-fn.c,v 1.1 2007-10-03 10:18:31 nicm Exp $ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "tmux.h" + +void +client_fill_sessid(struct sessid *sid, char name[MAXNAMELEN]) +{ + char *env, *ptr, buf[256]; + const char *errstr; + long long ll; + + strlcpy(sid->name, name, sizeof sid->name); + + sid->pid = -1; + if ((env = getenv("TMUX")) == NULL) + return; + if ((ptr = strchr(env, ',')) == NULL) + return; + if ((size_t) (ptr - env) > sizeof buf) + return; + memcpy(buf, env, ptr - env); + buf[ptr - env] = '\0'; + + ll = strtonum(ptr + 1, 0, UINT_MAX, &errstr); + if (errstr != NULL) + return; + sid->idx = ll; + + ll = strtonum(buf, 0, LLONG_MAX, &errstr); + if (errstr != NULL) + return; + sid->pid = ll; +} + +void +client_write_server( + struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len) +{ + struct hdr hdr; + + hdr.type = type; + hdr.size = len; + buffer_write(cctx->srv_out, &hdr, sizeof hdr); + if (len > 0) + buffer_write(cctx->srv_out, buf, len); +} diff --git a/client-msg.c b/client-msg.c index 8ecc38d0..0a17d67e 100644 --- a/client-msg.c +++ b/client-msg.c @@ -1,4 +1,4 @@ -/* $Id: client-msg.c,v 1.4 2007-09-29 14:57:07 nicm Exp $ */ +/* $Id: client-msg.c,v 1.5 2007-10-03 10:18:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,11 +24,11 @@ #include "tmux.h" -int client_msg_fn_output(struct hdr *, struct client_ctx *, char **); -int client_msg_fn_pause(struct hdr *, struct client_ctx *, char **); -int client_msg_fn_done(struct hdr *, struct client_ctx *, char **); -int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **); +int client_msg_fn_data(struct hdr *, struct client_ctx *, char **); +int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **); int client_msg_fn_error(struct hdr *, struct client_ctx *, char **); +int client_msg_fn_okay(struct hdr *, struct client_ctx *, char **); +int client_msg_fn_pause(struct hdr *, struct client_ctx *, char **); struct client_msg { enum hdrtype type; @@ -36,11 +36,11 @@ struct client_msg { int (*fn)(struct hdr *, struct client_ctx *, char **); }; struct client_msg client_msg_table[] = { - { MSG_OUTPUT, client_msg_fn_output }, - { MSG_PAUSE, client_msg_fn_pause }, - { MSG_DONE, client_msg_fn_done }, - { MSG_EXIT, client_msg_fn_exit }, + { MSG_DATA, client_msg_fn_data }, + { MSG_DETACH, client_msg_fn_detach }, { MSG_ERROR, client_msg_fn_error }, + { MSG_OKAY, client_msg_fn_okay }, + { MSG_PAUSE, client_msg_fn_pause }, }; #define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0]) @@ -73,9 +73,9 @@ client_msg_dispatch(struct client_ctx *cctx, char **error) } } -/* Output message from server. */ +/* Data message from server. */ int -client_msg_fn_output( +client_msg_fn_data( struct hdr *hdr, struct client_ctx *cctx, unused char **error) { local_output(cctx->srv_in, hdr->size); @@ -92,23 +92,13 @@ client_msg_fn_pause( return (1); } -/* Exit message from server. */ +/* Okay message from server. */ int -client_msg_fn_exit( +client_msg_fn_okay( struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) { if (hdr->size != 0) - fatalx("bad MSG_EXIT size"); - return (-1); -} - -/* Done message from server. */ -int -client_msg_fn_done( - struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) -{ - if (hdr->size != 0) - fatalx("bad MSG_DONE size"); + fatalx("bad MSG_OKAY size"); return (0); } @@ -125,3 +115,16 @@ client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error) return (-1); } + +/* Detach message from server. */ +int +client_msg_fn_detach( + struct hdr *hdr, unused struct client_ctx *cctx, char **error) +{ + if (hdr->size != 0) + fatalx("bad MSG_DETACH size"); + + *error = NULL; + + return (-1); +} diff --git a/client.c b/client.c index ede5e33d..77a1fb68 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.9 2007-09-29 13:22:15 nicm Exp $ */ +/* $Id: client.c,v 1.10 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -154,7 +154,7 @@ client_flush(struct client_ctx *cctx) continue; buffer_remove(cctx->srv_in, sizeof hdr); - if (hdr.type == MSG_DONE) + if (hdr.type == MSG_OKAY) return (0); if (hdr.type == MSG_ERROR) { if (hdr.size > INT_MAX - 1) @@ -241,49 +241,6 @@ local_dead: fatalx("local socket dead"); } -void -client_fill_sessid(struct sessid *sid, char name[MAXNAMELEN]) -{ - char *env, *ptr, buf[256]; - const char *errstr; - long long ll; - - strlcpy(sid->name, name, sizeof sid->name); - - sid->pid = -1; - if ((env = getenv("TMUX")) == NULL) - return; - if ((ptr = strchr(env, ',')) == NULL) - return; - if ((size_t) (ptr - env) > sizeof buf) - return; - memcpy(buf, env, ptr - env); - buf[ptr - env] = '\0'; - - ll = strtonum(ptr + 1, 0, UINT_MAX, &errstr); - if (errstr != NULL) - return; - sid->idx = ll; - - ll = strtonum(buf, 0, LLONG_MAX, &errstr); - if (errstr != NULL) - return; - sid->pid = ll; -} - -void -client_write_server( - struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len) -{ - struct hdr hdr; - - hdr.type = type; - hdr.size = len; - buffer_write(cctx->srv_out, &hdr, sizeof hdr); - if (len > 0) - buffer_write(cctx->srv_out, buf, len); -} - void client_handle_winch(struct client_ctx *cctx) { @@ -300,39 +257,22 @@ client_handle_winch(struct client_ctx *cctx) } int -client_process_local(struct client_ctx *cctx, char **error) +client_process_local(struct client_ctx *cctx, unused char **error) { struct buffer *b; - size_t size; - int n, key; + int key; - n = 0; b = buffer_create(BUFSIZ); - - while ((key = local_key(&size)) != KEYC_NONE) { - log_debug("key code: %d", key); - - if (key == client_cmd_prefix) { - if ((key = local_key(NULL)) == KEYC_NONE) { - /* XXX sux */ - buffer_reverse_remove(cctx->loc_in, size); - break; - } - n = client_cmd_dispatch(key, cctx, error); - break; - } - - input_store8(b, '\e'); - input_store16(b, (uint16_t) key /*XXX*/); - } + while ((key = local_key()) != KEYC_NONE) + input_store16(b, (uint16_t) key); log_debug("transmitting %zu bytes of input", BUFFER_USED(b)); - if (BUFFER_USED(b) == 0) { - buffer_destroy(b); - return (n); + if (BUFFER_USED(b) != 0) { + client_write_server( + cctx, MSG_KEYS, BUFFER_OUT(b), BUFFER_USED(b)); } - client_write_server(cctx, MSG_INPUT, BUFFER_OUT(b), BUFFER_USED(b)); + buffer_destroy(b); - return (n); + return (0); } diff --git a/cmd.c b/cmd.c new file mode 100644 index 00000000..5132f0e1 --- /dev/null +++ b/cmd.c @@ -0,0 +1,176 @@ +/* $Id: cmd.c,v 1.1 2007-10-03 10:18:32 nicm Exp $ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "tmux.h" + +int cmd_prefix = META; + +void cmd_fn_create(struct client *, int); +void cmd_fn_detach(struct client *, int); +void cmd_fn_last(struct client *, int); +void cmd_fn_meta(struct client *, int); +void cmd_fn_next(struct client *, int); +void cmd_fn_previous(struct client *, int); +void cmd_fn_refresh(struct client *, int); +void cmd_fn_select(struct client *, int); +void cmd_fn_windowinfo(struct client *, int); + +struct cmd { + int key; + void (*fn)(struct client *, int); + int arg; +}; + +struct cmd cmd_table[] = { + { '0', cmd_fn_select, 0 }, + { '1', cmd_fn_select, 1 }, + { '2', cmd_fn_select, 2 }, + { '3', cmd_fn_select, 3 }, + { '4', cmd_fn_select, 4 }, + { '5', cmd_fn_select, 5 }, + { '6', cmd_fn_select, 6 }, + { '7', cmd_fn_select, 7 }, + { '8', cmd_fn_select, 8 }, + { '9', cmd_fn_select, 9 }, + { 'C', cmd_fn_create, 0 }, + { 'c', cmd_fn_create, 0 }, + { 'D', cmd_fn_detach, 0 }, + { 'd', cmd_fn_detach, 0 }, + { 'N', cmd_fn_next, 0 }, + { 'n', cmd_fn_next, 0 }, + { 'P', cmd_fn_previous, 0 }, + { 'p', cmd_fn_previous, 0 }, + { 'R', cmd_fn_refresh, 0 }, + { 'r', cmd_fn_refresh, 0 }, + { 'L', cmd_fn_last, 0 }, + { 'l', cmd_fn_last, 0 }, + { 'I', cmd_fn_windowinfo, 0 }, + { 'i', cmd_fn_windowinfo, 0 }, + { META, cmd_fn_meta, 0 }, +}; +#define NCMD (sizeof cmd_table / sizeof cmd_table[0]) + +void +cmd_dispatch(struct client *c, int key) +{ + struct cmd *cmd; + u_int i; + + for (i = 0; i < NCMD; i++) { + cmd = cmd_table + i; + if (cmd->key == key) + cmd->fn(c, cmd->arg); + } +} + +void +cmd_fn_create(struct client *c, unused int arg) +{ + const char *shell; + char *cmd; + + shell = getenv("SHELL"); + if (shell == NULL) + shell = "/bin/ksh"; + xasprintf(&cmd, "%s -l", shell); + if (session_new(c->session, cmd, c->sx, c->sy) != 0) + fatalx("session_new failed"); + xfree(cmd); + + server_draw_client(c, 0, c->sy - 1); +} + +void +cmd_fn_detach(struct client *c, unused int arg) +{ + server_write_client(c, MSG_DETACH, NULL, 0); +} + +void +cmd_fn_last(struct client *c, unused int arg) +{ + if (session_last(c->session) == 0) + server_window_changed(c); + else + server_write_message(c, "No last window"); +} + +void +cmd_fn_meta(struct client *c, unused int arg) +{ + window_key(c->session->window, cmd_prefix); +} + +void +cmd_fn_next(struct client *c, unused int arg) +{ + if (session_next(c->session) == 0) + server_window_changed(c); + else + server_write_message(c, "No next window"); +} + +void +cmd_fn_previous(struct client *c, unused int arg) +{ + if (session_previous(c->session) == 0) + server_window_changed(c); + else + server_write_message(c, "No previous window"); +} + +void +cmd_fn_refresh(struct client *c, unused int arg) +{ + server_draw_client(c, 0, c->sy - 1); +} + +void +cmd_fn_select(struct client *c, int arg) +{ + if (session_select(c->session, arg) == 0) + server_window_changed(c); + else + server_write_message(c, "Window %u not present", arg); +} + +void +cmd_fn_windowinfo(struct client *c, unused int arg) +{ + struct window *w; + char *buf; + size_t len; + u_int i; + + len = c->sx + 1; + buf = xmalloc(len); + + w = c->session->window; + window_index(&c->session->windows, w, &i); + xsnprintf(buf, len, "%u:%s \"%s\" (size %u,%u) (cursor %u,%u) " + "(region %u,%u)", i, w->name, w->screen.title, w->screen.sx, + w->screen.sy, w->screen.cx, w->screen.cy, w->screen.ry_upper, + w->screen.ry_lower); + + server_write_message(c, "%s", buf); + xfree(buf); +} diff --git a/input.c b/input.c index ea589a0b..2434a24f 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.18 2007-10-03 09:16:59 nicm Exp $ */ +/* $Id: input.c,v 1.19 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -171,16 +171,6 @@ input_free(struct input_ctx *ictx) ARRAY_FREE(&ictx->args); } -void -input_parse1(struct screen *s, u_char *buf, size_t len, struct buffer *b) -{ - struct input_ctx ictx; - - input_init(&ictx, s); - input_parse(&ictx, buf, len, b); - input_free(&ictx); -} - void input_parse(struct input_ctx *ictx, u_char *buf, size_t len, struct buffer *b) { diff --git a/local.c b/local.c index a780aa39..0bf64126 100644 --- a/local.c +++ b/local.c @@ -1,4 +1,4 @@ -/* $Id: local.c,v 1.13 2007-10-02 15:13:59 nicm Exp $ */ +/* $Id: local.c,v 1.14 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -349,7 +349,7 @@ local_putp(const char *s) /* Return waiting keys if any. */ int -local_key(size_t *used) +local_key(void) { struct local_key *lk; u_int i; @@ -368,8 +368,6 @@ local_key(size_t *used) log_debug("got key: " "%s %d \"%s\"", lk->name, lk->code, lk->string); buffer_remove(local_in, lk->size); - if (used != NULL) - *used = lk->size; return (lk->code); } @@ -377,8 +375,6 @@ local_key(size_t *used) lk = local_keys + i; } - if (used != NULL) - *used = 1; return (input_extract8(local_in)); } diff --git a/server-fn.c b/server-fn.c index 83faba07..8048e8b7 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $Id: server-fn.c,v 1.11 2007-10-02 17:45:05 nicm Exp $ */ +/* $Id: server-fn.c,v 1.12 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -164,10 +164,9 @@ server_draw_client(struct client *c, u_int py_upper, u_int py_lower) size = BUFFER_USED(c->out) - size; log_debug("redrawing screen, %zu bytes", size); if (size != 0) { - hdr.type = MSG_OUTPUT; + hdr.type = MSG_DATA; hdr.size = size; - memcpy( - BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr); + memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr); } else buffer_reverse_add(c->out, sizeof hdr); @@ -191,7 +190,7 @@ server_draw_status(struct client *c) status_write(c); size = BUFFER_USED(c->out) - size; - hdr.type = MSG_OUTPUT; + hdr.type = MSG_DATA; hdr.size = size; memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr); } @@ -237,7 +236,7 @@ server_write_message(struct client *c, const char *fmt, ...) xfree(msg); size = BUFFER_USED(c->out) - size; - hdr.type = MSG_OUTPUT; + hdr.type = MSG_DATA; hdr.size = size; memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr); @@ -256,7 +255,7 @@ server_write_message(struct client *c, const char *fmt, ...) status_write(c); size = BUFFER_USED(c->out) - size; - hdr.type = MSG_OUTPUT; + hdr.type = MSG_DATA; hdr.size = size; memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr); } diff --git a/server-msg.c b/server-msg.c index bf7af9de..5f2a421b 100644 --- a/server-msg.c +++ b/server-msg.c @@ -1,4 +1,4 @@ -/* $Id: server-msg.c,v 1.15 2007-10-03 09:17:00 nicm Exp $ */ +/* $Id: server-msg.c,v 1.16 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -25,19 +25,12 @@ #include "tmux.h" int server_msg_fn_attach(struct hdr *, struct client *); -int server_msg_fn_create(struct hdr *, struct client *); -int server_msg_fn_input(struct hdr *, struct client *); -int server_msg_fn_last(struct hdr *, struct client *); +int server_msg_fn_keys(struct hdr *, struct client *); int server_msg_fn_new(struct hdr *, struct client *); -int server_msg_fn_next(struct hdr *, struct client *); -int server_msg_fn_previous(struct hdr *, struct client *); -int server_msg_fn_refresh(struct hdr *, struct client *); int server_msg_fn_rename(struct hdr *, struct client *); -int server_msg_fn_select(struct hdr *, struct client *); int server_msg_fn_sessions(struct hdr *, struct client *); int server_msg_fn_size(struct hdr *, struct client *); int server_msg_fn_windowlist(struct hdr *, struct client *); -int server_msg_fn_windowinfo(struct hdr *, struct client *); int server_msg_fn_windows(struct hdr *, struct client *); struct server_msg { @@ -47,19 +40,12 @@ struct server_msg { }; const struct server_msg server_msg_table[] = { { MSG_ATTACH, server_msg_fn_attach }, - { MSG_CREATE, server_msg_fn_create }, - { MSG_INPUT, server_msg_fn_input }, - { MSG_LAST, server_msg_fn_last }, + { MSG_KEYS, server_msg_fn_keys }, { MSG_NEW, server_msg_fn_new }, - { MSG_NEXT, server_msg_fn_next }, - { MSG_PREVIOUS, server_msg_fn_previous }, - { MSG_REFRESH, server_msg_fn_refresh }, { MSG_RENAME, server_msg_fn_rename }, - { MSG_SELECT, server_msg_fn_select }, { MSG_SESSIONS, server_msg_fn_sessions }, { MSG_SIZE, server_msg_fn_size }, { MSG_WINDOWLIST, server_msg_fn_windowlist }, - { MSG_WINDOWINFO, server_msg_fn_windowinfo }, { MSG_WINDOWS, server_msg_fn_windows }, }; #define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0]) @@ -134,7 +120,7 @@ server_msg_fn_new(struct hdr *hdr, struct client *c) fatalx("session_create failed"); xfree(cmd); - server_write_client(c, MSG_DONE, NULL, 0); + server_write_client(c, MSG_OKAY, NULL, 0); server_draw_client(c, 0, c->sy - 1); return (0); @@ -174,65 +160,6 @@ server_msg_fn_attach(struct hdr *hdr, struct client *c) return (0); } -/* Create message from client. */ -int -server_msg_fn_create(struct hdr *hdr, struct client *c) -{ - const char *shell; - char *cmd; - - if (c->session == NULL) - return (0); - if (hdr->size != 0) - fatalx("bad MSG_CREATE size"); - - shell = getenv("SHELL"); - if (shell == NULL) - shell = "/bin/ksh"; - xasprintf(&cmd, "%s -l", shell); - if (session_new(c->session, cmd, c->sx, c->sy) != 0) - fatalx("session_new failed"); - xfree(cmd); - - server_draw_client(c, 0, c->sy - 1); - - return (0); -} - -/* Next message from client. */ -int -server_msg_fn_next(struct hdr *hdr, struct client *c) -{ - if (c->session == NULL) - return (0); - if (hdr->size != 0) - fatalx("bad MSG_NEXT size"); - - if (session_next(c->session) == 0) - server_window_changed(c); - else - server_write_message(c, "No next window"); - - return (0); -} - -/* Previous message from client. */ -int -server_msg_fn_previous(struct hdr *hdr, struct client *c) -{ - if (c->session == NULL) - return (0); - if (hdr->size != 0) - fatalx("bad MSG_PREVIOUS size"); - - if (session_previous(c->session) == 0) - server_window_changed(c); - else - server_write_message(c, "No previous window"); - - return (0); -} - /* Size message from client. */ int server_msg_fn_size(struct hdr *hdr, struct client *c) @@ -261,52 +188,34 @@ server_msg_fn_size(struct hdr *hdr, struct client *c) return (0); } -/* Input message from client. */ +/* Keys message from client. */ int -server_msg_fn_input(struct hdr *hdr, struct client *c) +server_msg_fn_keys(struct hdr *hdr, struct client *c) { - if (c->session == NULL) - return (0); - - window_input(c->session->window, c->in, hdr->size); - - return (0); -} - -/* Refresh message from client. */ -int -server_msg_fn_refresh(struct hdr *hdr, struct client *c) -{ - struct refresh_data data; + int key; + size_t size; if (c->session == NULL) return (0); - if (hdr->size != 0 && hdr->size != sizeof data) - fatalx("bad MSG_REFRESH size"); + if (hdr->size & 0x1) + fatalx("bad MSG_KEYS size"); - server_draw_client(c, 0, c->sy - 1); + size = hdr->size; + while (size != 0) { + key = input_extract16(c->in); + size -= 2; - return (0); -} + if (c->prefix) { + cmd_dispatch(c, key); + c->prefix = 0; + continue; + } -/* Select message from client. */ -int -server_msg_fn_select(struct hdr *hdr, struct client *c) -{ - struct select_data data; - - if (c->session == NULL) - return (0); - if (hdr->size != sizeof data) - fatalx("bad MSG_SELECT size"); - buffer_read(c->in, &data, hdr->size); - - if (c->session == NULL) - return (0); - if (session_select(c->session, data.idx) == 0) - server_window_changed(c); - else - server_write_message(c, "Window %u not present", data.idx); + if (key == cmd_prefix) + c->prefix = 1; + else + window_key(c->session->window, key); + } return (0); } @@ -429,7 +338,7 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c) strlcpy(w->name, data.newname, sizeof w->name); - server_write_client(c, MSG_DONE, NULL, 0); + server_write_client(c, MSG_OKAY, NULL, 0); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c != NULL && c->session != NULL) { @@ -441,23 +350,6 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c) return (0); } -/* Last window message from client */ -int -server_msg_fn_last(struct hdr *hdr, struct client *c) -{ - if (c->session == NULL) - return (0); - if (hdr->size != 0) - fatalx("bad MSG_LAST size"); - - if (session_last(c->session) == 0) - server_window_changed(c); - else - server_write_message(c, "No last window"); - - return (0); -} - /* Window list message from client */ int server_msg_fn_windowlist(struct hdr *hdr, struct client *c) @@ -492,33 +384,3 @@ server_msg_fn_windowlist(struct hdr *hdr, struct client *c) return (0); } - -/* Window info message from client */ -int -server_msg_fn_windowinfo(struct hdr *hdr, struct client *c) -{ - struct window *w; - char *buf; - size_t len; - u_int i; - - if (c->session == NULL) - return (0); - if (hdr->size != 0) - fatalx("bad MSG_WINDOWINFO size"); - - len = c->sx + 1; - buf = xmalloc(len); - - w = c->session->window; - window_index(&c->session->windows, w, &i); - xsnprintf(buf, len, "%u:%s \"%s\" (size %u,%u) (cursor %u,%u) " - "(region %u,%u)", i, w->name, w->screen.title, w->screen.sx, - w->screen.sy, w->screen.cx, w->screen.cy, w->screen.ry_upper, - w->screen.ry_lower); - - server_write_message(c, "%s", buf); - xfree(buf); - - return (0); -} diff --git a/server.c b/server.c index 82bfd1d2..77897ede 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.16 2007-09-29 09:53:25 nicm Exp $ */ +/* $Id: server.c,v 1.17 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -315,11 +315,10 @@ server_handle_window(struct window *w) u_int i, j, p; b = buffer_create(BUFSIZ); - window_output(w, b); - + window_data(w, b); if (BUFFER_USED(b) != 0) { server_write_clients( - w, MSG_OUTPUT, BUFFER_OUT(b), BUFFER_USED(b)); + w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b)); } buffer_destroy(b); @@ -341,7 +340,7 @@ server_handle_window(struct window *w) if (s->window != w) server_write_message(c, "Bell in window %u", p); */ - server_write_client(c, MSG_OUTPUT, "\007", 1); + server_write_client(c, MSG_DATA, "\007", 1); } } diff --git a/tmux.h b/tmux.h index d2011b9c..f41f9975 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.33 2007-10-02 17:45:05 nicm Exp $ */ +/* $Id: tmux.h,v 1.34 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -260,23 +260,17 @@ struct buffer { /* Message codes. */ enum hdrtype { MSG_ATTACH, - MSG_CREATE, - MSG_DONE, + MSG_DATA, + MSG_DETACH, MSG_ERROR, MSG_EXIT, - MSG_INPUT, - MSG_LAST, + MSG_KEYS, MSG_NEW, - MSG_NEXT, - MSG_OUTPUT, + MSG_OKAY, MSG_PAUSE, - MSG_PREVIOUS, - MSG_REFRESH, MSG_RENAME, - MSG_SELECT, MSG_SESSIONS, MSG_SIZE, - MSG_WINDOWINFO, MSG_WINDOWLIST, MSG_WINDOWS, }; @@ -482,6 +476,8 @@ struct client { u_int sx; u_int sy; + int prefix; /* waiting for command */ + struct session *session; }; ARRAY_DECL(clients, struct client *); @@ -522,15 +518,17 @@ int op_list_windows(char *, int, char **); int client_init(char *, struct client_ctx *, int); int client_flush(struct client_ctx *); int client_main(struct client_ctx *); -void client_write_server(struct client_ctx *, enum hdrtype, void *, size_t); -void client_fill_sessid(struct sessid *, char [MAXNAMELEN]); /* client-msg.c */ int client_msg_dispatch(struct client_ctx *, char **); -/* command.c */ -extern int client_cmd_prefix; -int client_cmd_dispatch(int, struct client_ctx *, char **); +/* client-fn.c */ +void client_write_server(struct client_ctx *, enum hdrtype, void *, size_t); +void client_fill_sessid(struct sessid *, char [MAXNAMELEN]); + +/* cmd.c */ +extern int cmd_prefix; +void cmd_dispatch(struct client *, int); /* server.c */ extern struct clients clients; @@ -559,7 +557,6 @@ void status_write(struct client *c); /* input.c */ void input_init(struct input_ctx *, struct screen *); void input_free(struct input_ctx *); -void input_parse1(struct screen *, u_char *, size_t, struct buffer *); void input_parse(struct input_ctx *, u_char *, size_t, struct buffer *); uint8_t input_extract8(struct buffer *); uint16_t input_extract16(struct buffer *); @@ -602,7 +599,7 @@ void screen_fill_start_of_line( /* local.c */ int local_init(struct buffer **, struct buffer **); void local_done(void); -int local_key(size_t *); +int local_key(void); void local_output(struct buffer *, size_t); /* window.c */ @@ -617,8 +614,8 @@ struct window *window_previous(struct windows *, struct window *); struct window *window_at(struct windows *, u_int); int window_resize(struct window *, u_int, u_int); int window_poll(struct window *, struct pollfd *); -void window_input(struct window *, struct buffer *, size_t); -void window_output(struct window *, struct buffer *); +void window_key(struct window *, int); +void window_data(struct window *, struct buffer *); /* session.c */ extern struct sessions sessions; diff --git a/window.c b/window.c index e29fd766..67a37be2 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.15 2007-10-01 14:15:48 nicm Exp $ */ +/* $Id: window.c,v 1.16 2007-10-03 10:18:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -288,25 +288,11 @@ window_poll(struct window *w, struct pollfd *pfd) return (0); } -/* Process window input. */ +/* Process window key. */ void -window_input(struct window *w, struct buffer *b, size_t size) +window_key(struct window *w, int key) { - int key; - - while (size != 0) { - if (size < 1) - break; - size--; - key = input_extract8(b); - if (key == '\e') { - if (size < 2) - fatalx("underflow"); - size -= 2; - key = (int16_t) input_extract16(b); - } - input_translate_key(w->out, key); - } + input_translate_key(w->out, key); } /* @@ -314,7 +300,7 @@ window_input(struct window *w, struct buffer *b, size_t size) * sequences and strings and returned. */ void -window_output(struct window *w, struct buffer *b) +window_data(struct window *w, struct buffer *b) { FILE *f;