diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/grid.c | 155 | ||||
-rw-r--r-- | usr.bin/tmux/screen.c | 15 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
3 files changed, 133 insertions, 41 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index 626a2694038..ff9f302cd07 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.22 2013/02/05 11:08:59 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.23 2013/03/21 16:12:10 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -70,6 +70,11 @@ grid_check_y(struct grid *gd, u_int py) } #endif +void grid_reflow_join(struct grid *, u_int *, struct grid_line *, u_int); +void grid_reflow_split(struct grid *, u_int *, struct grid_line *, u_int, + u_int); +void grid_reflow_move(struct grid *, u_int *, struct grid_line *); + /* Create a new grid. */ struct grid * grid_create(u_int sx, u_int sy, u_int hlimit) @@ -461,43 +466,135 @@ grid_duplicate_lines( } } +/* Join line data. */ +void +grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, + u_int new_x) +{ + struct grid_line *dst_gl = &dst->linedata[(*py) - 1]; + u_int left, to_copy, ox, nx; + + /* How much is left on the old line? */ + left = new_x - dst_gl->cellsize; + + /* Work out how much to append. */ + to_copy = src_gl->cellsize; + if (to_copy > left) + to_copy = left; + ox = dst_gl->cellsize; + nx = ox + to_copy; + + /* Resize the destination line. */ + dst_gl->celldata = xrealloc(dst_gl->celldata, nx, + sizeof *dst_gl->celldata); + dst_gl->cellsize = nx; + + /* Append as much as possible. */ + memcpy(&dst_gl->celldata[ox], &src_gl->celldata[0], + to_copy * sizeof src_gl->celldata[0]); + + /* If there is any left in the source, split it. */ + if (src_gl->cellsize > to_copy) { + dst_gl->flags |= GRID_LINE_WRAPPED; + + src_gl->cellsize -= to_copy; + grid_reflow_split(dst, py, src_gl, new_x, to_copy); + } +} + +/* Split line data. */ +void +grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl, + u_int new_x, u_int offset) +{ + struct grid_line *dst_gl = NULL; + u_int to_copy; + + /* Loop and copy sections of the source line. */ + while (src_gl->cellsize > 0) { + /* Create new line. */ + if (*py >= dst->hsize + dst->sy) + grid_scroll_history(dst); + dst_gl = &dst->linedata[*py]; + (*py)++; + + /* How much should we copy? */ + to_copy = new_x; + if (to_copy > src_gl->cellsize) + to_copy = src_gl->cellsize; + + /* Expand destination line. */ + dst_gl->celldata = xmalloc(to_copy * sizeof *dst_gl->celldata); + dst_gl->cellsize = to_copy; + dst_gl->flags |= GRID_LINE_WRAPPED; + + /* Copy the data. */ + memcpy (&dst_gl->celldata[0], &src_gl->celldata[offset], + to_copy * sizeof dst_gl->celldata[0]); + + /* Move offset and reduce old line size. */ + offset += to_copy; + src_gl->cellsize -= to_copy; + } + + /* Last line is not wrapped. */ + if (dst_gl != NULL) + dst_gl->flags &= ~GRID_LINE_WRAPPED; +} + +/* Move line data. */ +void +grid_reflow_move(struct grid *dst, u_int *py, struct grid_line *src_gl) +{ + struct grid_line *dst_gl; + + /* Create new line. */ + if (*py >= dst->hsize + dst->sy) + grid_scroll_history(dst); + dst_gl = &dst->linedata[*py]; + (*py)++; + + /* Copy the old line. */ + memcpy(dst_gl, src_gl, sizeof *dst_gl); + dst_gl->flags &= ~GRID_LINE_WRAPPED; + + /* Clear old line. */ + src_gl->celldata = NULL; +} + /* - * Reflow lines from src grid into dst grid based on width sx. Returns number - * of lines fewer in the visible area, or zero. + * Reflow lines from src grid into dst grid of width new_x. Returns number of + * lines fewer in the visible area. The source grid is destroyed. */ u_int -grid_reflow(struct grid *dst, const struct grid *src, u_int sx) +grid_reflow(struct grid *dst, struct grid *src, u_int new_x) { - u_int px, py, line, cell; + u_int py, sy, line; int previous_wrapped; - struct grid_line *gl; + struct grid_line *src_gl; + + py = 0; + sy = src->sy; - px = py = 0; - previous_wrapped = 1; - for (line = 0; line < src->sy + src->hsize; line++) { - gl = src->linedata + line; + previous_wrapped = 0; + for (line = 0; line < sy + src->hsize; line++) { + src_gl = src->linedata + line; if (!previous_wrapped) { - px = 0; - py++; - if (py >= dst->hsize + dst->sy) - grid_scroll_history(dst); + /* Wasn't wrapped. If smaller, move to destination. */ + if (src_gl->cellsize <= new_x) + grid_reflow_move(dst, &py, src_gl); + else + grid_reflow_split(dst, &py, src_gl, new_x, 0); + } else { + /* Previous was wrapped. Try to join. */ + grid_reflow_join(dst, &py, src_gl, new_x); } - for (cell = 0; cell < gl->cellsize; cell++) { - if (px == sx) { - dst->linedata[py].flags |= GRID_LINE_WRAPPED; - px = 0; - py++; - if (py >= dst->hsize + dst->sy) - grid_scroll_history(dst); - } - grid_set_cell(dst, px, py, gl->celldata + cell); - px++; - } - previous_wrapped = gl->flags & GRID_LINE_WRAPPED; + previous_wrapped = src_gl->flags & GRID_LINE_WRAPPED; } - py++; /* account for final line, which never wraps */ - if (py > src->sy) + grid_destroy(src); + + if (py > sy) return (0); - return (src->sy - py); + return (sy - py); } diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c index 8546f1586b1..aa4cc16b6dc 100644 --- a/usr.bin/tmux/screen.c +++ b/usr.bin/tmux/screen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen.c,v 1.24 2013/02/05 11:08:59 nicm Exp $ */ +/* $OpenBSD: screen.c,v 1.25 2013/03/21 16:12:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -362,15 +362,10 @@ screen_check_selection(struct screen *s, u_int px, u_int py) /* Reflow wrapped lines. */ void -screen_reflow(struct screen *s, u_int sx) +screen_reflow(struct screen *s, u_int new_x) { - struct grid *old, *new; + struct grid *old = s->grid; - old = s->grid; - new = grid_create(old->sx, old->sy, old->hlimit); - - s->cy -= grid_reflow(new, old, sx); - s->grid = new; - - grid_destroy(old); + s->grid = grid_create(old->sx, old->sy, old->hlimit); + s->cy -= grid_reflow(s->grid, old, new_x); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index ca0ec7f5e3f..67975bde0a4 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.377 2013/03/21 16:09:59 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.378 2013/03/21 16:12:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1970,7 +1970,7 @@ void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int); char *grid_string_cells(struct grid *, u_int, u_int, u_int); void grid_duplicate_lines( struct grid *, u_int, struct grid *, u_int, u_int); -u_int grid_reflow(struct grid *, const struct grid *, u_int); +u_int grid_reflow(struct grid *, struct grid *, u_int); /* grid-cell.c */ u_int grid_cell_width(const struct grid_cell *); |