From e21587864a050bd8dcfe4621237c89bbeb6b09f5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 24 Oct 2007 15:01:25 +0000 Subject: [PATCH] Save restore attr. --- CHANGES | 9 +++++++- TODO | 14 ++++++++++++- input.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++--------- tmux.h | 14 +++++++++---- 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index e570374d..754ed5f5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +24 October 2007 + +* (nicm) Support for \e7, \e8 save/restore cursor and attribute sequences. + Currently don't save mode (probably should). Also change some cases where + out-of-bound values are ignored to limit them to within range (there are + others than need to be checked too). + 23 October 2007 * (nicm) Lift limit on session name passed with -s. @@ -151,5 +158,5 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.48 2007-10-23 10:48:22 nicm Exp $ +$Id: CHANGES,v 1.49 2007-10-24 15:01:23 nicm Exp $ diff --git a/TODO b/TODO index fd21a1b7..32229701 100644 --- a/TODO +++ b/TODO @@ -44,15 +44,27 @@ - status-fg/status-bg should be to set attributes: bold, etc - show-options command - fix resize(1) +- detach client and other client commands. note that there can only be a + "current client" on key presses - these should act like detach-session - + -a will do all clients, otherwise do nothing unless key in which case do + current client +- check handling of out-of-bound values in input.c, most should be limited + rather than ignored +- save/restore (DECSC/DECRC) are ugly. maybe a struct screen_attr and memcpy -- For 0.1 -------------------------------------------------------------------- - man page - commands: rename sessions swap windows + same as link but swap windows if tgt exists else error link/copy windows + tmux -s link-window -i + link src win to tgt win (at tgt idx if given and + empty else new) unlink window (error if window only linked to one session) - kill session (no not bind by default) + tmux -s unlink-window -i + kill session (not bound by default) - check for some reqd terminfo caps on startup -- For 0.2 -------------------------------------------------------------------- diff --git a/input.c b/input.c index 2442cc36..ecda9035 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.25 2007-10-19 23:25:33 nicm Exp $ */ +/* $Id: input.c,v 1.26 2007-10-24 15:01:25 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -430,6 +430,31 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx) case '>': /* DECKPNM*/ input_store_zero(ictx->b, CODE_KKEYPADOFF); break; + case '7': /* DECSC */ + ictx->s->saved_cx = ictx->s->cx; + ictx->s->saved_cy = ictx->s->cy; + ictx->s->saved_ry_upper = ictx->s->ry_upper; + ictx->s->saved_ry_lower = ictx->s->ry_lower; + ictx->s->saved_attr = ictx->s->attr; + ictx->s->saved_colr = ictx->s->colr; + ictx->s->mode |= MODE_SAVED; + break; + case '8': /* DECRC */ + if (!(ictx->s->mode & MODE_SAVED)) + break; + ictx->s->cx = ictx->s->saved_cx; + ictx->s->cy = ictx->s->saved_cy; + ictx->s->ry_upper = ictx->s->saved_ry_upper; + ictx->s->ry_lower = ictx->s->saved_ry_lower; + ictx->s->attr = ictx->s->saved_attr; + ictx->s->colr = ictx->s->saved_colr; + input_store_two( + ictx->b, CODE_ATTRIBUTES, ictx->s->attr, ictx->s->colr); + input_store_two(ictx->b, CODE_SCROLLREGION, + ictx->s->ry_upper + 1, ictx->s->ry_lower + 1); + input_store_two( + ictx->b, CODE_CURSORMOVE, ictx->s->cy + 1, ictx->s->cx + 1); + break; default: log_debug("unknown p2: %hhu", ch); break; @@ -733,10 +758,14 @@ input_handle_sequence_cup(struct input_ctx *ictx) if (input_get_argument(ictx, 1, &m, 1) != 0) return; - if (n == 0 || n > ictx->s->sy || m == 0 || m > ictx->s->sx) { - log_debug3("cup: out of range: %hu", n); - return; - } + if (n == 0) + n = 1; + if (n > ictx->s->sy) + n = ictx->s->sy; + if (m == 0) + m = 1; + if (m > ictx->s->sx) + m = ictx->s->sx; ictx->s->cx = m - 1; ictx->s->cy = n - 1; @@ -910,20 +939,36 @@ input_handle_sequence_decstbm(struct input_ctx *ictx) if (ARRAY_LENGTH(&ictx->args) > 2) return; - if (input_get_argument(ictx, 0, &n, 1) != 0) + if (input_get_argument(ictx, 0, &n, 0) != 0) return; - if (input_get_argument(ictx, 1, &m, 1) != 0) + if (input_get_argument(ictx, 1, &m, 0) != 0) return; - if (n == 0 || n > ictx->s->sy || m == 0 || m > ictx->s->sy) { - log_debug3("decstbm: out of range: %hu,%hu", n, m); - 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) { + n = 1; + m = ictx->s->sy; } + + if (n == 0) + n = 1; + if (n > ictx->s->sy) + n = ictx->s->sy; + if (m == 0) + m = 1; + if (m > ictx->s->sx) + m = ictx->s->sx; + if (n > m) { log_debug3("decstbm: out of range: %hu,%hu", n, m); return; } + /* Cursor moves to top-left. */ + ictx->s->cx = 0; + ictx->s->cy = n - 1; + ictx->s->ry_upper = n - 1; ictx->s->ry_lower = m - 1; input_store_two(ictx->b, CODE_SCROLLREGION, n, m); diff --git a/tmux.h b/tmux.h index bab0e934..c4ad4dec 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.66 2007-10-23 11:25:32 nicm Exp $ */ +/* $Id: tmux.h,v 1.67 2007-10-24 15:01:25 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -319,6 +319,7 @@ struct msg_resize_data { #define MODE_INSERT 0x2 #define MODE_KCURSOR 0x4 #define MODE_KKEYPAD 0x8 +#define MODE_SAVED 0x10 /* * Virtual screen. This is stored as three blocks of 8-bit values, one for @@ -334,18 +335,23 @@ struct screen { u_char **grid_attr; u_char **grid_colr; - u_int sx; /* size x */ + u_int sx; /* size x */ u_int sy; /* size y */ u_int cx; /* cursor x */ u_int cy; /* cursor y */ - u_int ry_upper; /* scroll region top */ u_int ry_lower; /* scroll region bottom */ - u_char attr; u_char colr; /* fg:bg */ + u_int saved_cx; + u_int saved_cy; + u_int saved_ry_upper; + u_int saved_ry_lower; + u_int saved_attr; + u_int saved_colr; + int mode; };