=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -r1.43 -r1.44 --- src/usr.bin/tmux/window.c 2010/02/06 17:15:33 1.43 +++ src/usr.bin/tmux/window.c 2010/03/22 19:02:54 1.44 @@ -1,4 +1,4 @@ -/* $OpenBSD: window.c,v 1.43 2010/02/06 17:15:33 nicm Exp $ */ +/* $OpenBSD: window.c,v 1.44 2010/03/22 19:02:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -621,6 +621,81 @@ if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) fatal("ioctl failed"); +} + +/* + * Enter alternative screen mode. A copy of the visible screen is saved and the + * history is not updated + */ +void +window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc) +{ + struct screen *s = &wp->base; + u_int sx, sy; + + if (wp->saved_grid != NULL) + return; + if (!options_get_number(&wp->window->options, "alternate-screen")) + return; + sx = screen_size_x(s); + sy = screen_size_y(s); + + wp->saved_grid = grid_create(sx, sy, 0); + grid_duplicate_lines(wp->saved_grid, 0, s->grid, screen_hsize(s), sy); + wp->saved_cx = s->cx; + wp->saved_cy = s->cy; + memcpy(&wp->saved_cell, gc, sizeof wp->saved_cell); + + grid_view_clear(s->grid, 0, 0, sx, sy); + + wp->base.grid->flags &= ~GRID_HISTORY; + + wp->flags |= PANE_REDRAW; +} + +/* Exit alternate screen mode and restore the copied grid. */ +void +window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc) +{ + struct screen *s = &wp->base; + u_int sx, sy; + + if (wp->saved_grid == NULL) + return; + if (!options_get_number(&wp->window->options, "alternate-screen")) + return; + sx = screen_size_x(s); + sy = screen_size_y(s); + + /* + * If the current size is bigger, temporarily resize to the old size + * before copying back. + */ + if (sy > wp->saved_grid->sy) + screen_resize(s, sx, wp->saved_grid->sy); + + /* Restore the grid, cursor position and cell. */ + grid_duplicate_lines(s->grid, screen_hsize(s), wp->saved_grid, 0, sy); + s->cx = wp->saved_cx; + if (s->cx > screen_size_x(s) - 1) + s->cx = screen_size_x(s) - 1; + s->cy = wp->saved_cy; + if (s->cy > screen_size_y(s) - 1) + s->cy = screen_size_y(s) - 1; + memcpy(gc, &wp->saved_cell, sizeof *gc); + + /* + * Turn history back on (so resize can use it) and then resize back to + * the current size. + */ + wp->base.grid->flags |= GRID_HISTORY; + if (sy > wp->saved_grid->sy) + screen_resize(s, sx, sy); + + grid_destroy(wp->saved_grid); + wp->saved_grid = NULL; + + wp->flags |= PANE_REDRAW; } int