From 514fe11727c1b2744fff28c525fb4f48ca944860 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 11 Feb 2009 17:04:39 +0000 Subject: [PATCH] We are going to need the updated screen data for emulating the scroll region, which may involve changing the cursor position; however, the old (before redraw) cursor position is necessary for writing to the tty. So, save it before doing the redraw then update the internal screen then update the tty. Not sure I like this solution but it does the job for now. --- screen-redraw.c | 10 +++--- screen-write.c | 84 ++++++++++++++++++++++++++++++++----------- tmux.h | 13 +++++-- tty.c | 96 ++++++++++++++++++++++++------------------------- 4 files changed, 124 insertions(+), 79 deletions(-) diff --git a/screen-redraw.c b/screen-redraw.c index fc3d3eb9..917f7175 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $Id: screen-redraw.c,v 1.21 2009-02-11 06:50:15 nicm Exp $ */ +/* $Id: screen-redraw.c,v 1.22 2009-02-11 17:04:38 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -135,15 +135,13 @@ screen_redraw_line(struct client *c, struct screen *s, u_int oy, u_int py) if (sx > c->sx) sx = c->sx; for (i = 0; i < sx; i++) { - s->cx = i; - s->cy = py; - gc = grid_view_peek_cell(s->grid, i, py); + tty_cursor(&c->tty, i, py, oy); if (screen_check_selection(s, i, py)) { memcpy(&tc, &s->sel.cell, sizeof tc); tc.data = gc->data; - tty_cell(&c->tty, s, oy, &tc); + tty_cell(&c->tty, &tc); } else - tty_cell(&c->tty, s, oy, gc); + tty_cell(&c->tty, gc); } } diff --git a/screen-write.c b/screen-write.c index 490b0927..4553b2a0 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $Id: screen-write.c,v 1.32 2009-02-11 06:31:09 nicm Exp $ */ +/* $Id: screen-write.c,v 1.33 2009-02-11 17:04:39 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -22,6 +22,8 @@ #include "tmux.h" +void screen_write_save(struct screen_write_ctx *); + /* Initialise writing with a window. */ void screen_write_start( @@ -95,6 +97,19 @@ screen_write_copy(struct screen_write_ctx *ctx, } } +/* Save cursor and region positions. */ +void +screen_write_save(struct screen_write_ctx *ctx) +{ + struct screen *s = ctx->s; + + s->old_cx = s->cx; + s->old_cy = s->cy; + + s->old_rlower = s->rlower; + s->old_rupper = s->rupper; +} + /* Cursor up by ny. */ void screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny) @@ -177,10 +192,12 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx) if (nx == 0) return; - tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, nx); + screen_write_save(ctx); if (s->cx <= screen_size_x(s) - 1) grid_view_insert_cells(s->grid, s->cx, s->cy, nx); + + tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, nx); } /* Delete nx characters. */ @@ -197,10 +214,12 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx) if (nx == 0) return; - tty_write_cmd(ctx->wp, TTY_DELETECHARACTER, nx); + screen_write_save(ctx); if (s->cx <= screen_size_x(s) - 1) grid_view_delete_cells(s->grid, s->cx, s->cy, nx); + + tty_write_cmd(ctx->wp, TTY_DELETECHARACTER, nx); } /* Insert ny lines. */ @@ -217,7 +236,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) if (ny == 0) return; - tty_write_cmd(ctx->wp, TTY_INSERTLINE, ny); + screen_write_save(ctx); if (s->cy < s->rupper || s->cy > s->rlower) grid_view_insert_lines(s->grid, s->cy, ny); @@ -225,6 +244,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) grid_view_insert_lines_region( s->grid, s->rupper, s->rlower, s->cy, ny); } + + tty_write_cmd(ctx->wp, TTY_INSERTLINE, ny); } /* Delete ny lines. */ @@ -241,7 +262,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) if (ny == 0) return; - tty_write_cmd(ctx->wp, TTY_DELETELINE, ny); + screen_write_save(ctx); if (s->cy < s->rupper || s->cy > s->rlower) grid_view_delete_lines(s->grid, s->cy, ny); @@ -249,6 +270,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) grid_view_delete_lines_region( s->grid, s->rupper, s->rlower, s->cy, ny); } + + tty_write_cmd(ctx->wp, TTY_DELETELINE, ny); } /* Clear line at cursor. */ @@ -257,9 +280,11 @@ screen_write_clearline(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - tty_write_cmd(ctx->wp, TTY_CLEARLINE); + screen_write_save(ctx); grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1); + + tty_write_cmd(ctx->wp, TTY_CLEARLINE); } /* Clear to end of line from cursor. */ @@ -269,12 +294,14 @@ screen_write_clearendofline(struct screen_write_ctx *ctx) struct screen *s = ctx->s; u_int sx; - sx = screen_size_x(s); + screen_write_save(ctx); - tty_write_cmd(ctx->wp, TTY_CLEARENDOFLINE); + sx = screen_size_x(s); if (s->cx <= sx - 1) grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1); + + tty_write_cmd(ctx->wp, TTY_CLEARENDOFLINE); } /* Clear to start of line from cursor. */ @@ -284,14 +311,16 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx) struct screen *s = ctx->s; u_int sx; - sx = screen_size_x(s); + screen_write_save(ctx); - tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFLINE); + sx = screen_size_x(s); if (s->cx > sx - 1) grid_view_clear(s->grid, 0, s->cy, sx, 1); else grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1); + + tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFLINE); } /* Move cursor to px,py. */ @@ -327,12 +356,14 @@ screen_write_reverseindex(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - tty_write_cmd(ctx->wp, TTY_REVERSEINDEX); + screen_write_save(ctx); if (s->cy == s->rupper) grid_view_scroll_region_down(s->grid, s->rupper, s->rlower); else if (s->cy > 0) s->cy--; + + tty_write_cmd(ctx->wp, TTY_REVERSEINDEX); } /* Set scroll region. */ @@ -387,12 +418,14 @@ screen_write_linefeed(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - tty_write_cmd(ctx->wp, TTY_LINEFEED); + screen_write_save(ctx); if (s->cy == s->rlower) grid_view_scroll_region_up(s->grid, s->rupper, s->rlower); else if (s->cy < screen_size_y(s) - 1) s->cy++; + + tty_write_cmd(ctx->wp, TTY_LINEFEED); } /* Carriage return (cursor to start of line). */ @@ -435,14 +468,16 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx) struct screen *s = ctx->s; u_int sx, sy; + screen_write_save(ctx); + sx = screen_size_x(s); sy = screen_size_y(s); - tty_write_cmd(ctx->wp, TTY_CLEARENDOFSCREEN); - if (s->cx <= sx - 1) grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1); grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1)); + + tty_write_cmd(ctx->wp, TTY_CLEARENDOFSCREEN); } /* Clear to start of screen. */ @@ -452,9 +487,9 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx) struct screen *s = ctx->s; u_int sx; - sx = screen_size_x(s); + screen_write_save(ctx); - tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN); + sx = screen_size_x(s); if (s->cy > 0) grid_view_clear(s->grid, 0, 0, sx, s->cy - 1); @@ -462,6 +497,8 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx) grid_view_clear(s->grid, 0, s->cy, sx, 1); else grid_view_clear(s->grid, 0, s->cy, s->cx, 1); + + tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN); } /* Clear entire screen. */ @@ -470,9 +507,11 @@ screen_write_clearscreen(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - tty_write_cmd(ctx->wp, TTY_CLEARSCREEN); + screen_write_save(ctx); grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s)); + + tty_write_cmd(ctx->wp, TTY_CLEARSCREEN); } /* Write cell data. */ @@ -572,15 +611,18 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) ic->flags |= GRID_FLAG_PADDING; } - /* Write the actual cell. */ + /* Set the cell. */ grid_view_set_cell(gd, s->cx, s->cy, gc); + + /* Move the cursor. */ + screen_write_save(ctx); + s->cx += width; + + /* Draw to the screen if necessary. */ if (screen_check_selection(s, s->cx, s->cy)) { memcpy(&tc, &s->sel.cell, sizeof tc); tc.data = gc->data; tty_write_cmd(ctx->wp, TTY_CELL, &tc); } else tty_write_cmd(ctx->wp, TTY_CELL, gc); - - /* Move the cursor. */ - s->cx += width; } diff --git a/tmux.h b/tmux.h index 19980417..6a5a259c 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.266 2009-02-11 07:02:34 nicm Exp $ */ +/* $Id: tmux.h,v 1.267 2009-02-11 17:04:39 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -496,9 +496,15 @@ struct screen { u_int cx; /* cursor x */ u_int cy; /* cursor y */ + u_int old_cx; + u_int old_cy; + u_int rupper; /* scroll region top */ u_int rlower; /* scroll region bottom */ + u_int old_rupper; + u_int old_rlower; + int mode; struct screen_sel sel; @@ -1011,9 +1017,10 @@ void options_set_number(struct options *, const char *, long long); long long options_get_number(struct options *, const char *); /* tty.c */ +void tty_reset(struct tty *); +void tty_region(struct tty *, u_int, u_int, u_int); void tty_cursor(struct tty *, u_int, u_int, u_int); -void tty_cell(struct tty *, - struct screen *, u_int, const struct grid_cell *); +void tty_cell(struct tty *, const struct grid_cell *); void tty_putcode(struct tty *, enum tty_code_code); void tty_putcode1(struct tty *, enum tty_code_code, int); void tty_putcode2(struct tty *, enum tty_code_code, int, int); diff --git a/tty.c b/tty.c index 70ab6ff9..959a8d79 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.67 2009-02-11 07:02:34 nicm Exp $ */ +/* $Id: tty.c,v 1.68 2009-02-11 17:04:39 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -35,8 +35,6 @@ void tty_emulate_repeat( void tty_raw(struct tty *, const char *); -void tty_reset(struct tty *); -void tty_region(struct tty *, struct screen *, u_int); void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); @@ -399,7 +397,7 @@ tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap) ua = va_arg(ap, u_int); tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); if (tty_term_has(tty->term, TTYC_ICH) || tty_term_has(tty->term, TTYC_ICH1)) @@ -409,7 +407,7 @@ tty_cmd_insertcharacter(struct tty *tty, struct window_pane *wp, va_list ap) while (ua-- > 0) tty_putc(tty, ' '); tty_putcode(tty, TTYC_RMIR); - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); } } @@ -422,7 +420,7 @@ tty_cmd_deletecharacter(struct tty *tty, struct window_pane *wp, va_list ap) ua = va_arg(ap, u_int); tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua); } @@ -436,8 +434,8 @@ tty_cmd_insertline(struct tty *tty, struct window_pane *wp, va_list ap) ua = va_arg(ap, u_int); tty_reset(tty); - tty_region(tty, s, wp->yoff); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua); } @@ -451,8 +449,8 @@ tty_cmd_deleteline(struct tty *tty, struct window_pane *wp, va_list ap) ua = va_arg(ap, u_int); tty_reset(tty); - tty_region(tty, s, wp->yoff); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua); } @@ -464,17 +462,17 @@ tty_cmd_clearline(struct tty *tty, struct window_pane *wp, unused va_list ap) u_int i; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); if (tty_term_has(tty->term, TTYC_EL)) { - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0); tty_putcode(tty, TTYC_EL); - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); } else { - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); } } @@ -486,15 +484,15 @@ tty_cmd_clearendofline( u_int i; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); if (tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else { - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); - for (i = s->cx; i < screen_size_x(s); i++) + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); + for (i = s->old_cx; i < screen_size_x(s); i++) tty_putc(tty, ' '); - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); } } @@ -506,15 +504,15 @@ tty_cmd_clearstartofline( u_int i; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); if (tty_term_has(tty->term, TTYC_EL1)) tty_putcode(tty, TTYC_EL1); else { - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, 0); - for (i = 0; i < s->cx + 1; i++) + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, 0); + for (i = 0; i < s->old_cx + 1; i++) tty_putc(tty, ' '); - tty_putcode2(tty, TTYC_CUP, wp->yoff + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, wp->yoff + s->old_cy, s->old_cx); } } @@ -524,8 +522,8 @@ tty_cmd_reverseindex(struct tty *tty, struct window_pane *wp, unused va_list ap) struct screen *s = wp->screen; tty_reset(tty); - tty_region(tty, s, wp->yoff); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); tty_putcode(tty, TTYC_RI); } @@ -536,8 +534,8 @@ tty_cmd_linefeed(struct tty *tty, struct window_pane *wp, unused va_list ap) struct screen *s = wp->screen; tty_reset(tty); - tty_region(tty, s, wp->yoff); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_region(tty, s->old_rupper, s->old_rlower, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); tty_putc(tty, '\n'); tty->cy++; @@ -553,23 +551,23 @@ tty_cmd_clearendofscreen( oy = wp->yoff; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, wp->yoff); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); if (tty_term_has(tty->term, TTYC_EL)) { - for (i = oy + s->cy; i < oy + screen_size_y(s); i++) { + for (i = oy + s->old_cy; i < oy + screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); } } else { - for (i = s->cx; i < screen_size_y(s); i++) + for (i = s->old_cx; i < screen_size_y(s); i++) tty_putc(tty, ' '); - for (j = oy + s->cy; j < oy + screen_size_y(s); j++) { + for (j = oy + s->old_cy; j < oy + screen_size_y(s); j++) { for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } } - tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx); } void @@ -582,24 +580,24 @@ tty_cmd_clearstartofscreen( oy = wp->yoff; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, oy); + tty_cursor(tty, s->old_cx, s->old_cy, oy); tty_putcode2(tty, TTYC_CUP, oy, 0); if (tty_term_has(tty->term, TTYC_EL)) { - for (i = 0; i < oy + s->cy; i++) { + for (i = 0; i < oy + s->old_cy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); } - tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0); + tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, 0); } else { - for (j = 0; j < oy + s->cy; j++) { + for (j = 0; j < oy + s->old_cy; j++) { for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } } - for (i = 0; i < s->cx; i++) + for (i = 0; i < s->old_cx; i++) tty_putc(tty, ' '); - tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx); } void @@ -612,7 +610,7 @@ tty_cmd_clearscreen( oy = wp->yoff; tty_reset(tty); - tty_cursor(tty, s->cx, s->cy, oy); + tty_cursor(tty, s->old_cx, s->old_cy, oy); tty_putcode2(tty, TTYC_CUP, oy, 0); if (tty_term_has(tty->term, TTYC_EL)) { @@ -627,28 +625,28 @@ tty_cmd_clearscreen( tty_putc(tty, ' '); } } - tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx); + tty_putcode2(tty, TTYC_CUP, oy + s->old_cy, s->old_cx); } void tty_cmd_cell(struct tty *tty, struct window_pane *wp, va_list ap) { + struct screen *s = wp->screen; struct grid_cell *gc; gc = va_arg(ap, struct grid_cell *); - tty_cell(tty, wp->screen, wp->yoff, gc); + tty_cursor(tty, s->old_cx, s->old_cy, wp->yoff); + + tty_cell(tty, gc); } void -tty_cell( - struct tty *tty, struct screen *s, u_int oy, const struct grid_cell *gc) +tty_cell(struct tty *tty, const struct grid_cell *gc) { u_int i, width; u_char out[4]; - tty_cursor(tty, s->cx, s->cy, oy); - /* If this is a padding character, do nothing. */ if (gc->flags & GRID_FLAG_PADDING) return; @@ -697,11 +695,11 @@ tty_reset(struct tty *tty) } void -tty_region(struct tty *tty, struct screen *s, u_int oy) +tty_region(struct tty *tty, u_int rupper, u_int rlower, u_int oy) { - if (tty->rlower != oy + s->rlower || tty->rupper != oy + s->rupper) { - tty->rlower = oy + s->rlower; - tty->rupper = oy + s->rupper; + if (tty->rlower != oy + rlower || tty->rupper != oy + rupper) { + tty->rlower = oy + rlower; + tty->rupper = oy + rupper; tty->cx = 0; tty->cy = 0; tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower);