diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | cmd-detach-session.c | 4 | ||||
-rw-r--r-- | cmd-new-session.c | 4 | ||||
-rw-r--r-- | cmd-new-window.c | 170 | ||||
-rw-r--r-- | cmd.c | 3 | ||||
-rw-r--r-- | key-bindings.c | 8 | ||||
-rw-r--r-- | server-fn.c | 16 | ||||
-rw-r--r-- | server-msg.c | 22 | ||||
-rw-r--r-- | server.c | 4 | ||||
-rw-r--r-- | session.c | 22 | ||||
-rw-r--r-- | status.c | 4 | ||||
-rw-r--r-- | tmux.h | 19 | ||||
-rw-r--r-- | window.c | 44 |
13 files changed, 257 insertions, 69 deletions
@@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.13 2007-10-03 21:31:07 nicm Exp $ +# $Id: Makefile,v 1.14 2007-10-03 23:32:26 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean @@ -19,8 +19,8 @@ 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-fn.c key-string.c \ - key-bindings.c \ - cmd.c cmd-new-session.c cmd-detach-session.c cmd-list-sessions.c + key-bindings.c cmd.c cmd-new-session.c cmd-detach-session.c \ + cmd-list-sessions.c cmd-new-window.c YACC= yacc -d diff --git a/cmd-detach-session.c b/cmd-detach-session.c index bcb858a7..c9f41352 100644 --- a/cmd-detach-session.c +++ b/cmd-detach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-detach-session.c,v 1.1 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: cmd-detach-session.c,v 1.2 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -67,7 +67,7 @@ cmd_detach_session_parse(void **ptr, int argc, char **argv, char **cause) } } argc -= optind; - argv -= optind; + argv += optind; if (argc != 0) goto usage; diff --git a/cmd-new-session.c b/cmd-new-session.c index 6ed04ed8..229115a5 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-session.c,v 1.1 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: cmd-new-session.c,v 1.2 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -71,7 +71,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause) } } argc -= optind; - argv -= optind; + argv += optind; if (argc != 0) goto usage; diff --git a/cmd-new-window.c b/cmd-new-window.c new file mode 100644 index 00000000..9a78ab31 --- /dev/null +++ b/cmd-new-window.c @@ -0,0 +1,170 @@ +/* $Id: cmd-new-window.c,v 1.1 2007-10-03 23:32:26 nicm Exp $ */ + +/* + * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> + * + * 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 <sys/types.h> + +#include <getopt.h> + +#include "tmux.h" + +/* + * Create a new window. + */ + +int cmd_new_window_parse(void **, int, char **, char **); +const char *cmd_new_window_usage(void); +void cmd_new_window_exec(void *, struct cmd_ctx *); +void cmd_new_window_send(void *, struct buffer *); +void cmd_new_window_recv(void **, struct buffer *); +void cmd_new_window_free(void *); + +struct cmd_new_window_data { + char *name; + char *cmd; + int flag_detached; +}; + +const struct cmd_entry cmd_new_window_entry = { + CMD_NEWWINDOW, "new-window", "neww", 0, + cmd_new_window_parse, + cmd_new_window_usage, + cmd_new_window_exec, + cmd_new_window_send, + cmd_new_window_recv, + cmd_new_window_free +}; + +int +cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause) +{ + struct cmd_new_window_data *data; + int opt; + + *ptr = data = xmalloc(sizeof *data); + data->flag_detached = 0; + data->name = NULL; + data->cmd = NULL; + + while ((opt = getopt(argc, argv, "dn:")) != EOF) { + switch (opt) { + case 'n': + data->name = xstrdup(optarg); + break; + case 'd': + data->flag_detached = 1; + break; + default: + goto usage; + } + } + argc -= optind; + argv += optind; + if (argc != 0 && argc != 1) + goto usage; + + data->cmd = NULL; + if (argc == 1) + data->cmd = xstrdup(argv[0]); + + return (0); + +usage: + usage(cause, "%s", cmd_new_window_usage()); + + if (data->name != NULL) + xfree(data->name); + if (data->cmd != NULL) + xfree(data->cmd); + xfree(data); + return (-1); +} + +const char * +cmd_new_window_usage(void) +{ + return ("new-window [command]"); +} + +void +cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx) +{ + struct cmd_new_window_data *data = ptr, std = { NULL, NULL, 0 }; + struct client *c = ctx->client; + struct session *s = ctx->session; + char *cmd; + u_int i; + + if (data == NULL) + data = &std; + + cmd = data->cmd; + if (cmd == NULL) + cmd = default_command; + + if (session_new(s, data->name, cmd, &i) != 0) { + ctx->error(ctx, "command failed: %s", cmd); + return; + } + if (!data->flag_detached) + session_select(s, i); + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c != NULL && c->session == s) { + if (!data->flag_detached) + server_draw_client(c); + server_draw_status(c); + } + } + + if (!(ctx->flags & CMD_KEY)) + server_write_client(c, MSG_EXIT, NULL, 0); +} + +void +cmd_new_window_send(void *ptr, struct buffer *b) +{ + struct cmd_new_window_data *data = ptr; + + buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->name); + cmd_send_string(b, data->cmd); +} + +void +cmd_new_window_recv(void **ptr, struct buffer *b) +{ + struct cmd_new_window_data *data; + + *ptr = data = xmalloc(sizeof *data); + buffer_read(b, data, sizeof *data); + data->name = cmd_recv_string(b); + data->cmd = cmd_recv_string(b); +} + +void +cmd_new_window_free(void *ptr) +{ + struct cmd_new_window_data *data = ptr; + + if (data->name != NULL) + xfree(data->name); + if (data->cmd != NULL) + xfree(data->cmd); + xfree(data); +} @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.5 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: cmd.c,v 1.6 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -27,6 +27,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_detach_session_entry, &cmd_list_sessions_entry, &cmd_new_session_entry, + &cmd_new_window_entry, NULL }; diff --git a/key-bindings.c b/key-bindings.c index 7cbd556b..397533ef 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.1 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.2 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -79,9 +79,9 @@ key_bindings_init(void) { 'd', &cmd_detach_session_entry }, { 'S', &cmd_list_sessions_entry }, { 's', &cmd_list_sessions_entry }, -/* { 'C', &cmd_new_window }, - { 'c', &cmd_new_window }, - { 'N', &cmd_next_window }, + { 'C', &cmd_new_window_entry }, + { 'c', &cmd_new_window_entry }, +/* { 'N', &cmd_next_window }, { 'n', &cmd_next_window }, { 'P', &cmd_previous_window }, { 'p', &cmd_previous_window }, diff --git a/server-fn.c b/server-fn.c index 7af77146..ca95da2c 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $Id: server-fn.c,v 1.14 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: server-fn.c,v 1.15 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -138,18 +138,6 @@ server_write_clients( } } -/* Changed client window. */ -void -server_window_changed(struct client *c) -{ - struct window *w; - - w = c->session->window; - if (c->sx != w->screen.sx || c->sy != w->screen.sy) - window_resize(w, c->sx, c->sy); - server_draw_client(c); -} - /* Draw window on client. */ void server_draw_client(struct client *c) @@ -228,7 +216,7 @@ server_write_message(struct client *c, const char *fmt, ...) size = BUFFER_USED(c->out); input_store_zero(c->out, CODE_CURSOROFF); - input_store_two(c->out, CODE_CURSORMOVE, c->sy + status_lines, 1); + input_store_two(c->out, CODE_CURSORMOVE, c->sy, 1); input_store_two(c->out, CODE_ATTRIBUTES, ATTR_REVERSE, 0x88); va_start(ap, fmt); xvasprintf(&msg, fmt, ap); diff --git a/server-msg.c b/server-msg.c index 89d57b0f..1a67e28a 100644 --- a/server-msg.c +++ b/server-msg.c @@ -1,4 +1,4 @@ -/* $Id: server-msg.c,v 1.20 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: server-msg.c,v 1.21 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -167,7 +167,7 @@ server_msg_fn_resize(struct hdr *hdr, struct client *c) u_int sy; if (hdr->size != sizeof data) - fatalx("bad MSG_SIZE size"); + fatalx("bad MSG_RESIZE size"); buffer_read(c->in, &data, sizeof data); c->sx = data.sx; @@ -182,8 +182,22 @@ server_msg_fn_resize(struct hdr *hdr, struct client *c) sy = status_lines + 1; sy -= status_lines; - if (window_resize(c->session->window, c->sx, sy) != 0) - server_draw_client(c); + /* XXX */ + /* + * Okay. Need to be able to recalculate sizes: + * - every session has the size of the smallest client it is + * attached to + * - every window has the size of the smallest session it is + * attached to + * + * So, when a client is resized or a session added to a new client: + * - find the smallest client it is attached to, and resize to + * that size + * And when a session's window changes or a window is added/removed + * from a session: + * - find the smallest session the window is attached to + * and use that + */ return (0); } @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.20 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: server.c,v 1.21 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -379,7 +379,7 @@ server_lost_window(struct window *w) c->session = NULL; server_write_client(c, MSG_EXIT, NULL, 0); } else - server_window_changed(c); + server_draw_client(c); } } } @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.20 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: session.c,v 1.21 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -55,6 +55,9 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy) s->window = s->last = NULL; ARRAY_INIT(&s->windows); + s->sx = sx; + s->sy = sy; + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { if (ARRAY_ITEM(&sessions, i) == NULL) { ARRAY_SET(&sessions, i, s); @@ -68,10 +71,11 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy) s->name = xstrdup(name); else xasprintf(&s->name, "%u", i); - if (session_new(s, cmd, sx, sy) != 0) { + if (session_new(s, NULL, cmd, &i) != 0) { session_destroy(s); return (NULL); } + session_select(s, i); return (s); } @@ -108,24 +112,22 @@ session_index(struct session *s, u_int *i) /* Create a new window on a session. */ int -session_new(struct session *s, const char *cmd, u_int sx, u_int sy) +session_new(struct session *s, const char *name, const char *cmd, u_int *i) { struct window *w; const char *environ[] = { NULL, "TERM=screen", NULL }; char buf[256]; - u_int i; - if (session_index(s, &i) != 0) + if (session_index(s, i) != 0) fatalx("session not found"); - xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i); + xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), *i); environ[0] = buf; - if ((w = window_create(cmd, environ, sx, sy)) == NULL) + if ((w = window_create(name, cmd, environ, s->sx, s->sy)) == NULL) return (-1); session_attach(s, w); - - s->last = s->window; - s->window = w; + + window_index(&s->windows, w, i); return (0); } @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.1 2007-10-01 14:53:29 nicm Exp $ */ +/* $Id: status.c,v 1.2 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -34,7 +34,7 @@ status_write(struct client *c) u_int i; input_store_zero(b, CODE_CURSOROFF); - input_store_two(b, CODE_CURSORMOVE, s->sy + 1, 1); + input_store_two(b, CODE_CURSORMOVE, c->sy - status_lines + 1, 1); input_store_two(b, CODE_ATTRIBUTES, ATTR_REVERSE, 0x20); size = s->sx; @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.38 2007-10-03 21:31:07 nicm Exp $ */ +/* $Id: tmux.h,v 1.39 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -395,7 +395,7 @@ struct input_ctx { /* Window structure. */ struct window { - char name[MAXNAMELEN]; + char *name; int fd; struct buffer *in; @@ -417,6 +417,9 @@ struct session { char *name; time_t tim; + u_int sx; + u_int sy; + struct window *window; struct window *last; struct windows windows; @@ -454,9 +457,10 @@ struct client_ctx { /* Key/command line command. */ enum cmd_type { - CMD_NEWSESSION, CMD_DETACHSESSION, CMD_LISTSESSIONS, + CMD_NEWSESSION, + CMD_NEWWINDOW, }; struct cmd_ctx { @@ -518,9 +522,10 @@ struct cmd *cmd_recv(struct buffer *); void cmd_free(struct cmd *); void cmd_send_string(struct buffer *, const char *); char *cmd_recv_string(struct buffer *); -extern const struct cmd_entry cmd_new_session_entry; extern const struct cmd_entry cmd_detach_session_entry; extern const struct cmd_entry cmd_list_sessions_entry; +extern const struct cmd_entry cmd_new_session_entry; +extern const struct cmd_entry cmd_new_window_entry; /* bind.c */ const struct bind *cmdx_lookup_bind(const char *); @@ -628,7 +633,8 @@ void local_output(struct buffer *, size_t); /* window.c */ extern struct windows windows; -struct window *window_create(const char *, const char **, u_int, u_int); +struct window *window_create( + const char *, const char *, const char **, u_int, u_int); int window_index(struct windows *, struct window *, u_int *); void window_add(struct windows *, struct window *); void window_remove(struct windows *, struct window *); @@ -647,7 +653,8 @@ struct session *session_find(const char *); struct session *session_create(const char *, const char *, u_int, u_int); void session_destroy(struct session *); int session_index(struct session *, u_int *); -int session_new(struct session *, const char *, u_int, u_int); +int session_new( + struct session *, const char *, const char *, u_int *); void session_attach(struct session *, struct window *); int session_detach(struct session *, struct window *); int session_has(struct session *, struct window *); @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.17 2007-10-03 13:07:42 nicm Exp $ */ +/* $Id: window.c,v 1.18 2007-10-03 23:32:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -52,13 +52,14 @@ struct windows windows; /* Create a new window. */ struct window * -window_create(const char *cmd, const char **environ, u_int sx, u_int sy) +window_create( + const char *name, const char *cmd, const char **environ, u_int sx, u_int sy) { struct window *w; struct winsize ws; struct termios tio; int fd, mode; - char *ptr, *name; + char *ptr, *copy; const char **entry; memset(&ws, 0, sizeof ws); @@ -104,25 +105,28 @@ window_create(const char *cmd, const char **environ, u_int sx, u_int sy) screen_create(&w->screen, sx, sy); input_init(&w->ictx, &w->screen); - /* XXX */ - if (strncmp(cmd, "exec ", (sizeof "exec ") - 1) == 0) - name = xstrdup(cmd + sizeof "exec "); - else - name = xstrdup(cmd); - if ((ptr = strchr(name, ' ')) != NULL) { - if (ptr != name && ptr[-1] != '\\') - *ptr = '\0'; - else { - while ((ptr = strchr(ptr + 1, ' ')) != NULL) { - if (ptr[-1] != '\\') { - *ptr = '\0'; - break; + if (name == NULL) { + /* XXX */ + if (strncmp(cmd, "exec ", (sizeof "exec ") - 1) == 0) + copy = xstrdup(cmd + sizeof "exec "); + else + copy = xstrdup(cmd); + if ((ptr = strchr(copy, ' ')) != NULL) { + if (ptr != copy && ptr[-1] != '\\') + *ptr = '\0'; + else { + while ((ptr = strchr(ptr + 1, ' ')) != NULL) { + if (ptr[-1] != '\\') { + *ptr = '\0'; + break; + } } } } - } - strlcpy(w->name, xbasename(name), sizeof w->name); - xfree(name); + w->name = xstrdup(xbasename(copy)); + xfree(copy); + } else + w->name = xstrdup(name); window_add(&windows, w); w->references = 1; @@ -186,6 +190,8 @@ window_destroy(struct window *w) buffer_destroy(w->in); buffer_destroy(w->out); + + xfree(w->name); xfree(w); } |