From d5eaf3a9f6ab9299f76d65e77f11e08f11d9e150 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 11 Feb 2009 19:06:58 +0000 Subject: [PATCH] Emulate CSR with existing screen data on old/stupid terminals which don't support it. --- CHANGES | 7 ++++- NOTES | 10 +------ tty-term.c | 6 +--- tty.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index d4a7d770..02417ef6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +11 February 2009 + +* Emulate scroll regions (slowly) to support the few terminals which don't have + it (some of which don't really have any excuse). + 10 February 2009 * No longer redraw the status line every status-interval unless it has actually @@ -1090,7 +1095,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.250 2009-02-10 00:18:06 nicm Exp $ +$Id: CHANGES,v 1.251 2009-02-11 19:06:56 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/NOTES b/NOTES index 13d25545..1dbdd1d3 100644 --- a/NOTES +++ b/NOTES @@ -72,14 +72,6 @@ A Vim syntax file is available in the examples directory. To install it: - Switch on syntax highlighting in your vimrc file by adding "syntax enable" to it. -There are the following known issues: - -- cons25 on the FreeBSD console doesn't support scroll region (cs) (or lies - about support, I'm not totally clear which). This is a pity but emulating cs - is nontrivial and as most modern vt220-based software terminals support it, - currently there are better things to work one. Diffs or ideas how to cleanly - emulate cs are welcome. - For debugging, running tmux with -v or -vv will generate server and client log files in the current directory. @@ -99,4 +91,4 @@ welcome. Please email: -- Nicholas Marriott -$Id: NOTES,v 1.42 2009-01-18 17:20:52 nicm Exp $ +$Id: NOTES,v 1.43 2009-02-11 19:06:58 nicm Exp $ diff --git a/tty-term.c b/tty-term.c index 14c6b6bc..4e3069b8 100644 --- a/tty-term.c +++ b/tty-term.c @@ -1,4 +1,4 @@ -/* $Id: tty-term.c,v 1.11 2009-02-11 18:44:08 nicm Exp $ */ +/* $Id: tty-term.c,v 1.12 2009-02-11 19:06:58 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -240,10 +240,6 @@ tty_term_find(char *name, int fd, char **cause) xasprintf(cause, "terminal does not support ri"); goto error; } - if (!tty_term_has(term, TTYC_CSR)) { - xasprintf(cause, "terminal does not support csr"); - goto error; - } if (!tty_term_has(term, TTYC_CUP)) { xasprintf(cause, "terminal does not support cup"); goto error; diff --git a/tty.c b/tty.c index ee76e325..0336ddc8 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.69 2009-02-11 18:44:08 nicm Exp $ */ +/* $Id: tty.c,v 1.70 2009-02-11 19:06:58 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -32,6 +32,7 @@ u_char tty_get_acs(struct tty *, u_char); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); +void tty_draw_line(struct tty *, struct window_pane *, u_int); void tty_raw(struct tty *, const char *); @@ -368,6 +369,27 @@ tty_emulate_repeat( } } +void +tty_draw_line(struct tty *tty, struct window_pane *wp, u_int py) +{ + struct screen *s = wp->screen; + const struct grid_cell *gc; + struct grid_cell tc; + u_int i; + + for (i = 0; i < tty->sx; i++) { + gc = grid_view_peek_cell(s->grid, i, py); + + tty_cursor(tty, i, py, wp->yoff); + if (screen_check_selection(s, i, py)) { + memcpy(&tc, &s->sel.cell, sizeof tc); + tc.data = gc->data; + tty_cell(tty, &tc); + } else + tty_cell(tty, gc); + } +} + void tty_write(struct tty *tty, struct window_pane *wp, enum tty_cmd cmd, ...) { @@ -428,7 +450,22 @@ void tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap) { struct screen *s = wp->screen; - u_int ua; + u_int ua, i; + + if (!tty_term_has(tty->term, TTYC_CSR)) { + /* + * Scroll region unsupported. Redraw using data from screen + * (already updated). + */ + if (s->old_cy < s->old_rupper || s->old_cy > s->old_rlower) { + for (i = s->old_cy; i < screen_size_y(s); i++) + tty_draw_line(tty, wp, i); + } else { + for (i = s->old_rupper; i <= s->old_rlower; i++) + tty_draw_line(tty, wp, i); + } + return; + } ua = va_arg(ap, u_int); @@ -444,7 +481,22 @@ void tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap) { struct screen *s = wp->screen; - u_int ua; + u_int ua, i; + + if (!tty_term_has(tty->term, TTYC_CSR)) { + /* + * Scroll region unsupported. Redraw using data from screen + * (already updated). + */ + if (s->old_cy < s->old_rupper || s->old_cy > s->old_rlower) { + for (i = s->old_cy; i < screen_size_y(s); i++) + tty_draw_line(tty, wp, i); + } else { + for (i = s->old_rupper; i <= s->old_rlower; i++) + tty_draw_line(tty, wp, i); + } + return; + } ua = va_arg(ap, u_int); @@ -514,6 +566,19 @@ void tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap) { struct screen *s = wp->screen; + u_int i; + + if (!tty_term_has(tty->term, TTYC_CSR)) { + /* + * Scroll region unsupported. If would have scrolled, redraw + * scroll region from already updated window screen. + */ + if (s->old_cy == s->old_rupper) { + for (i = s->old_rupper; i <= s->old_rlower; i++) + tty_draw_line(tty, wp, i); + return; + } + } tty_reset(tty); @@ -527,6 +592,19 @@ void tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap) { struct screen *s = wp->screen; + u_int i; + + if (!tty_term_has(tty->term, TTYC_CSR)) { + /* + * Scroll region unsupported. If would have scrolled, redraw + * scroll region from already updated window screen. + */ + if (s->old_cy == s->old_rlower) { + for (i = s->old_rupper; i <= s->old_rlower; i++) + tty_draw_line(tty, wp, i); + return; + } + } tty_reset(tty); @@ -694,11 +772,13 @@ tty_reset(struct tty *tty) void tty_region(struct tty *tty, u_int rupper, u_int rlower, u_int oy) { + if (!tty_term_has(tty->term, TTYC_CSR)) + return; if (tty->rlower != oy + rlower || tty->rupper != oy + rupper) { tty->rlower = oy + rlower; tty->rupper = oy + rupper; tty->cx = 0; - tty->cy = 0; + tty->cy = 0; tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); } }