diff --git a/TODO b/TODO index a4c6c8f9..679c2230 100644 --- a/TODO +++ b/TODO @@ -61,8 +61,7 @@ - chmod +x socket when any client is attached - split clients into three RB trees by fd: attached/unattached/dead? or tailqs? what would be fastest per-char? -- everything should write via a screen and modes should be done by switching - screen out +- multiple paste buffers -- For 0.2 -------------------------------------------------------------------- - window splitting? diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index c5945743..e9b30022 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-copy-mode.c,v 1.3 2007-12-06 09:46:21 nicm Exp $ */ +/* $Id: cmd-copy-mode.c,v 1.4 2007-12-06 10:04:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,11 +44,8 @@ cmd_copy_mode_exec(unused void *ptr, struct cmd_ctx *ctx) { struct window *w = ctx->session->curw->window; - if (w->mode == NULL && ctx->flags & CMD_KEY) { - w->mode = &window_copy_mode; - w->mode->init(w); - server_redraw_window(w); - } + if (ctx->flags & CMD_KEY) + window_set_mode(w, &window_copy_mode); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-scroll-mode.c b/cmd-scroll-mode.c index 5bdf5bb6..2d444a9a 100644 --- a/cmd-scroll-mode.c +++ b/cmd-scroll-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-scroll-mode.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */ +/* $Id: cmd-scroll-mode.c,v 1.6 2007-12-06 10:04:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,11 +44,8 @@ cmd_scroll_mode_exec(unused void *ptr, struct cmd_ctx *ctx) { struct window *w = ctx->session->curw->window; - if (w->mode == NULL && ctx->flags & CMD_KEY) { - w->mode = &window_scroll_mode; - w->mode->init(w); - server_redraw_window(w); - } + if (ctx->flags & CMD_KEY) + window_set_mode(w, &window_scroll_mode); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/key-bindings.c b/key-bindings.c index 8889d81a..e217d798 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.23 2007-12-06 09:46:22 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.24 2007-12-06 10:04:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -165,11 +165,7 @@ key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...) struct window *w = ctx->session->curw->window; va_list ap; - if (w->mode == NULL) { - w->mode = &window_more_mode; - w->mode->init(w); - server_redraw_window(w); - } else if (w->mode != &window_more_mode) + if (window_set_mode(w, &window_more_mode) != 0) return; va_start(ap, fmt); diff --git a/tmux.h b/tmux.h index 77901477..90d4549f 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.109 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: tmux.h,v 1.110 2007-12-06 10:04:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -467,7 +467,7 @@ struct input_ctx { * right function to handle input and output. */ struct window_mode { - void (*init)(struct window *); + struct screen *(*init)(struct window *); void (*free)(struct window *); void (*resize)(struct window *, u_int, u_int); void (*key)(struct window *, int); @@ -905,6 +905,8 @@ struct window *window_create( const char *, const char *, const char **, u_int, u_int); void window_destroy(struct window *); int window_resize(struct window *, u_int, u_int); +int window_set_mode(struct window *, const struct window_mode *); +void window_reset_mode(struct window *); void window_parse(struct window *); void window_key(struct window *, int); diff --git a/window-copy.c b/window-copy.c index afbeb31d..bcf4b218 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $Id: window-copy.c,v 1.13 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: window-copy.c,v 1.14 2007-12-06 10:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -22,7 +22,7 @@ #include "tmux.h" -void window_copy_init(struct window *); +struct screen *window_copy_init(struct window *); void window_copy_free(struct window *); void window_copy_resize(struct window *, u_int, u_int); void window_copy_key(struct window *, int); @@ -76,7 +76,7 @@ struct window_copy_mode_data { u_int cy; }; -void +struct screen * window_copy_init(struct window *w) { struct window_copy_mode_data *data; @@ -94,13 +94,14 @@ window_copy_init(struct window *w) screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base)); s->cx = data->cx; s->cy = data->cy; - w->screen = s; screen_write_start(&ctx, s, NULL, NULL); for (i = 0; i < screen_size_y(s); i++) window_copy_write_line(w, &ctx, i); screen_write_move_cursor(&ctx, data->cx, data->cy); screen_write_stop(&ctx); + + return (s); } void @@ -108,11 +109,8 @@ window_copy_free(struct window *w) { struct window_copy_mode_data *data = w->modedata; - w->screen = &w->base; screen_destroy(&data->screen); - - w->mode = NULL; - xfree(w->modedata); + xfree(data); } void @@ -136,8 +134,7 @@ window_copy_key(struct window *w, int key) switch (key) { case 'Q': case 'q': - window_copy_free(w); - server_redraw_window(w); + window_reset_mode(w); break; case 'h': case KEYC_LEFT: @@ -185,8 +182,7 @@ window_copy_key(struct window *w, int key) case '\027': /* C-w */ case '\r': /* enter */ window_copy_copy_selection(w); - window_copy_free(w); - server_redraw_window(w); + window_reset_mode(w); break; case '\001': /* C-a */ window_copy_cursor_start_of_line(w); diff --git a/window-more.c b/window-more.c index 64e4f03f..fc201500 100644 --- a/window-more.c +++ b/window-more.c @@ -1,4 +1,4 @@ -/* $Id: window-more.c,v 1.6 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: window-more.c,v 1.7 2007-12-06 10:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -22,7 +22,7 @@ #include "tmux.h" -void window_more_init(struct window *); +struct screen *window_more_init(struct window *); void window_more_free(struct window *); void window_more_resize(struct window *, u_int, u_int); void window_more_key(struct window *, int); @@ -83,7 +83,7 @@ window_more_add(struct window *w, const char *fmt, ...) va_end(ap); } -void +struct screen * window_more_init(struct window *w) { struct window_more_mode_data *data; @@ -96,7 +96,8 @@ window_more_init(struct window *w) s = &data->screen; screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base)); s->mode = 0; - w->screen = s; + + return (s); } void @@ -105,15 +106,12 @@ window_more_free(struct window *w) struct window_more_mode_data *data = w->modedata; u_int i; - w->screen = &w->base; - screen_destroy(&data->screen); - for (i = 0; i < ARRAY_LENGTH(&data->list); i++) xfree(ARRAY_ITEM(&data->list, i)); ARRAY_FREE(&data->list); - w->mode = NULL; - xfree(w->modedata); + screen_destroy(&data->screen); + xfree(data); } void @@ -135,8 +133,7 @@ window_more_key(struct window *w, int key) switch (key) { case 'Q': case 'q': - window_more_free(w); - server_redraw_window(w); + window_reset_mode(w); break; case 'k': case 'K': diff --git a/window-scroll.c b/window-scroll.c index 60d3d9cd..dee8d094 100644 --- a/window-scroll.c +++ b/window-scroll.c @@ -1,4 +1,4 @@ -/* $Id: window-scroll.c,v 1.15 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: window-scroll.c,v 1.16 2007-12-06 10:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -22,7 +22,7 @@ #include "tmux.h" -void window_scroll_init(struct window *); +struct screen *window_scroll_init(struct window *); void window_scroll_free(struct window *); void window_scroll_resize(struct window *, u_int, u_int); void window_scroll_key(struct window *, int); @@ -52,7 +52,7 @@ struct window_scroll_mode_data { u_int oy; }; -void +struct screen * window_scroll_init(struct window *w) { struct window_scroll_mode_data *data; @@ -67,12 +67,13 @@ window_scroll_init(struct window *w) s = &data->screen; screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base)); s->mode = 0; - w->screen = s; screen_write_start(&ctx, s, NULL, NULL); for (i = 0; i < screen_size_y(s); i++) window_scroll_write_line(w, &ctx, i); screen_write_stop(&ctx); + + return (s); } void @@ -80,11 +81,8 @@ window_scroll_free(struct window *w) { struct window_scroll_mode_data *data = w->modedata; - w->screen = &w->base; screen_destroy(&data->screen); - - w->mode = NULL; - xfree(w->modedata); + xfree(data); } void @@ -107,8 +105,7 @@ window_scroll_key(struct window *w, int key) switch (key) { case 'Q': case 'q': - window_scroll_free(w); - server_redraw_window(w); + window_reset_mode(w); break; case 'h': case KEYC_LEFT: diff --git a/window.c b/window.c index 47d4f05d..366f80d3 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.33 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: window.c,v 1.34 2007-12-06 10:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -244,9 +244,8 @@ window_destroy(struct window *w) input_free(w); + window_reset_mode(w); screen_destroy(&w->base); - if (w->mode != NULL) - w->mode->free(w); buffer_destroy(w->in); buffer_destroy(w->out); @@ -276,6 +275,35 @@ window_resize(struct window *w, u_int sx, u_int sy) return (0); } +int +window_set_mode(struct window *w, const struct window_mode *mode) +{ + struct screen *s; + + if (w->mode != NULL || w->mode == mode) + return (1); + + w->mode = mode; + + if ((s = w->mode->init(w)) != NULL) + w->screen = s; + server_redraw_window(w); + return (0); +} + +void +window_reset_mode(struct window *w) +{ + if (w->mode == NULL) + return; + + w->mode->free(w); + w->mode = NULL; + + w->screen = &w->base; + server_redraw_window(w); +} + void window_parse(struct window *w) {