diff --git a/CHANGES b/CHANGES index 02417ef6..263fd637 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,12 @@ 11 February 2009 +* FreeBSD's console wraps lines at $COLUMNS - 1 rather than $COLUMNS (the + cursor can never be beyond $COLUMNS - 1) and does not appear to support + changing this behaviour, or any of the obvious possibilities (turning off + right margin wrapping, insert mode). This is irritating, most notably because + it impossible to write to the very bottom-right of the screen without + scrolling. To work around this, if built on FreeBSD and run with a "cons" + $TERM, the bottom-right cell on the screen is omitted. * Emulate scroll regions (slowly) to support the few terminals which don't have it (some of which don't really have any excuse). @@ -1095,7 +1102,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.251 2009-02-11 19:06:56 nicm Exp $ +$Id: CHANGES,v 1.252 2009-02-11 23:16:41 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/screen-redraw.c b/screen-redraw.c index 68b4223c..2043ad19 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $Id: screen-redraw.c,v 1.23 2009-02-11 17:50:33 nicm Exp $ */ +/* $Id: screen-redraw.c,v 1.24 2009-02-11 23:16:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -134,6 +134,11 @@ screen_redraw_line(struct client *c, struct screen *s, u_int oy, u_int py) sx = screen_size_x(s); if (sx > c->tty.sx) sx = c->tty.sx; + if (c->tty.term->flags & TERM_EARLYWRAP) { + /* Work around weirdness by omitting bottom right character. */ + if (oy + py == c->tty.sy - 1 && sx == c->tty.sx) + sx--; + } for (i = 0; i < sx; i++) { gc = grid_view_peek_cell(s->grid, i, py); tty_cursor(&c->tty, i, py, oy); diff --git a/tmux.h b/tmux.h index 1fe8986d..769d99c8 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.269 2009-02-11 18:44:05 nicm Exp $ */ +/* $Id: tmux.h,v 1.270 2009-02-11 23:16:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -702,6 +702,7 @@ struct tty_term { #define TERM_HASDEFAULTS 0x1 #define TERM_256COLOURS 0x2 +#define TERM_EARLYWRAP 0x4 int flags; SLIST_ENTRY(tty_term) entry; diff --git a/tty-term.c b/tty-term.c index 4e3069b8..f273e03e 100644 --- a/tty-term.c +++ b/tty-term.c @@ -1,4 +1,4 @@ -/* $Id: tty-term.c,v 1.12 2009-02-11 19:06:58 nicm Exp $ */ +/* $Id: tty-term.c,v 1.13 2009-02-11 23:16:44 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -148,6 +148,26 @@ tty_term_quirks(struct tty_term *term) term->codes[TTYC_ICH1].value.string = xstrdup("\033[@"); } } + +#ifdef __FreeBSD__ + if (strncmp(term->name, "cons", 4) == 0) { + /* + * FreeBSD's console wraps lines at $COLUMNS - 1 rather than + * $COLUMNS (the cursor can never be beyond $COLUMNS - 1) and + * does not appear to support changing this behaviour, or any + * of the obvious possibilities (turning off right margin + * wrapping, insert mode). + * + * This is irritating, most notably because it is impossible to + * write to the very bottom-right of the screen without + * scrolling. + * + * Flag the terminal here and apply some workarounds in other + * places to do the best possible. + */ + term->flags |= TERM_EARLYWRAP; + } +#endif } struct tty_term * diff --git a/tty.c b/tty.c index 0336ddc8..c3dcf0f2 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.70 2009-02-11 19:06:58 nicm Exp $ */ +/* $Id: tty.c,v 1.71 2009-02-11 23:16:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -309,12 +309,23 @@ tty_puts(struct tty *tty, const char *s) void tty_putc(struct tty *tty, char ch) { + u_int sx; + if (tty->cell.attr & GRID_ATTR_CHARSET) ch = tty_get_acs(tty, ch); buffer_write8(tty->out, ch); - if (ch >= 0x20) - tty->cx++; /* This is right most of the time. */ + if (ch >= 0x20) { + sx = tty->sx; + if (tty->term->flags & TERM_EARLYWRAP) + sx--; + + if (tty->cx == sx) { + tty->cx = 0; + tty->cy++; + } else + tty->cx++; + } if (tty->log_fd != -1) write(tty->log_fd, &ch, 1);