From 103748d6adfe1b2d706cb0a1e1a128be5366d655 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 6 Dec 2007 09:46:23 +0000 Subject: Major reorganisation of screen handling. --- CHANGES | 10 +- GNUmakefile | 4 +- Makefile | 4 +- TODO | 16 +- buffer.c | 4 +- client-msg.c | 8 +- client.c | 14 +- cmd-attach-session.c | 6 +- cmd-bind-key.c | 6 +- cmd-copy-mode.c | 4 +- cmd-kill-session.c | 6 +- cmd-kill-window.c | 8 +- cmd-last-window.c | 6 +- cmd-link-window.c | 10 +- cmd-list-windows.c | 20 +- cmd-new-session.c | 10 +- cmd-new-window.c | 10 +- cmd-next-window.c | 6 +- cmd-paste-buffer.c | 4 +- cmd-previous-window.c | 6 +- cmd-rename-session.c | 8 +- cmd-rename-window.c | 8 +- cmd-scroll-mode.c | 4 +- cmd-select-window.c | 10 +- cmd-send-prefix.c | 4 +- cmd-set-option.c | 16 +- cmd-swap-window.c | 8 +- cmd-switch-client.c | 10 +- cmd-unbind-key.c | 6 +- cmd-unlink-window.c | 8 +- cmd.c | 12 +- input.c | 398 +++++++++++---------------------- key-bindings.c | 10 +- resize.c | 16 +- screen-display.c | 191 ++++++---------- screen-redraw.c | 218 ++++++++++++++++++ screen-write.c | 516 ++++++++++++++++++++++++++++++++++++++++++ screen.c | 450 +++++++++---------------------------- server-fn.c | 83 +++---- server-msg.c | 16 +- server.c | 8 +- session.c | 18 +- status.c | 24 +- tmux.c | 10 +- tmux.h | 211 ++++++++++-------- tty-keys.c | 4 +- tty-write.c | 16 +- tty.c | 47 +++- window-copy.c | 603 +++++++++++++++++++++++++++++++------------------- window-more.c | 227 ++++++++++--------- window-scroll.c | 266 ++++++++++++---------- window.c | 36 ++- 52 files changed, 2085 insertions(+), 1539 deletions(-) create mode 100644 screen-redraw.c create mode 100644 screen-write.c diff --git a/CHANGES b/CHANGES index 932ec115..69ef8fb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +06 December 2007 + +* Another major reorganisation, this time of screen handling. A new set of + functions, screen_write_*, are now used to write to a screen and a tty + simultaneously. These are used by the input parser to update the base + window screen and also by the different modes which now interpose their own + screen. + 30 November 2007 * Support \ek...\e\ to set window name. @@ -289,4 +297,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.89 2007-11-30 11:08:34 nicm Exp $ +$Id: CHANGES,v 1.90 2007-12-06 09:46:21 nicm Exp $ diff --git a/GNUmakefile b/GNUmakefile index 3acfd1c7..7c3354f1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.8 2007-11-25 22:08:13 nicm Exp $ +# $Id: GNUmakefile,v 1.9 2007-12-06 09:46:21 nicm Exp $ .PHONY: clean @@ -37,7 +37,7 @@ CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align -LDFLAGS+= +LDFLAGS+= LIBS+= -lncurses PREFIX?= /usr/local diff --git a/Makefile b/Makefile index 13155c90..cf31418e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.51 2007-11-30 13:59:16 nicm Exp $ +# $Id: Makefile,v 1.52 2007-12-06 09:46:21 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -28,7 +28,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \ cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \ cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c \ - tty.c tty-keys.c tty-write.c + tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c CC?= cc INCDIRS+= -I. -I- -I/usr/local/include diff --git a/TODO b/TODO index 47c7f90c..a4c6c8f9 100644 --- a/TODO +++ b/TODO @@ -66,13 +66,27 @@ -- For 0.2 -------------------------------------------------------------------- - window splitting? -- restore term cap checks +- restore term cap checks **** - anything which uses cmd_{send,recv}_string will break if the string is split. string length should be part of the command size - echo \\033[35\;46m\\033[2J last line quirk (with C-b r) - quick intro section (tmux new/attach/detach) etc - is ACS the right way round?? +-------- + +screen redraw. + +ops: +- redraw screen or section of screen to tty without altering it + (screen-redraw.c, screen_redraw_ctx) + (switching screen etc) +- draw to screen and optionally tty + (window output) + (screen-write.c, screen_write_ctx) +- copy line/column from one screen (inc history) at offset?? + (scroll/copy mode) + -------- kmous -- \E[M diff --git a/buffer.c b/buffer.c index f5864892..7bf0e4b0 100644 --- a/buffer.c +++ b/buffer.c @@ -1,4 +1,4 @@ -/* $Id: buffer.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: buffer.c,v 1.4 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -215,7 +215,7 @@ uint16_t buffer_read16(struct buffer *b) { uint16_t n; - + n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8); buffer_remove(b, 2); return (n); diff --git a/client-msg.c b/client-msg.c index 878bbcd0..65287f50 100644 --- a/client-msg.c +++ b/client-msg.c @@ -1,4 +1,4 @@ -/* $Id: client-msg.c,v 1.13 2007-11-27 20:03:08 nicm Exp $ */ +/* $Id: client-msg.c,v 1.14 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,7 +34,7 @@ int client_msg_fn_pause(struct hdr *, struct client_ctx *, char **); struct client_msg { enum hdrtype type; - + int (*fn)(struct hdr *, struct client_ctx *, char **); }; struct client_msg client_msg_table[] = { @@ -58,7 +58,7 @@ client_msg_dispatch(struct client_ctx *cctx, char **error) if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size) return (1); buffer_remove(cctx->srv_in, sizeof hdr); - + for (i = 0; i < NCLIENTMSG; i++) { msg = client_msg_table + i; if (msg->type == hdr.type) { @@ -92,7 +92,7 @@ client_msg_fn_detach( client_write_server(cctx, MSG_EXITING, NULL, 0); cctx->flags |= CCTX_DETACH; - + return (0); } diff --git a/client.c b/client.c index 4caf30a4..20e5dc33 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.24 2007-12-01 11:10:33 nicm Exp $ */ +/* $Id: client.c,v 1.25 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -134,7 +134,7 @@ client_main(struct client_ctx *cctx) pfd.events = POLLIN; if (BUFFER_USED(cctx->srv_out) > 0) pfd.events |= POLLOUT; - + if (poll(&pfd, 1, timeout) == -1) { if (errno == EAGAIN || errno == EINTR) continue; @@ -157,18 +157,18 @@ client_main(struct client_ctx *cctx) break; } } - + out: if (sigterm) { printf("[terminated]\n"); return (1); } - + if (cctx->flags & CCTX_EXIT) { printf("[exited]\n"); return (0); } - + if (cctx->flags & CCTX_DETACH) { printf("[detached]\n"); return (0); @@ -187,13 +187,13 @@ client_handle_winch(struct client_ctx *cctx) { struct msg_resize_data data; struct winsize ws; - + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) fatal("ioctl failed"); data.sx = ws.ws_col; data.sy = ws.ws_row; client_write_server(cctx, MSG_RESIZE, &data, sizeof data); - + sigwinch = 0; } diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 930b756b..1741b36e 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.10 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: cmd-attach-session.c,v 1.11 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -40,7 +40,7 @@ const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", "[-d]", CMD_CANTNEST|CMD_NOCLIENT, cmd_attach_session_parse, - cmd_attach_session_exec, + cmd_attach_session_exec, cmd_attach_session_send, cmd_attach_session_recv, cmd_attach_session_free @@ -63,7 +63,7 @@ cmd_attach_session_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 0) diff --git a/cmd-bind-key.c b/cmd-bind-key.c index 5f739aca..537a12f5 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -1,4 +1,4 @@ -/* $Id: cmd-bind-key.c,v 1.7 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-bind-key.c,v 1.8 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ const struct cmd_entry cmd_bind_key_entry = { "bind-key", "bind", "key command [arguments]", CMD_NOCLIENT|CMD_NOSESSION, cmd_bind_key_parse, - cmd_bind_key_exec, + cmd_bind_key_exec, cmd_bind_key_send, cmd_bind_key_recv, cmd_bind_key_free @@ -61,7 +61,7 @@ cmd_bind_key_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc < 1) diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 665507e1..c5945743 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-copy-mode.c,v 1.2 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: cmd-copy-mode.c,v 1.3 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,7 +33,7 @@ const struct cmd_entry cmd_copy_mode_entry = { "copy-mode", NULL, "", CMD_NOCLIENT, NULL, - cmd_copy_mode_exec, + cmd_copy_mode_exec, NULL, NULL, NULL diff --git a/cmd-kill-session.c b/cmd-kill-session.c index e4addc87..21cb6025 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-session.c,v 1.4 2007-11-21 13:11:41 nicm Exp $ */ +/* $Id: cmd-kill-session.c,v 1.5 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -47,7 +47,7 @@ cmd_kill_session_exec(unused void *ptr, struct cmd_ctx *ctx) { struct client *c; u_int i; - + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c->session == ctx->session) { @@ -57,7 +57,7 @@ cmd_kill_session_exec(unused void *ptr, struct cmd_ctx *ctx) } session_destroy(ctx->session); - + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-kill-window.c b/cmd-kill-window.c index e962fc75..13742e19 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-kill-window.c,v 1.6 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-kill-window.c,v 1.7 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ const struct cmd_entry cmd_kill_window_entry = { "kill-window", "killw", "[-i index]", CMD_NOCLIENT, cmd_kill_window_parse, - cmd_kill_window_exec, + cmd_kill_window_exec, cmd_kill_window_send, cmd_kill_window_recv, cmd_kill_window_free @@ -69,7 +69,7 @@ cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 0) @@ -117,7 +117,7 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx) } else server_redraw_client(c); } - + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-last-window.c b/cmd-last-window.c index 7052c1f1..e68289cd 100644 --- a/cmd-last-window.c +++ b/cmd-last-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-last-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-last-window.c,v 1.6 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,8 +45,8 @@ cmd_last_window_exec(unused void *ptr, struct cmd_ctx *ctx) if (session_last(ctx->session) == 0) server_redraw_session(ctx->session); else - ctx->error(ctx, "no last window"); - + ctx->error(ctx, "no last window"); + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-link-window.c b/cmd-link-window.c index 331c6c45..00e3b4a7 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-link-window.c,v 1.8 2007-11-21 15:05:53 nicm Exp $ */ +/* $Id: cmd-link-window.c,v 1.9 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,7 +45,7 @@ const struct cmd_entry cmd_link_window_entry = { "link-window", "linkw", "[-dk] [-i index] name index", CMD_NOCLIENT, cmd_link_window_parse, - cmd_link_window_exec, + cmd_link_window_exec, cmd_link_window_send, cmd_link_window_recv, cmd_link_window_free @@ -83,7 +83,7 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 2) @@ -116,7 +116,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - + if ((src = session_find(data->srcname)) == NULL) { ctx->error(ctx, "session not found: %s", data->srcname); return; @@ -155,7 +155,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx) dst->lastw = NULL; /* - * Can't error out after this or there could be an empty + * Can't error out after this or there could be an empty * session! */ } diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 111101b2..056af295 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-windows.c,v 1.14 2007-11-23 13:11:43 nicm Exp $ */ +/* $Id: cmd-list-windows.c,v 1.15 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -51,18 +51,18 @@ cmd_list_windows_exec(unused void *ptr, struct cmd_ctx *ctx) w = wl->window; size = 0; - for (i = 0; i < w->screen.hsize; i++) - size += w->screen.grid_size[i] * 3; - size += w->screen.hsize * (sizeof *w->screen.grid_data); - size += w->screen.hsize * (sizeof *w->screen.grid_attr); - size += w->screen.hsize * (sizeof *w->screen.grid_colr); - size += w->screen.hsize * (sizeof *w->screen.grid_size); + for (i = 0; i < w->base.hsize; i++) + size += w->base.grid_size[i] * 3; + size += w->base.hsize * (sizeof *w->base.grid_data); + size += w->base.hsize * (sizeof *w->base.grid_attr); + size += w->base.hsize * (sizeof *w->base.grid_colr); + size += w->base.hsize * (sizeof *w->base.grid_size); ctx->print(ctx, "%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]", - wl->idx, w->name, w->screen.title, ttyname(w->fd), - screen_size_x(&w->screen), screen_size_y(&w->screen), - w->screen.hsize, w->screen.hlimit, size); + wl->idx, w->name, w->base.title, ttyname(w->fd), + screen_size_x(&w->base), screen_size_y(&w->base), + w->base.hsize, w->base.hlimit, size); } if (ctx->cmdclient != NULL) diff --git a/cmd-new-session.c b/cmd-new-session.c index 418fbf8e..aff19eab 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-session.c,v 1.18 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: cmd-new-session.c,v 1.19 2007-12-06 09:46:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,7 +44,7 @@ const struct cmd_entry cmd_new_session_entry = { "[-d] [-s session-name] [-n window-name] [command]", CMD_STARTSERVER|CMD_NOCLIENT|CMD_NOSESSION|CMD_CANTNEST, cmd_new_session_parse, - cmd_new_session_exec, + cmd_new_session_exec, cmd_new_session_send, cmd_new_session_recv, cmd_new_session_free @@ -76,7 +76,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 0 && argc != 1) @@ -90,7 +90,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause) usage: usage(cause, "%s %s", cmd_new_session_entry.name, cmd_new_session_entry.usage); - + cmd_new_session_free(data); return (-1); } @@ -103,7 +103,7 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx) struct client *c = ctx->cmdclient; char *cmd, *cause; u_int sy; - + if (data == NULL) data = &std; diff --git a/cmd-new-window.c b/cmd-new-window.c index 730c0293..71d922f3 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-window.c,v 1.13 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-new-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,7 +44,7 @@ const struct cmd_entry cmd_new_window_entry = { "new-window", "neww", "[-d] [-i index] [-n name] [command]", CMD_NOCLIENT, cmd_new_window_parse, - cmd_new_window_exec, + cmd_new_window_exec, cmd_new_window_send, cmd_new_window_recv, cmd_new_window_free @@ -81,7 +81,7 @@ cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 0 && argc != 1) @@ -111,7 +111,7 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) data = &std; - + cmd = data->cmd; if (cmd == NULL) cmd = default_command; @@ -128,7 +128,7 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx) server_redraw_session(ctx->session); } else server_status_session(ctx->session); - + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-next-window.c b/cmd-next-window.c index 8a807714..4495558e 100644 --- a/cmd-next-window.c +++ b/cmd-next-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-next-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-next-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,8 +45,8 @@ cmd_next_window_exec(unused void *ptr, struct cmd_ctx *ctx) if (session_next(ctx->session) == 0) server_redraw_session(ctx->session); else - ctx->error(ctx, "no next window"); - + ctx->error(ctx, "no next window"); + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index b4bdf324..349feb48 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -1,4 +1,4 @@ -/* $Id: cmd-paste-buffer.c,v 1.1 2007-11-23 17:52:54 nicm Exp $ */ +/* $Id: cmd-paste-buffer.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -34,7 +34,7 @@ const struct cmd_entry cmd_paste_buffer_entry = { "paste-buffer", NULL, "paste", CMD_NOCLIENT, NULL, - cmd_paste_buffer_exec, + cmd_paste_buffer_exec, NULL, NULL, NULL diff --git a/cmd-previous-window.c b/cmd-previous-window.c index cdf0b7d8..d0423998 100644 --- a/cmd-previous-window.c +++ b/cmd-previous-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-previous-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-previous-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -45,8 +45,8 @@ cmd_previous_window_exec(unused void *ptr, struct cmd_ctx *ctx) if (session_previous(ctx->session) == 0) server_redraw_session(ctx->session); else - ctx->error(ctx, "no previous window"); - + ctx->error(ctx, "no previous window"); + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-rename-session.c b/cmd-rename-session.c index ae28eec6..498bacd2 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-session.c,v 1.3 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-rename-session.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ const struct cmd_entry cmd_rename_session_entry = { "rename-session", "rename", "new-name", CMD_NOCLIENT, cmd_rename_session_parse, - cmd_rename_session_exec, + cmd_rename_session_exec, cmd_rename_session_send, cmd_rename_session_recv, cmd_rename_session_free @@ -61,7 +61,7 @@ cmd_rename_session_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1) @@ -89,7 +89,7 @@ cmd_rename_session_exec(void *ptr, struct cmd_ctx *ctx) xfree(ctx->session->name); ctx->session->name = xstrdup(data->newname); - + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-rename-window.c b/cmd-rename-window.c index ba2f4fad..5ed0c161 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-rename-window.c,v 1.13 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-rename-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -42,7 +42,7 @@ const struct cmd_entry cmd_rename_window_entry = { "rename-window", "renamew", "[-i index] new-name", CMD_NOCLIENT, cmd_rename_window_parse, - cmd_rename_window_exec, + cmd_rename_window_exec, cmd_rename_window_send, cmd_rename_window_recv, cmd_rename_window_free @@ -71,7 +71,7 @@ cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1) @@ -110,7 +110,7 @@ cmd_rename_window_exec(void *ptr, struct cmd_ctx *ctx) wl->window->name = xstrdup(data->newname); server_status_session(ctx->session); - + 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 17d839ae..5bdf5bb6 100644 --- a/cmd-scroll-mode.c +++ b/cmd-scroll-mode.c @@ -1,4 +1,4 @@ -/* $Id: cmd-scroll-mode.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: cmd-scroll-mode.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,7 +33,7 @@ const struct cmd_entry cmd_scroll_mode_entry = { "scroll-mode", NULL, "", CMD_NOCLIENT, NULL, - cmd_scroll_mode_exec, + cmd_scroll_mode_exec, NULL, NULL, NULL diff --git a/cmd-select-window.c b/cmd-select-window.c index 16329ecf..896b18cb 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-select-window.c,v 1.10 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-select-window.c,v 1.11 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", "index", CMD_NOCLIENT, cmd_select_window_parse, - cmd_select_window_exec, + cmd_select_window_exec, cmd_select_window_send, cmd_select_window_recv, cmd_select_window_free @@ -75,7 +75,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1) @@ -86,7 +86,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause) xasprintf(cause, "index %s", errstr); goto error; } - + return (0); usage: @@ -116,7 +116,7 @@ cmd_select_window_exec(void *ptr, struct cmd_ctx *ctx) ctx->error(ctx, "no window %d", data->idx); break; } - + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index 3d556675..eb13b673 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.6 2007-11-21 13:11:41 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.7 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,6 +44,6 @@ cmd_send_prefix_exec(unused void *ptr, struct cmd_ctx *ctx) { window_key(ctx->client->session->curw->window, prefix_key); - if (ctx->cmdclient != NULL) + if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-set-option.c b/cmd-set-option.c index 70a4c3e4..d0e86c89 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.14 2007-11-23 12:48:20 nicm Exp $ */ +/* $Id: cmd-set-option.c,v 1.15 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -43,7 +43,7 @@ const struct cmd_entry cmd_set_option_entry = { "set-option", "set", "option value", CMD_NOCLIENT|CMD_NOSESSION, cmd_set_option_parse, - cmd_set_option_exec, + cmd_set_option_exec, cmd_set_option_send, cmd_set_option_recv, cmd_set_option_free @@ -64,7 +64,7 @@ cmd_set_option_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1 && argc != 2) @@ -104,7 +104,7 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx) number = -1; if (data->value != NULL) { number = strtonum(data->value, 0, INT_MAX, &errstr); - + bool = -1; if (number == 1 || strcasecmp(data->value, "on") == 0 || strcasecmp(data->value, "yes") == 0) @@ -171,10 +171,10 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx) server_redraw_client(c); } } - } else if (strcmp(data->option, "bell-action") == 0) { + } else if (strcmp(data->option, "bell-action") == 0) { if (data->value == NULL) { ctx->error(ctx, "invalid value"); - return; + return; } if (strcmp(data->value, "any") == 0) bell_action = BELL_ANY; @@ -186,10 +186,10 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx) ctx->error(ctx, "unknown bell-action: %s", data->value); return; } - } else if (strcmp(data->option, "default-command") == 0) { + } else if (strcmp(data->option, "default-command") == 0) { if (data->value == NULL) { ctx->error(ctx, "invalid value"); - return; + return; } xfree(default_command); default_command = xstrdup(data->value); diff --git a/cmd-swap-window.c b/cmd-swap-window.c index 66480ebf..6c4cac0f 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-swap-window.c,v 1.3 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-swap-window.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,7 +44,7 @@ const struct cmd_entry cmd_swap_window_entry = { "swap-window", "swapw", "[-i index] name index", CMD_NOCLIENT, cmd_swap_window_parse, - cmd_swap_window_exec, + cmd_swap_window_exec, cmd_swap_window_send, cmd_swap_window_recv, cmd_swap_window_free @@ -78,7 +78,7 @@ cmd_swap_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 2) @@ -112,7 +112,7 @@ cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - + if ((src = session_find(data->srcname)) == NULL) { ctx->error(ctx, "session not found: %s", data->srcname); return; diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 2d3788b7..ca122879 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -1,4 +1,4 @@ -/* $Id: cmd-switch-client.c,v 1.1 2007-11-16 21:31:03 nicm Exp $ */ +/* $Id: cmd-switch-client.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -42,7 +42,7 @@ const struct cmd_entry cmd_switch_client_entry = { "switch-client", "switchc", "session-name", CMD_NOSESSION, cmd_switch_client_parse, - cmd_switch_client_exec, + cmd_switch_client_exec, cmd_switch_client_send, cmd_switch_client_recv, cmd_switch_client_free @@ -62,7 +62,7 @@ cmd_switch_client_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1) @@ -88,14 +88,14 @@ cmd_switch_client_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - + if ((s = session_find(data->name)) == NULL) { ctx->error(ctx, "session not found: %s", data->name); return; } ctx->client->session = s; - + recalculate_sizes(); server_redraw_client(ctx->client); diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index 86a795a4..fd4e775f 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -1,4 +1,4 @@ -/* $Id: cmd-unbind-key.c,v 1.7 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-unbind-key.c,v 1.8 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -40,7 +40,7 @@ const struct cmd_entry cmd_unbind_key_entry = { "unbind-key", "unbind", "key", CMD_NOCLIENT|CMD_NOSESSION, cmd_unbind_key_parse, - cmd_unbind_key_exec, + cmd_unbind_key_exec, cmd_unbind_key_send, cmd_unbind_key_recv, cmd_unbind_key_free @@ -59,7 +59,7 @@ cmd_unbind_key_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 1) diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c index 9ed48104..577a2e2d 100644 --- a/cmd-unlink-window.c +++ b/cmd-unlink-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-unlink-window.c,v 1.4 2007-11-16 21:12:31 nicm Exp $ */ +/* $Id: cmd-unlink-window.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -41,7 +41,7 @@ const struct cmd_entry cmd_unlink_window_entry = { "unlink-window", "unlinkw", "[-i index]", CMD_NOCLIENT, cmd_unlink_window_parse, - cmd_unlink_window_exec, + cmd_unlink_window_exec, cmd_unlink_window_send, cmd_unlink_window_recv, cmd_unlink_window_free @@ -69,7 +69,7 @@ cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause) default: goto usage; } - } + } argc -= optind; argv += optind; if (argc != 0) @@ -98,7 +98,7 @@ cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx) if (data == NULL) return; - + if (data->idx < 0) data->idx = -1; if (data->idx == -1) diff --git a/cmd.c b/cmd.c index 6526fa90..8e46a92f 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.32 2007-11-23 17:52:54 nicm Exp $ */ +/* $Id: cmd.c,v 1.33 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -48,7 +48,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_scroll_mode_entry, &cmd_select_window_entry, &cmd_send_prefix_entry, - &cmd_set_option_entry, + &cmd_set_option_entry, &cmd_swap_window_entry, &cmd_switch_client_entry, &cmd_unbind_key_entry, @@ -70,7 +70,7 @@ cmd_parse(int argc, char **argv, char **cause) entry = NULL; for (entryp = cmd_table; *entryp != NULL; entryp++) { - if ((*entryp)->alias != NULL && + if ((*entryp)->alias != NULL && strcmp((*entryp)->alias, argv[0]) == 0) { entry = *entryp; break; @@ -165,7 +165,7 @@ cmd_recv(struct buffer *b) u_int m, n; buffer_read(b, &m, sizeof m); - + n = 0; for (entryp = cmd_table; *entryp != NULL; entryp++) { if (n == m) @@ -195,7 +195,7 @@ void cmd_send_string(struct buffer *b, const char *s) { size_t n; - + if (s == NULL) { n = 0; buffer_write(b, &n, sizeof n); @@ -218,7 +218,7 @@ cmd_recv_string(struct buffer *b) if (n == 0) return (NULL); - + s = xmalloc(n); buffer_read(b, s, n); s[n - 1] = '\0'; diff --git a/input.c b/input.c index 6ac6b54f..33c7f074 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.43 2007-11-30 11:08:35 nicm Exp $ */ +/* $Id: input.c,v 1.44 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -43,7 +43,6 @@ void input_abort_string(struct input_ctx *); int input_add_string(struct input_ctx *, u_char); char *input_get_string(struct input_ctx *); -void input_write(struct input_ctx *, int, ...); void input_state(struct input_ctx *, void *); void input_state_first(u_char, struct input_ctx *); @@ -85,13 +84,6 @@ void input_handle_sequence_decstbm(struct input_ctx *); void input_handle_sequence_sgr(struct input_ctx *); void input_handle_sequence_dsr(struct input_ctx *); -#define input_limit(v, lower, upper) do { \ - if (v < lower) \ - v = lower; \ - if (v > upper) \ - v = upper; \ -} while (0) - int input_new_argument(struct input_ctx *ictx) { @@ -183,19 +175,6 @@ input_get_string(struct input_ctx *ictx) return (s); } -void -input_write(struct input_ctx *ictx, int cmd, ...) -{ - va_list ap; - - if (ictx->w->screen.mode & (MODE_HIDDEN|MODE_BACKGROUND)) - return; - - va_start(ap, cmd); - tty_vwrite_window(ictx->w, cmd, ap); - va_end(ap); -} - void input_state(struct input_ctx *ictx, void *state) { @@ -239,11 +218,18 @@ input_parse(struct window *w) log_debug2("entry; buffer=%zu", ictx->len); + if (w->mode == NULL) + screen_write_start(&ictx->ctx, &w->base, tty_write_window, w); + else + screen_write_start(&ictx->ctx, &w->base, NULL, NULL); + while (ictx->off < ictx->len) { ch = ictx->buf[ictx->off++]; ictx->state(ch, ictx); } + screen_write_stop(&ictx->ctx); + buffer_remove(w->in, ictx->len); } @@ -253,7 +239,7 @@ input_state_first(u_char ch, struct input_ctx *ictx) if (INPUT_C0CONTROL(ch)) { if (ch == 0x1b) input_state(ictx, input_state_escape); - else + else input_handle_c0_control(ch, ictx); return; } @@ -268,10 +254,10 @@ input_state_first(u_char ch, struct input_ctx *ictx) input_handle_c1_control(ch, ictx); return; } - + input_handle_character(ch, ictx); } - + void input_state_escape(u_char ch, struct input_ctx *ictx) { @@ -326,7 +312,7 @@ input_state_title_first(u_char ch, struct input_ctx *ictx) input_start_string(ictx, STRING_IGNORE); input_state(ictx, input_state_title_second); return; - } + } input_state(ictx, input_state_first); } @@ -345,13 +331,10 @@ input_state_title_second(u_char ch, struct input_ctx *ictx) void input_state_title_next(u_char ch, struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - if (ch == '\007') { if (ictx->string_type == STRING_TITLE) { - xfree(s->title); - s->title = input_get_string(ictx); - input_write(ictx, TTY_TITLE, s->title); + screen_write_set_title( + &ictx->ctx, input_get_string(ictx)); } else input_abort_string(ictx); input_state(ictx, input_state_first); @@ -440,7 +423,7 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx) } return; } - + input_state(ictx, input_state_first); } @@ -449,13 +432,13 @@ input_state_sequence_intermediate(u_char ch, struct input_ctx *ictx) { if (INPUT_INTERMEDIATE(ch)) return; - + if (INPUT_UPPERCASE(ch) || INPUT_LOWERCASE(ch)) { input_state(ictx, input_state_first); input_handle_sequence(ch, ictx); return; } - + input_state(ictx, input_state_first); } @@ -496,82 +479,63 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx) void input_handle_character(u_char ch, struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch); - - if (s->cx == screen_size_x(s)) { - input_write(ictx, TTY_CHARACTER, '\r'); - input_write(ictx, TTY_CHARACTER, '\n'); - s->cx = 0; - screen_display_cursor_down(s); - } else if (!screen_in_x(s, s->cx) || !screen_in_y(s, s->cy)) - return; - - screen_display_cursor_set(s, ch); - input_write(ictx, TTY_CHARACTER, ch); - - s->cx++; + screen_write_put_character(&ictx->ctx, ch); } void input_handle_c0_control(u_char ch, struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; + struct screen *s = ictx->ctx.s; log_debug2("-- c0 %zu: %hhu", ictx->off, ch); switch (ch) { case '\0': /* NUL */ - return; + break; case '\n': /* LF */ - screen_display_cursor_down(s); + screen_write_cursor_down_scroll(&ictx->ctx); break; case '\r': /* CR */ - s->cx = 0; + screen_write_move_cursor(&ictx->ctx, 0, s->cy); break; case '\007': /* BELL */ ictx->w->flags |= WINDOW_BELL; - return; + break; case '\010': /* BS */ - if (s->cx > 0) - s->cx--; + screen_write_cursor_left(&ictx->ctx, 1); break; case '\011': /* TAB */ s->cx = ((s->cx / 8) * 8) + 8; if (s->cx > screen_last_x(s)) { s->cx = 0; - screen_display_cursor_down(s); + screen_write_cursor_down(&ictx->ctx, 1); } - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); - return; + screen_write_move_cursor(&ictx->ctx, s->cx, s->cy); + break; case '\016': /* SO */ s->attr |= ATTR_CHARSET; - input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr); - return; + screen_write_set_attributes(&ictx->ctx, s->attr, s->colr); + break; case '\017': /* SI */ s->attr &= ~ATTR_CHARSET; - input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr); - return; + screen_write_set_attributes(&ictx->ctx, s->attr, s->colr); + break; default: log_debug("unknown c0: %hhu", ch); - return; + break; } - input_write(ictx, TTY_CHARACTER, ch); } void input_handle_c1_control(u_char ch, struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - log_debug2("-- c1 %zu: %hhu (%c)", ictx->off, ch, ch); switch (ch) { case 'M': /* RI */ - screen_display_cursor_up(s); - input_write(ictx, TTY_REVERSEINDEX); + screen_write_cursor_up_scroll(&ictx->ctx); break; default: log_debug("unknown c1: %hhu", ch); @@ -582,16 +546,16 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx) void input_handle_private_two(u_char ch, struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; + struct screen *s = ictx->ctx.s; log_debug2("-- p2 %zu: %hhu (%c)", ictx->off, ch, ch); switch (ch) { case '=': /* DECKPAM */ - input_write(ictx, TTY_KKEYPADON); + screen_write_set_mode(&ictx->ctx, MODE_KKEYPAD); break; case '>': /* DECKPNM*/ - input_write(ictx, TTY_KKEYPADOFF); + screen_write_clear_mode(&ictx->ctx, MODE_KKEYPAD); break; case '7': /* DECSC */ s->saved_cx = s->cx; @@ -607,8 +571,8 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx) s->cy = s->saved_cy; s->attr = s->saved_attr; s->colr = s->saved_colr; - input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr); - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_set_attributes(&ictx->ctx, s->attr, s->colr); + screen_write_move_cursor(&ictx->ctx, s->cx, s->cy); break; default: log_debug("unknown p2: %hhu", ch); @@ -659,10 +623,10 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx) { 'n', input_handle_sequence_dsr }, { 'r', input_handle_sequence_decstbm }, }; - struct screen *s = &ictx->w->screen; + struct screen *s = ictx->ctx.s; u_int i; struct input_arg *iarg; - + log_debug2("-- sq %zu: %hhu (%c): %u [sx=%u, sy=%u, cx=%u, cy=%u, " "ru=%u, rl=%u]", ictx->off, ch, ch, ARRAY_LENGTH(&ictx->args), screen_size_x(s), screen_size_y(s), s->cx, s->cy, s->rupper, @@ -687,8 +651,7 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx) void input_handle_sequence_cuu(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -697,21 +660,16 @@ input_handle_sequence_cuu(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; + if (n == 0) + n = 1; - if (n == 0 || n > s->cy) { - log_debug3("cuu: out of range: %hu", n); - return; - } - - s->cy -= n; - input_write(ictx, TTY_CURSORUP, n); + screen_write_cursor_up(&ictx->ctx, n); } void input_handle_sequence_cud(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -720,20 +678,16 @@ input_handle_sequence_cud(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_y(s) - s->cy); + n = 1; - s->cy += n; - input_write(ictx, TTY_CURSORDOWN, n); + screen_write_cursor_down(&ictx->ctx, n); } void input_handle_sequence_cuf(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -742,20 +696,16 @@ input_handle_sequence_cuf(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_x(s) - s->cx); + n = 1; - s->cx += n; - input_write(ictx, TTY_CURSORRIGHT, n); + screen_write_cursor_right(&ictx->ctx, n); } void input_handle_sequence_cub(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -764,21 +714,16 @@ input_handle_sequence_cub(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; + if (n == 0) + n = 1; - if (n == 0 || n > s->cx) { - log_debug3("cub: out of range: %hu", n); - return; - } - - s->cx -= n; - input_write(ictx, TTY_CURSORLEFT, n); + screen_write_cursor_left(&ictx->ctx, n); } void input_handle_sequence_dch(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -787,20 +732,16 @@ input_handle_sequence_dch(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_x(s) - s->cx); + n = 1; - screen_display_delete_characters(s, s->cx, s->cy, n); - input_write(ictx, TTY_DELETECHARACTER, n); + screen_write_delete_characters(&ictx->ctx, n); } void input_handle_sequence_dl(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -809,23 +750,16 @@ input_handle_sequence_dl(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_y(s) - s->cy); + n = 1; - if (s->cy < s->rupper || s->cy > s->rlower) - screen_display_delete_lines(s, s->cy, n); - else - screen_display_delete_lines_region(s, s->cy, n); - input_write(ictx, TTY_DELETELINE, n); + screen_write_delete_lines(&ictx->ctx, n); } void input_handle_sequence_ich(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -834,20 +768,16 @@ input_handle_sequence_ich(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_x(s) - s->cx); + n = 1; - screen_display_insert_characters(s, s->cx, s->cy, n); - input_write(ictx, TTY_INSERTCHARACTER, n); + screen_write_insert_characters(&ictx->ctx, n); } void input_handle_sequence_il(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -856,23 +786,17 @@ input_handle_sequence_il(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_last_y(s) - s->cy); + n = 1; - if (s->cy < s->rupper || s->cy > s->rlower) - screen_display_insert_lines(s, s->cy, n); - else - screen_display_insert_lines_region(s, s->cy, n); - input_write(ictx, TTY_INSERTLINE, n); + screen_write_insert_lines(&ictx->ctx, n); } void input_handle_sequence_vpa(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + struct screen *s = ictx->ctx.s; + uint16_t n; if (ictx->private != '\0') return; @@ -881,20 +805,17 @@ input_handle_sequence_vpa(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_size_y(s)); + n = 1; - s->cy = n - 1; - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_move_cursor(&ictx->ctx, s->cx, n - 1); } void input_handle_sequence_hpa(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + struct screen *s = ictx->ctx.s; + uint16_t n; if (ictx->private != '\0') return; @@ -903,20 +824,16 @@ input_handle_sequence_hpa(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 1) != 0) return; - if (n == 0) - return; - input_limit(n, 1, screen_size_x(s)); + n = 1; - s->cx = n - 1; - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_move_cursor(&ictx->ctx, n - 1, s->cy); } void input_handle_sequence_cup(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n, m; + uint16_t n, m; if (ictx->private != '\0') return; @@ -927,21 +844,18 @@ input_handle_sequence_cup(struct input_ctx *ictx) return; if (input_get_argument(ictx, 1, &m, 1) != 0) return; + if (n == 0) + n = 1; + if (m == 0) + m = 1; - input_limit(n, 1, screen_size_y(s)); - input_limit(m, 1, screen_size_x(s)); - - s->cx = m - 1; - s->cy = n - 1; - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_move_cursor(&ictx->ctx, m - 1, n - 1); } void input_handle_sequence_ed(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; - u_int i; + uint16_t n; if (ictx->private != '\0') return; @@ -950,31 +864,15 @@ input_handle_sequence_ed(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 0) != 0) return; - if (n > 2) return; switch (n) { case 0: - screen_display_fill_cursor_eos( - s, SCREEN_DEFDATA, s->attr, s->colr); - - input_write(ictx, TTY_CLEARENDOFLINE); - for (i = s->cy + 1; i < screen_size_y(s); i++) { - input_write(ictx, TTY_CURSORMOVE, i, 0); - input_write(ictx, TTY_CLEARENDOFLINE); - } - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_fill_end_of_screen(&ictx->ctx); break; case 2: - screen_display_fill_lines( - s, 0, screen_size_y(s), SCREEN_DEFDATA, s->attr, s->colr); - - for (i = 0; i < screen_size_y(s); i++) { - input_write(ictx, TTY_CURSORMOVE, i, 0); - input_write(ictx, TTY_CLEARENDOFLINE); - } - input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx); + screen_write_fill_screen(&ictx->ctx); break; } } @@ -982,8 +880,7 @@ input_handle_sequence_ed(struct input_ctx *ictx) void input_handle_sequence_el(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ictx->private != '\0') return; @@ -992,25 +889,18 @@ input_handle_sequence_el(struct input_ctx *ictx) return; if (input_get_argument(ictx, 0, &n, 0) != 0) return; - if (n > 2) return; switch (n) { case 0: - screen_display_fill_cursor_eol( - s, SCREEN_DEFDATA, s->attr, s->colr); - input_write(ictx, TTY_CLEARENDOFLINE); + screen_write_fill_end_of_line(&ictx->ctx); break; case 1: - screen_display_fill_cursor_bol( - s, SCREEN_DEFDATA, s->attr, s->colr); - input_write(ictx, TTY_CLEARSTARTOFLINE); + screen_write_fill_start_of_line(&ictx->ctx); break; case 2: - screen_display_fill_line( - s, s->cy, SCREEN_DEFDATA, s->attr, s->colr); - input_write(ictx, TTY_CLEARLINE); + screen_write_fill_line(&ictx->ctx); break; } } @@ -1018,8 +908,7 @@ input_handle_sequence_el(struct input_ctx *ictx) void input_handle_sequence_sm(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; + uint16_t n; if (ARRAY_LENGTH(&ictx->args) > 1) return; @@ -1029,16 +918,13 @@ input_handle_sequence_sm(struct input_ctx *ictx) if (ictx->private == '?') { switch (n) { case 1: /* GATM */ - s->mode |= MODE_KCURSOR; - input_write(ictx, TTY_KCURSORON); + screen_write_set_mode(&ictx->ctx, MODE_KCURSOR); break; case 25: /* TCEM */ - s->mode |= MODE_CURSOR; - input_write(ictx, TTY_CURSORON); + screen_write_set_mode(&ictx->ctx, MODE_CURSOR); break; case 1000: - s->mode |= MODE_MOUSE; - input_write(ictx, TTY_MOUSEON); + screen_write_set_mode(&ictx->ctx, MODE_MOUSE); break; default: log_debug("unknown SM [%hhu]: %u", ictx->private, n); @@ -1047,8 +933,7 @@ input_handle_sequence_sm(struct input_ctx *ictx) } else { switch (n) { case 4: /* IRM */ - s->mode |= MODE_INSERT; - input_write(ictx, TTY_INSERTON); + screen_write_set_mode(&ictx->ctx, MODE_INSERT); break; case 34: /* Cursor high visibility not supported. */ @@ -1063,7 +948,6 @@ input_handle_sequence_sm(struct input_ctx *ictx) void input_handle_sequence_rm(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; uint16_t n; if (ARRAY_LENGTH(&ictx->args) > 1) @@ -1074,16 +958,13 @@ input_handle_sequence_rm(struct input_ctx *ictx) if (ictx->private == '?') { switch (n) { case 1: /* GATM */ - s->mode &= ~MODE_KCURSOR; - input_write(ictx, TTY_KCURSOROFF); + screen_write_clear_mode(&ictx->ctx, MODE_KCURSOR); break; case 25: /* TCEM */ - s->mode &= ~MODE_CURSOR; - input_write(ictx, TTY_CURSOROFF); + screen_write_clear_mode(&ictx->ctx, MODE_CURSOR); break; case 1000: - s->mode &= ~MODE_MOUSE; - input_write(ictx, TTY_MOUSEOFF); + screen_write_clear_mode(&ictx->ctx, MODE_MOUSE); break; default: log_debug("unknown RM [%hhu]: %u", ictx->private, n); @@ -1092,8 +973,7 @@ input_handle_sequence_rm(struct input_ctx *ictx) } else if (ictx->private == '\0') { switch (n) { case 4: /* IRM */ - s->mode &= ~MODE_INSERT; - input_write(ictx, TTY_INSERTOFF); + screen_write_clear_mode(&ictx->ctx, MODE_INSERT); break; case 34: /* Cursor high visibility not supported. */ @@ -1108,9 +988,9 @@ input_handle_sequence_rm(struct input_ctx *ictx) void input_handle_sequence_dsr(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n; - char reply[32]; + struct screen *s = ictx->ctx.s; + uint16_t n; + char reply[32]; if (ARRAY_LENGTH(&ictx->args) > 1) return; @@ -1133,8 +1013,8 @@ input_handle_sequence_dsr(struct input_ctx *ictx) void input_handle_sequence_decstbm(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - uint16_t n, m; + struct screen *s = ictx->ctx.s; + uint16_t n, m; if (ictx->private != '\0') return; @@ -1145,78 +1025,64 @@ input_handle_sequence_decstbm(struct input_ctx *ictx) return; if (input_get_argument(ictx, 1, &m, 0) != 0) return; - - /* Special case: both zero restores to entire screen. */ - /* XXX this will catch [0;0r and [;r etc too, is this right? */ - if (n == 0 && m == 0) { + if (n == 0) n = 1; + if (m == 0) m = screen_size_y(s); - } - - input_limit(n, 1, screen_size_y(s)); - input_limit(m, 1, screen_size_y(s)); - - if (n > m) { - log_debug3("decstbm: out of range: %hu,%hu", n, m); - return; - } - - /* Cursor moves to top-left. */ - s->cx = 0; - s->cy = n - 1; - s->rupper = n - 1; - s->rlower = m - 1; - input_write(ictx, TTY_SCROLLREGION, s->rupper, s->rlower); + screen_write_set_region(&ictx->ctx, n - 1, m - 1); } void input_handle_sequence_sgr(struct input_ctx *ictx) { - struct screen *s = &ictx->w->screen; - u_int i, n; - uint16_t m; + struct screen *s = ictx->ctx.s; + u_int i, n; + uint16_t m; + u_char attr, colr; n = ARRAY_LENGTH(&ictx->args); if (n == 0) { - s->attr = 0; - s->colr = SCREEN_DEFCOLR; + attr = 0; + colr = SCREEN_DEFCOLR; } else { + attr = s->attr; + colr = s->colr; for (i = 0; i < n; i++) { if (input_get_argument(ictx, i, &m, 0) != 0) return; switch (m) { case 0: case 10: - s->attr &= ATTR_CHARSET; - s->colr = SCREEN_DEFCOLR; + attr &= ATTR_CHARSET; + colr = SCREEN_DEFCOLR; break; case 1: - s->attr |= ATTR_BRIGHT; + attr |= ATTR_BRIGHT; break; case 2: - s->attr |= ATTR_DIM; + attr |= ATTR_DIM; break; case 3: - s->attr |= ATTR_ITALICS; + attr |= ATTR_ITALICS; break; case 4: - s->attr |= ATTR_UNDERSCORE; + attr |= ATTR_UNDERSCORE; break; case 5: - s->attr |= ATTR_BLINK; + attr |= ATTR_BLINK; break; case 7: - s->attr |= ATTR_REVERSE; + attr |= ATTR_REVERSE; break; case 8: - s->attr |= ATTR_HIDDEN; + attr |= ATTR_HIDDEN; break; case 23: - s->attr &= ~ATTR_ITALICS; + attr &= ~ATTR_ITALICS; break; case 24: - s->attr &= ~ATTR_UNDERSCORE; + attr &= ~ATTR_UNDERSCORE; break; case 30: case 31: @@ -1226,12 +1092,12 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 35: case 36: case 37: - s->colr &= 0x0f; - s->colr |= (m - 30) << 4; + colr &= 0x0f; + colr |= (m - 30) << 4; break; case 39: - s->colr &= 0x0f; - s->colr |= 0x80; + colr &= 0x0f; + colr |= 0x80; break; case 40: case 41: @@ -1241,15 +1107,15 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 45: case 46: case 47: - s->colr &= 0xf0; - s->colr |= m - 40; + colr &= 0xf0; + colr |= m - 40; break; case 49: - s->colr &= 0xf0; - s->colr |= 0x08; + colr &= 0xf0; + colr |= 0x08; break; } } } - input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr); + screen_write_set_attributes(&ictx->ctx, attr, colr); } diff --git a/key-bindings.c b/key-bindings.c index d2f51b25..8889d81a 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.22 2007-11-27 19:23:33 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.23 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -84,7 +84,7 @@ key_bindings_init(void) { 'S', &cmd_list_sessions_entry, NULL }, { 's', &cmd_list_sessions_entry, NULL }, { 'W', &cmd_list_windows_entry, NULL }, - { 'w', &cmd_list_windows_entry, NULL }, + { 'w', &cmd_list_windows_entry, NULL }, { '?', &cmd_list_keys_entry, NULL }, { '/', &cmd_list_keys_entry, NULL }, { 'C', &cmd_new_window_entry, NULL }, @@ -140,7 +140,7 @@ key_bindings_free(void) cmd_free(bd->cmd); xfree(bd); } - + ARRAY_FREE(&key_bindings); } @@ -168,6 +168,7 @@ key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...) if (w->mode == NULL) { w->mode = &window_more_mode; w->mode->init(w); + server_redraw_window(w); } else if (w->mode != &window_more_mode) return; @@ -202,7 +203,4 @@ key_bindings_dispatch(int key, struct client *c) ctx.flags = CMD_KEY; cmd_exec(bd->cmd, &ctx); - - if (c->session->curw->window->mode == &window_more_mode) - server_redraw_window(c->session->curw->window); } diff --git a/resize.c b/resize.c index c69ef08d..94a7621b 100644 --- a/resize.c +++ b/resize.c @@ -1,4 +1,4 @@ -/* $Id: resize.c,v 1.8 2007-12-02 23:00:22 nicm Exp $ */ +/* $Id: resize.c,v 1.9 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -33,7 +33,7 @@ * smallest client it is attached to, and resize it to that size. Then for * every window, find the smallest session it is attached to, resize it to that * size and clear and redraw every client with it as the current window. - * + * * This is quite inefficient - better/additional data structures are needed * to make it better. * @@ -50,7 +50,7 @@ recalculate_sizes(void) struct client *c; struct window *w; u_int i, j, ssx, ssy; - + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { s = ARRAY_ITEM(&sessions, i); if (s == NULL) @@ -105,17 +105,17 @@ recalculate_sizes(void) } } if (ssx == UINT_MAX || ssy == UINT_MAX) { - w->screen.mode |= MODE_HIDDEN; + w->flags |= WINDOW_HIDDEN; continue; } - w->screen.mode &= ~MODE_HIDDEN; + w->flags &= ~WINDOW_HIDDEN; - if (screen_size_x(&w->screen) == ssx && - screen_size_y(&w->screen) == ssy) + if (screen_size_x(&w->base) == ssx && + screen_size_y(&w->base) == ssy) continue; log_debug("window size %u,%u (was %u,%u)", ssx, ssy, - screen_size_x(&w->screen), screen_size_y(&w->screen)); + screen_size_x(&w->base), screen_size_y(&w->base)); server_clear_window(w); window_resize(w, ssx, ssy); diff --git a/screen-display.c b/screen-display.c index 1985570e..4124a61e 100644 --- a/screen-display.c +++ b/screen-display.c @@ -1,4 +1,4 @@ -/* $Id: screen-display.c,v 1.9 2007-11-26 22:22:18 nicm Exp $ */ +/* $Id: screen-display.c,v 1.10 2007-12-06 09:46:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -22,17 +22,20 @@ #include "tmux.h" -/* - * Screen display modification functions. These alter the displayed portion - * of the screen. - */ +/* Set a cell. */ +void +screen_display_set_cell( + struct screen *s, u_int px, u_int py, u_char data, u_char attr, u_char colr) +{ + screen_set_cell(s, screen_x(s, px), screen_y(s, py), data, attr, colr); +} /* Create a region of lines. */ void screen_display_make_lines(struct screen *s, u_int py, u_int ny) { if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) - fatalx("bad value"); + return; screen_make_lines(s, screen_y(s, py), ny); } @@ -41,7 +44,7 @@ void screen_display_free_lines(struct screen *s, u_int py, u_int ny) { if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) - fatalx("bad value"); + return; screen_free_lines(s, screen_y(s, py), ny); } @@ -50,116 +53,25 @@ void screen_display_move_lines(struct screen *s, u_int dy, u_int py, u_int ny) { if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) - fatalx("bad value"); + return; if (!screen_in_y(s, dy) || !screen_in_y(s, dy + ny - 1) || dy == py) - fatalx("bad value"); + return; screen_move_lines(s, screen_y(s, dy), screen_y(s, py), ny); } -/* Fill a set of lines. */ -void -screen_display_fill_lines( - struct screen *s, u_int py, u_int ny, u_char data, u_char attr, u_char colr) -{ - if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1)) - fatalx("bad value"); - screen_fill_lines(s, screen_y(s, py), ny, data, attr, colr); -} - -/* Fill a set of cellss. */ -void -screen_display_fill_cells(struct screen *s, - u_int px, u_int py, u_int nx, u_char data, u_char attr, u_char colr) -{ - if (nx == 0 || !screen_in_x(s, px) || !screen_in_y(s, py)) - fatalx("bad value"); - screen_fill_cells( - s, screen_x(s, px), screen_y(s, py), nx, data, attr, colr); -} - -/* Fill entire screen. */ -void -screen_display_fill_screen( - struct screen *s, u_char data, u_char attr, u_char colr) -{ - screen_display_fill_lines(s, 0, screen_size_y(s), data, attr, colr); -} - -/* Fill end of screen from cursor. */ -void -screen_display_fill_cursor_eos( - struct screen *s, u_char data, u_char attr, u_char colr) -{ - screen_display_fill_cursor_eol(s, data, attr, colr); - if (s->cy != screen_last_y(s)) { - screen_display_fill_lines( - s, s->cy, screen_size_y(s) - s->cy, data, attr, colr); - } -} - -/* Fill beginning of screen from cursor. */ +/* Fill a set of cells. */ void -screen_display_fill_cursor_bos( - struct screen *s, u_char data, u_char attr, u_char colr) +screen_display_fill_area(struct screen *s, u_int px, u_int py, + u_int nx, u_int ny, u_char data, u_char attr, u_char colr) { - screen_display_fill_lines(s, 0, s->cy, data, attr, colr); -} - -/* Fill a single line. */ -void -screen_display_fill_line( - struct screen *s, u_int py, u_char data, u_char attr, u_char colr) -{ - screen_display_fill_lines(s, py, 1, data, attr, colr); -} - -/* Fill cursor to beginning of line. */ -void -screen_display_fill_cursor_bol( - struct screen *s, u_char data, u_char attr, u_char colr) -{ - screen_display_fill_cells(s, 0, s->cy, s->cx, data, attr, colr); -} - -/* Fill cursor to end of line. */ -void -screen_display_fill_cursor_eol( - struct screen *s, u_char data, u_char attr, u_char colr) -{ - screen_display_fill_cells( - s, s->cx, s->cy, screen_size_x(s) - s->cx, data, attr, colr); -} - -/* Set character at cursor. */ -void -screen_display_cursor_set(struct screen *s, u_char ch) -{ - u_int px, py; - - px = screen_x(s, s->cx); - py = screen_y(s, s->cy); - - screen_set_cell(s, px, py, ch, s->attr, s->colr); -} - -/* Move cursor up and scroll if necessary. */ -void -screen_display_cursor_up(struct screen *s) -{ - if (s->cy == s->rupper) - screen_display_scroll_region_down(s); - else if (s->cy > 0) - s->cy--; -} - -/* Move cursor down and scroll if necessary. */ -void -screen_display_cursor_down(struct screen *s) -{ - if (s->cy == s->rlower) - screen_display_scroll_region_up(s); - else if (s->cy < screen_last_y(s)) - s->cy++; + if (nx == 0 || ny == 0) + return; + if (!screen_in_x(s, px) || !screen_in_y(s, py)) + return; + if (!screen_in_x(s, px + nx - 1) || !screen_in_y(s, py - ny - 1)) + return; + screen_fill_area( + s, screen_x(s, px), screen_y(s, py), nx, ny, data, attr, colr); } /* Scroll region up. */ @@ -167,13 +79,13 @@ void screen_display_scroll_region_up(struct screen *s) { u_int ny, sy; - + /* * If the region is the entire screen, this is easy-peasy. Allocate * a new line and adjust the history size. * XXX should this be done somewhere else? */ - if (s->rupper == 0 && s->rlower == screen_last_y(s)) { + if (s->rupper == 0 && s->rlower == screen_last_y(s)) { if (s->hsize == s->hlimit) { /* If the limit is hit, free 10% and shift up. */ ny = s->hlimit / 10; @@ -197,7 +109,7 @@ screen_display_scroll_region_up(struct screen *s) return; } - /* + /* * Scroll scrolling region up: * - delete rupper * - move rupper + 1 to rlower to rupper @@ -213,7 +125,7 @@ screen_display_scroll_region_up(struct screen *s) screen_display_free_lines(s, s->rupper, 1); if (s->rupper != s->rlower) { - screen_display_move_lines(s, + screen_display_move_lines(s, s->rupper, s->rupper + 1, s->rlower - s->rupper); } @@ -224,7 +136,7 @@ screen_display_scroll_region_up(struct screen *s) void screen_display_scroll_region_down(struct screen *s) { - /* + /* * Scroll scrolling region down: * - delete rlower * - move rupper to rlower - 1 to rupper + 1 @@ -252,14 +164,14 @@ void screen_display_insert_lines(struct screen *s, u_int py, u_int ny) { if (!screen_in_y(s, py)) - fatalx("bad value"); + return; if (ny == 0) - fatalx("bad value"); + return; if (py + ny > screen_last_y(s)) ny = screen_size_y(s) - py; if (ny == 0) - return; + return; /* * Insert range of ny lines at py: @@ -289,9 +201,9 @@ void screen_display_insert_lines_region(struct screen *s, u_int py, u_int ny) { if (!screen_in_region(s, py)) - fatalx("bad value"); + return; if (ny == 0) - fatalx("bad value"); + return; if (py + ny > s->rlower) ny = (s->rlower + 1) - py; @@ -326,9 +238,9 @@ void screen_display_delete_lines(struct screen *s, u_int py, u_int ny) { if (!screen_in_y(s, py)) - fatalx("bad value"); + return; if (ny == 0) - fatalx("bad value"); + return; if (py + ny > screen_last_y(s)) ny = screen_size_y(s) - py; @@ -363,9 +275,9 @@ void screen_display_delete_lines_region(struct screen *s, u_int py, u_int ny) { if (!screen_in_region(s, py)) - fatalx("bad value"); + return; if (ny == 0) - fatalx("bad value"); + return; if (py + ny > s->rlower) ny = (s->rlower + 1) - py; @@ -402,7 +314,7 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx) u_int mx; if (!screen_in_x(s, px) || !screen_in_y(s, py)) - fatalx("bad value"); + return; if (px + nx > screen_last_x(s)) nx = screen_last_x(s) - px; @@ -439,7 +351,7 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx) u_int mx; if (!screen_in_x(s, px) || !screen_in_y(s, py)) - fatalx("bad value"); + return; if (px + nx > screen_last_x(s)) nx = screen_last_x(s) - px; @@ -468,3 +380,28 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx) memset(&s->grid_attr[py][screen_size_x(s) - nx], SCREEN_DEFATTR, nx); memset(&s->grid_colr[py][screen_size_x(s) - nx], SCREEN_DEFCOLR, nx); } + +/* Fill cells from another screen, with an offset. */ +void +screen_display_copy_area(struct screen *dst, struct screen *src, + u_int px, u_int py, u_int nx, u_int ny, u_int ox, u_int oy) +{ + u_int i, j; + u_char data, attr, colr; + + if (nx == 0 || ny == 0) + return; + if (!screen_in_x(dst, px) || !screen_in_y(dst, py)) + return; + if (!screen_in_x(dst, px + nx - 1) || !screen_in_y(dst, py + ny - 1)) + return; + + for (i = py; i < py + ny; i++) { + for (j = px; j < px + nx; j++) {