Thanks.
On Sun, Feb 10, 2013 at 03:20:20PM -0500, Richard Woodbury wrote: > I worried that my code did a lot of reallocations, but it ran fine even on > my older machines, so I let it be. This was also less of a concern when it > was an optional feature, but now it matters greatly. > Nicholas, your latest patch passes my smoke test. I will continue to use > it and let you know if it causes any trouble. > > On Sun, Feb 10, 2013 at 11:38 AM, Nicholas Marriott > <[1]nicholas.marri...@gmail.com> wrote: > > And another version. previous_wrap had to be 1 at the start to eat the > blank line inserted because py started at 0 and was incremented before > use. So switch things around so the line is incremented after it is > used. > > diff --git a/grid.c b/grid.c > index aabf66c..3bf02ae 100644 > --- a/grid.c > +++ b/grid.c > @@ -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,134 @@ 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; > + * * * 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. */ > + * * * 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/screen.c b/screen.c > index fe0b738..e92c6aa 100644 > --- a/screen.c > +++ b/screen.c > @@ -363,15 +363,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/tmux.h b/tmux.h > index 1dd11ad..fd67724 100644 > --- a/tmux.h > +++ b/tmux.h > @@ -1960,7 +1960,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 *); > > > ------------------------------------------------------------------------------ > Free Next-Gen Firewall Hardware Offer > Buy your Sophos next-gen firewall before the end March 2013 > and get the hardware for free! Learn more. > [2]http://p.sf.net/sfu/sophos-d2d-feb > _______________________________________________ > tmux-users mailing list > [3]tmux-users@lists.sourceforge.net > [4]https://lists.sourceforge.net/lists/listinfo/tmux-users > > References > > Visible links > 1. mailto:nicholas.marri...@gmail.com > 2. http://p.sf.net/sfu/sophos-d2d-feb > 3. mailto:tmux-users@lists.sourceforge.net > 4. https://lists.sourceforge.net/lists/listinfo/tmux-users ------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users