diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2015-11-13 08:09:29 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2015-11-13 08:09:29 +0000 |
commit | 1807e69c6fc53984f200744f88f41cb74d0afb66 (patch) | |
tree | 1e3884b98699d369bfce45fb1725cfc553d71b5d /usr.bin | |
parent | 5ff4709ff7558432f7ee0cb765b3715c28a0f05a (diff) |
Long overdue change to the way we store cells in the grid: now, instead
of storing a full grid_cell with UTF-8 data and everything, store a new
type grid_cell_entry. This can either be the cell itself (for ASCII
cells), or an offset into an extended array (per line) for UTF-8
data.
This avoid a large (8 byte) overhead on non-UTF-8 cells (by far the
majority for most users) without the complexity of the shadow array we
had before. Grid memory without any UTF-8 is about half.
The disadvantage that cells can no longer be modified in place and need
to be copied out of the grid and back but it turned out to be lot less
complicated than I expected.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/tmux/format.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/grid-cell.c | 55 | ||||
-rw-r--r-- | usr.bin/tmux/grid-view.c | 21 | ||||
-rw-r--r-- | usr.bin/tmux/grid.c | 171 | ||||
-rw-r--r-- | usr.bin/tmux/input.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/screen-write.c | 94 | ||||
-rw-r--r-- | usr.bin/tmux/status.c | 9 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 74 | ||||
-rw-r--r-- | usr.bin/tmux/tty.c | 39 | ||||
-rw-r--r-- | usr.bin/tmux/utf8.c | 19 | ||||
-rw-r--r-- | usr.bin/tmux/window-copy.c | 107 |
12 files changed, 308 insertions, 293 deletions
diff --git a/usr.bin/tmux/Makefile b/usr.bin/tmux/Makefile index 5ab96427132..8138a15842b 100644 --- a/usr.bin/tmux/Makefile +++ b/usr.bin/tmux/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.81 2015/10/27 13:23:24 nicm Exp $ +# $OpenBSD: Makefile,v 1.82 2015/11/13 08:09:28 nicm Exp $ PROG= tmux SRCS= alerts.c \ @@ -76,7 +76,6 @@ SRCS= alerts.c \ control-notify.c \ environ.c \ format.c \ - grid-cell.c \ grid-view.c \ grid.c \ input-keys.c \ diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index ca97da95ad9..269a8ec55a6 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.94 2015/11/12 11:09:11 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.95 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net> @@ -415,6 +415,7 @@ format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe) for (i = 0; i < gd->hsize; i++) { gl = &gd->linedata[i]; size += gl->cellsize * sizeof *gl->celldata; + size += gl->extdsize * sizeof *gl->extddata; } size += gd->hsize * sizeof *gd->linedata; diff --git a/usr.bin/tmux/grid-cell.c b/usr.bin/tmux/grid-cell.c deleted file mode 100644 index 4b71d2ba3c1..00000000000 --- a/usr.bin/tmux/grid-cell.c +++ /dev/null @@ -1,55 +0,0 @@ -/* $OpenBSD: grid-cell.c,v 1.1 2013/01/18 02:16:21 nicm Exp $ */ - -/* - * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> - -#include <string.h> - -#include "tmux.h" - -/* Get cell width. */ -u_int -grid_cell_width(const struct grid_cell *gc) -{ - return (gc->xstate >> 4); -} - -/* Get cell data. */ -void -grid_cell_get(const struct grid_cell *gc, struct utf8_data *ud) -{ - ud->size = gc->xstate & 0xf; - ud->width = gc->xstate >> 4; - memcpy(ud->data, gc->xdata, ud->size); -} - -/* Set cell data. */ -void -grid_cell_set(struct grid_cell *gc, const struct utf8_data *ud) -{ - memcpy(gc->xdata, ud->data, ud->size); - gc->xstate = (ud->width << 4) | ud->size; -} - -/* Set a single character as cell data. */ -void -grid_cell_one(struct grid_cell *gc, u_char ch) -{ - *gc->xdata = ch; - gc->xstate = (1 << 4) | 1; -} diff --git a/usr.bin/tmux/grid-view.c b/usr.bin/tmux/grid-view.c index c0deb6b07bb..86d1feba6bc 100644 --- a/usr.bin/tmux/grid-view.c +++ b/usr.bin/tmux/grid-view.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid-view.c,v 1.21 2015/01/06 21:14:42 nicm Exp $ */ +/* $OpenBSD: grid-view.c,v 1.22 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -30,24 +30,17 @@ #define grid_view_x(gd, x) (x) #define grid_view_y(gd, y) ((gd)->hsize + (y)) -/* Get cell for reading. */ -const struct grid_cell * -grid_view_peek_cell(struct grid *gd, u_int px, u_int py) -{ - return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py))); -} - -/* Get cell for writing. */ -struct grid_cell * -grid_view_get_cell(struct grid *gd, u_int px, u_int py) +/* Get cel. */ +void +grid_view_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc) { - return (grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py))); + grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc); } /* Set cell. */ void -grid_view_set_cell( - struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) +grid_view_set_cell(struct grid *gd, u_int px, u_int py, + const struct grid_cell *gc) { grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc); } diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index 664ae12f419..ea382208ce0 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.47 2015/11/12 14:50:57 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.48 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -36,15 +36,17 @@ */ /* Default grid cell data. */ -const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " }; - -#define grid_put_cell(gd, px, py, gc) do { \ - memcpy(&gd->linedata[py].celldata[px], \ - gc, sizeof gd->linedata[py].celldata[px]); \ -} while (0) +const struct grid_cell grid_default_cell = { + 0, 0, 8, 8, { { ' ' }, 0, 1, 1 } +}; +const struct grid_cell_entry grid_default_entry = { + 0, { .data = { 0, 8, 8, ' ' } } +}; int grid_check_y(struct grid *, u_int); +void grid_reflow_copy(struct grid_line *, u_int, struct grid_line *l, + u_int, u_int); 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); @@ -54,6 +56,13 @@ size_t grid_string_cells_bg(const struct grid_cell *, int *); void grid_string_cells_code(const struct grid_cell *, const struct grid_cell *, char *, size_t, int); +/* Copy default into a cell. */ +static void +grid_clear_cell(struct grid *gd, u_int px, u_int py) +{ + gd->linedata[py].celldata[px] = grid_default_entry; +} + /* Check grid y position. */ int grid_check_y(struct grid *gd, u_int py) @@ -95,6 +104,7 @@ grid_destroy(struct grid *gd) for (yy = 0; yy < gd->hsize + gd->sy; yy++) { gl = &gd->linedata[yy]; free(gl->celldata); + free(gl->extddata); } free(gd->linedata); @@ -107,7 +117,7 @@ int grid_compare(struct grid *ga, struct grid *gb) { struct grid_line *gla, *glb; - struct grid_cell *gca, *gcb; + struct grid_cell gca, gcb; u_int xx, yy; if (ga->sx != gb->sx || ga->sy != gb->sy) @@ -118,10 +128,10 @@ grid_compare(struct grid *ga, struct grid *gb) glb = &gb->linedata[yy]; if (gla->cellsize != glb->cellsize) return (1); - for (xx = 0; xx < ga->sx; xx++) { - gca = &gla->celldata[xx]; - gcb = &glb->celldata[xx]; - if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0) + for (xx = 0; xx < gla->cellsize; xx++) { + grid_get_cell(ga, xx, yy, &gca); + grid_get_cell(gb, xx, yy, &gcb); + if (memcmp(&gca, &gcb, sizeof (struct grid_cell)) != 0) return (1); } } @@ -224,7 +234,7 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx) gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata); for (xx = gl->cellsize; xx < sx; xx++) - grid_put_cell(gd, xx, py, &grid_default_cell); + grid_clear_cell(gd, xx, py); gl->cellsize = sx; } @@ -238,37 +248,72 @@ grid_peek_line(struct grid *gd, u_int py) } /* Get cell for reading. */ -const struct grid_cell * -grid_peek_cell(struct grid *gd, u_int px, u_int py) +void +grid_get_cell(struct grid *gd, u_int px, u_int py, struct grid_cell *gc) { - if (grid_check_y(gd, py) != 0) - return (&grid_default_cell); + struct grid_line *gl; + struct grid_cell_entry *gce; - if (px >= gd->linedata[py].cellsize) - return (&grid_default_cell); - return (&gd->linedata[py].celldata[px]); -} + if (grid_check_y(gd, py) != 0 || px >= gd->linedata[py].cellsize) { + memcpy(gc, &grid_default_cell, sizeof *gc); + return; + } -/* Get cell at relative position (for writing). */ -struct grid_cell * -grid_get_cell(struct grid *gd, u_int px, u_int py) -{ - if (grid_check_y(gd, py) != 0) - return (NULL); + gl = &gd->linedata[py]; + gce = &gl->celldata[px]; - grid_expand_line(gd, py, px + 1); - return (&gd->linedata[py].celldata[px]); + if (gce->flags & GRID_FLAG_EXTENDED) { + if (gce->offset >= gl->extdsize) + memcpy(gc, &grid_default_cell, sizeof *gc); + else + memcpy(gc, &gl->extddata[gce->offset], sizeof *gc); + return; + } + + gc->flags = gce->flags & ~GRID_FLAG_EXTENDED; + gc->attr = gce->data.attr; + gc->fg = gce->data.fg; + gc->bg = gce->data.bg; + utf8_set(&gc->data, gce->data.data); } /* Set cell at relative position. */ void grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) { + struct grid_line *gl; + struct grid_cell_entry *gce; + struct grid_cell *gcp; + if (grid_check_y(gd, py) != 0) return; grid_expand_line(gd, py, px + 1); - grid_put_cell(gd, px, py, gc); + + gl = &gd->linedata[py]; + gce = &gl->celldata[px]; + + if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 || + gc->data.width != 1) { + if (~gce->flags & GRID_FLAG_EXTENDED) { + gl->extddata = xreallocarray(gl->extddata, + gl->extdsize + 1, sizeof *gl->extddata); + gce->offset = gl->extdsize++; + gce->flags = gc->flags | GRID_FLAG_EXTENDED; + } + + if (gce->offset >= gl->extdsize) + fatalx("offset too big"); + gcp = &gl->extddata[gce->offset]; + memcpy(gcp, gc, sizeof *gcp); + return; + } + + gce->flags = gc->flags & ~GRID_FLAG_EXTENDED; + gce->data.attr = gc->attr; + gce->data.fg = gc->fg; + gce->data.bg = gc->bg; + gce->data.data = gc->data.data[0]; } /* Clear area. */ @@ -300,7 +345,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) for (xx = px; xx < px + nx; xx++) { if (xx >= gd->linedata[yy].cellsize) break; - grid_put_cell(gd, xx, yy, &grid_default_cell); + grid_clear_cell(gd, xx, yy); } } } @@ -324,6 +369,10 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny) gl = &gd->linedata[yy]; free(gl->celldata); memset(gl, 0, sizeof *gl); + + free(gl->extddata); + gl->extddata = NULL; + gl->extdsize = 0; } } @@ -386,7 +435,7 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) for (xx = px; xx < px + nx; xx++) { if (xx >= dx && xx < dx + nx) continue; - grid_put_cell(gd, xx, py, &grid_default_cell); + grid_clear_cell(gd, xx, py); } } @@ -568,9 +617,8 @@ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, struct grid_cell **lastgc, int with_codes, int escape_c0, int trim) { - const struct grid_cell *gc; + struct grid_cell gc; static struct grid_cell lastgc1; - struct utf8_data ud; const char *data; char *buf, code[128]; size_t len, off, size, codelen; @@ -590,21 +638,20 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, for (xx = px; xx < px + nx; xx++) { if (gl == NULL || xx >= gl->cellsize) break; - gc = &gl->celldata[xx]; - if (gc->flags & GRID_FLAG_PADDING) + grid_get_cell(gd, xx, py, &gc); + if (gc.flags & GRID_FLAG_PADDING) continue; - grid_cell_get(gc, &ud); if (with_codes) { - grid_string_cells_code(*lastgc, gc, code, sizeof code, + grid_string_cells_code(*lastgc, &gc, code, sizeof code, escape_c0); codelen = strlen(code); - memcpy(*lastgc, gc, sizeof *gc); + memcpy(*lastgc, &gc, sizeof **lastgc); } else codelen = 0; - data = ud.data; - size = ud.size; + data = gc.data.data; + size = gc.data.size; if (escape_c0 && size == 1 && *data == '\\') { data = "\\\\"; size = 2; @@ -663,11 +710,44 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, } else dstl->celldata = NULL; + if (srcl->extdsize != 0) { + dstl->extdsize = srcl->extdsize; + dstl->extddata = xreallocarray(NULL, dstl->extdsize, + sizeof *dstl->extddata); + memcpy(dstl->extddata, srcl->extddata, dstl->extdsize * + sizeof *dstl->extddata); + } + sy++; dy++; } } +/* Copy a section of a line. */ +void +grid_reflow_copy(struct grid_line *dst_gl, u_int to, struct grid_line *src_gl, + u_int from, u_int to_copy) +{ + struct grid_cell_entry *gce; + u_int i, was; + + memcpy(&dst_gl->celldata[to], &src_gl->celldata[from], + to_copy * sizeof *dst_gl->celldata); + + for (i = to; i < to + to_copy; i++) { + gce = &dst_gl->celldata[i]; + if (~gce->flags & GRID_FLAG_EXTENDED) + continue; + was = gce->offset; + + dst_gl->extddata = xreallocarray(dst_gl->extddata, + dst_gl->extdsize + 1, sizeof *dst_gl->extddata); + gce->offset = dst_gl->extdsize++; + memcpy(&dst_gl->extddata[gce->offset], &src_gl->extddata[was], + sizeof *dst_gl->extddata); + } +} + /* Join line data. */ void grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, @@ -692,8 +772,7 @@ grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, 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]); + grid_reflow_copy(dst_gl, ox, src_gl, 0, to_copy); /* If there is any left in the source, split it. */ if (src_gl->cellsize > to_copy) { @@ -732,8 +811,7 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl, 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]); + grid_reflow_copy(dst_gl, 0, src_gl, offset, to_copy); /* Move offset and reduce old line size. */ offset += to_copy; @@ -763,6 +841,7 @@ grid_reflow_move(struct grid *dst, u_int *py, struct grid_line *src_gl) /* Clear old line. */ src_gl->celldata = NULL; + src_gl->extddata = NULL; } /* @@ -792,7 +871,7 @@ grid_reflow(struct grid *dst, struct grid *src, u_int new_x) /* Previous was wrapped. Try to join. */ grid_reflow_join(dst, &py, src_gl, new_x); } - previous_wrapped = src_gl->flags & GRID_LINE_WRAPPED; + previous_wrapped = (src_gl->flags & GRID_LINE_WRAPPED); } grid_destroy(src); diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c index 8040cb191c7..5665a14adaa 100644 --- a/usr.bin/tmux/input.c +++ b/usr.bin/tmux/input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: input.c,v 1.88 2015/11/12 11:09:11 nicm Exp $ */ +/* $OpenBSD: input.c,v 1.89 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1006,7 +1006,7 @@ input_print(struct input_ctx *ictx) else ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET; - grid_cell_one(&ictx->cell.cell, ictx->ch); + utf8_set(&ictx->cell.cell.data, ictx->ch); screen_write_cell(&ictx->ctx, &ictx->cell.cell); ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET; @@ -1945,7 +1945,7 @@ input_utf8_close(struct input_ctx *ictx) utf8_append(&ictx->utf8data, ictx->ch); - grid_cell_set(&ictx->cell.cell, &ictx->utf8data); + utf8_copy(&ictx->cell.cell.data, &ictx->utf8data); screen_write_cell(&ictx->ctx, &ictx->cell.cell); return (0); diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 727bc88f8c7..f9db0b41e50 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.76 2015/11/12 22:04:37 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.77 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -67,7 +67,7 @@ void screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) { - grid_cell_one(gc, ch); + utf8_set(&gc->data, ch); screen_write_cell(ctx, gc); } @@ -126,7 +126,7 @@ screen_write_strlen(const char *fmt, ...) ptr++; left = strlen(ptr); - if (left < ud.size - 1) + if (left < (size_t)ud.size - 1) break; while (utf8_append(&ud, *ptr)) ptr++; @@ -185,7 +185,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, ptr++; left = strlen(ptr); - if (left < ud.size - 1) + if (left < (size_t)ud.size - 1) break; while (utf8_append(&ud, *ptr)) ptr++; @@ -201,7 +201,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, } size += ud.width; - grid_cell_set(gc, &ud); + utf8_copy(&gc->data, &ud); screen_write_cell(ctx, gc); } else { if (maxlen > 0 && size + 1 > (size_t) maxlen) @@ -258,7 +258,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen, ptr++; left = strlen(ptr); - if (left < ud.size - 1) + if (left < (size_t)ud.size - 1) break; while (utf8_append(&ud, *ptr)) ptr++; @@ -274,7 +274,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, ssize_t maxlen, } size += ud.width; - grid_cell_set(&lgc, &ud); + utf8_copy(&lgc.data, &ud); screen_write_cell(ctx, &lgc); } else { if (maxlen > 0 && size + 1 > (size_t) maxlen) @@ -299,8 +299,7 @@ screen_write_copy(struct screen_write_ctx *ctx, struct screen *s = ctx->s; struct grid *gd = src->grid; struct grid_line *gl; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int xx, yy, cx, cy, ax, bx; cx = s->cx; @@ -324,12 +323,8 @@ screen_write_copy(struct screen_write_ctx *ctx, bx = px + nx; for (xx = ax; xx < bx; xx++) { - if (xx >= gl->cellsize) - gc = &grid_default_cell; - else - gc = &gl->celldata[xx]; - grid_cell_get(gc, &ud); - screen_write_cell(ctx, gc); + grid_get_cell(gd, xx, yy, &gc); + screen_write_cell(ctx, &gc); } if (px + nx == gd->sx && px + nx > gl->cellsize) screen_write_clearendofline(ctx); @@ -342,12 +337,12 @@ screen_write_copy(struct screen_write_ctx *ctx, /* Set up context for TTY command. */ void -screen_write_initctx( - struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, int save_last) +screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, + int save_last) { struct screen *s = ctx->s; struct grid *gd = s->grid; - const struct grid_cell *gc; + struct grid_cell gc; u_int xx; ttyctx->wp = ctx->wp; @@ -362,14 +357,14 @@ screen_write_initctx( return; /* Save the last cell on the screen. */ - gc = &grid_default_cell; + memcpy(&gc, &grid_default_cell, sizeof gc); for (xx = 1; xx <= screen_size_x(s); xx++) { - gc = grid_view_peek_cell(gd, screen_size_x(s) - xx, s->cy); - if (!(gc->flags & GRID_FLAG_PADDING)) + grid_view_get_cell(gd, screen_size_x(s) - xx, s->cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) break; } ttyctx->last_width = xx; - memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); + memcpy(&ttyctx->last_cell, &gc, sizeof ttyctx->last_cell); } /* Set a mode. */ @@ -507,7 +502,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) screen_write_initctx(ctx, &ttyctx, 0); memcpy(&gc, &grid_default_cell, sizeof gc); - grid_cell_one(&gc, 'E'); + utf8_set(&gc.data, 'E'); for (yy = 0; yy < screen_size_y(s); yy++) { for (xx = 0; xx < screen_size_x(s); xx++) @@ -904,14 +899,13 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) struct grid *gd = s->grid; struct tty_ctx ttyctx; u_int width, xx, last; - struct grid_cell tmp_gc, *tmp_gcp; - struct utf8_data ud; + struct grid_cell tmp_gc; int insert; /* Ignore padding. */ if (gc->flags & GRID_FLAG_PADDING) return; - width = grid_cell_width(gc); + width = gc->data.width; /* * If this is a wide character and there is no room on the screen, for @@ -928,8 +922,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) * there is space. */ if (width == 0) { - grid_cell_get(gc, &ud); - if (screen_write_combine(ctx, &ud) == 0) { + if (screen_write_combine(ctx, &gc->data) == 0) { screen_write_initctx(ctx, &ttyctx, 0); tty_write(tty_cmd_utf8character, &ttyctx); } @@ -964,11 +957,11 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) * If the new character is UTF-8 wide, fill in padding cells. Have * already ensured there is enough room. */ - for (xx = s->cx + 1; xx < s->cx + width; xx++) { - tmp_gcp = grid_view_get_cell(gd, xx, s->cy); - if (tmp_gcp != NULL) - tmp_gcp->flags |= GRID_FLAG_PADDING; - } + memcpy(&tmp_gc, &grid_default_cell, sizeof tmp_gc); + tmp_gc.flags |= GRID_FLAG_PADDING; + tmp_gc.data.width = 0; + for (xx = s->cx + 1; xx < s->cx + width; xx++) + grid_view_set_cell(gd, xx, s->cy, &tmp_gc); /* Set the cell. */ grid_view_set_cell(gd, s->cx, s->cy, gc); @@ -990,8 +983,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) } if (screen_check_selection(s, s->cx - width, s->cy)) { memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); - grid_cell_get(gc, &ud); - grid_cell_set(&tmp_gc, &ud); + utf8_copy(&tmp_gc.data, &gc->data); tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); @@ -1011,8 +1003,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud) { struct screen *s = ctx->s; struct grid *gd = s->grid; - struct grid_cell *gc; - struct utf8_data ud1; + struct grid_cell gc; /* Can't combine if at 0. */ if (s->cx == 0) @@ -1023,17 +1014,18 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud) fatalx("UTF-8 data empty"); /* Retrieve the previous cell. */ - gc = grid_view_get_cell(gd, s->cx - 1, s->cy); - grid_cell_get(gc, &ud1); + grid_view_get_cell(gd, s->cx - 1, s->cy, &gc); /* Check there is enough space. */ - if (ud1.size + ud->size > sizeof ud1.data) + if (gc.data.size + ud->size > sizeof gc.data.data) return (-1); - /* Append the data and set the cell. */ - memcpy(ud1.data + ud1.size, ud->data, ud->size); - ud1.size += ud->size; - grid_cell_set(gc, &ud1); + /* Append the data. */ + memcpy(gc.data.data + gc.data.size, ud->data, ud->size); + gc.data.size += ud->size; + + /* Set the new cell. */ + grid_view_set_cell(gd, s->cx - 1, s->cy, &gc); return (0); } @@ -1052,11 +1044,11 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width) { struct screen *s = ctx->s; struct grid *gd = s->grid; - const struct grid_cell *gc; + struct grid_cell gc; u_int xx; - gc = grid_view_peek_cell(gd, s->cx, s->cy); - if (gc->flags & GRID_FLAG_PADDING) { + grid_view_get_cell(gd, s->cx, s->cy, &gc); + if (gc.flags & GRID_FLAG_PADDING) { /* * A padding cell, so clear any following and leading padding * cells back to the character. Don't overwrite the current @@ -1064,8 +1056,8 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width) */ xx = s->cx + 1; while (--xx > 0) { - gc = grid_view_peek_cell(gd, xx, s->cy); - if (!(gc->flags & GRID_FLAG_PADDING)) + grid_view_get_cell(gd, xx, s->cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) break; grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); } @@ -1080,8 +1072,8 @@ screen_write_overwrite(struct screen_write_ctx *ctx, u_int width) */ xx = s->cx + width - 1; while (++xx < screen_size_x(s)) { - gc = grid_view_peek_cell(gd, xx, s->cy); - if (!(gc->flags & GRID_FLAG_PADDING)) + grid_view_get_cell(gd, xx, s->cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) break; grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); } diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c index edbe26ffba6..3592979b7a1 100644 --- a/usr.bin/tmux/status.c +++ b/usr.bin/tmux/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.139 2015/11/12 11:09:11 nicm Exp $ */ +/* $OpenBSD: status.c,v 1.140 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -746,7 +746,7 @@ status_prompt_redraw(struct client *c) struct session *s = c->session; struct screen old_status; size_t i, size, left, len, off; - struct grid_cell gc, *gcp; + struct grid_cell gc; if (c->tty.sx == 0 || c->tty.sy == 0) return (0); @@ -789,8 +789,9 @@ status_prompt_redraw(struct client *c) /* Apply fake cursor. */ off = len + c->prompt_index - off; - gcp = grid_view_get_cell(c->status.grid, off, 0); - gcp->attr ^= GRID_ATTR_REVERSE; + grid_view_get_cell(c->status.grid, off, 0, &gc); + gc.attr ^= GRID_ATTR_REVERSE; + grid_view_set_cell(c->status.grid, off, 0, &gc); if (grid_compare(c->status.grid, old_status.grid) == 0) { screen_free(&old_status); diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index b0c047d5220..a0792454b50 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.575 2015/11/12 12:43:36 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.576 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -621,11 +621,11 @@ struct mode_key_table { struct utf8_data { u_char data[UTF8_SIZE]; - size_t have; - size_t size; + u_char have; + u_char size; - u_int width; -}; + u_char width; +} __packed; /* Grid attributes. */ #define GRID_ATTR_BRIGHT 0x1 @@ -641,41 +641,56 @@ struct utf8_data { #define GRID_FLAG_FG256 0x1 #define GRID_FLAG_BG256 0x2 #define GRID_FLAG_PADDING 0x4 +#define GRID_FLAG_EXTENDED 0x8 /* Grid line flags. */ #define GRID_LINE_WRAPPED 0x1 /* Grid cell data. */ struct grid_cell { - u_char attr; - u_char flags; - u_char fg; - u_char bg; + u_char flags; + u_char attr; + u_char fg; + u_char bg; + struct utf8_data data; - u_char xstate; /* top 4 bits width, bottom 4 bits size */ - u_char xdata[UTF8_SIZE]; +}; +struct grid_cell_entry { + u_char flags; + union { + u_int offset; + struct { + u_char attr; + u_char fg; + u_char bg; + u_char data; + } data; + }; } __packed; /* Grid line. */ struct grid_line { - u_int cellsize; - struct grid_cell *celldata; + u_int cellsize; + struct grid_cell_entry *celldata; + + u_int extdsize; + struct grid_cell *extddata; - int flags; + int flags; } __packed; /* Entire grid of cells. */ struct grid { - int flags; -#define GRID_HISTORY 0x1 /* scroll lines into history */ + int flags; +#define GRID_HISTORY 0x1 /* scroll lines into history */ - u_int sx; - u_int sy; + u_int sx; + u_int sy; - u_int hsize; - u_int hlimit; + u_int hsize; + u_int hlimit; - struct grid_line *linedata; + struct grid_line *linedata; }; /* Option data structures. */ @@ -1854,9 +1869,8 @@ void grid_scroll_history(struct grid *); void grid_scroll_history_region(struct grid *, u_int, u_int); void grid_clear_history(struct grid *); void grid_expand_line(struct grid *, u_int, u_int); -const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int); const struct grid_line *grid_peek_line(struct grid *, u_int); -struct grid_cell *grid_get_cell(struct grid *, u_int, u_int); +void grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *); void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *); void grid_clear(struct grid *, u_int, u_int, u_int, u_int); void grid_clear_lines(struct grid *, u_int, u_int); @@ -1868,17 +1882,10 @@ void grid_duplicate_lines( struct grid *, u_int, struct grid *, u_int, u_int); u_int grid_reflow(struct grid *, struct grid *, u_int); -/* grid-cell.c */ -u_int grid_cell_width(const struct grid_cell *); -void grid_cell_get(const struct grid_cell *, struct utf8_data *); -void grid_cell_set(struct grid_cell *, const struct utf8_data *); -void grid_cell_one(struct grid_cell *, u_char); - /* grid-view.c */ -const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int); -struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int); -void grid_view_set_cell( - struct grid *, u_int, u_int, const struct grid_cell *); +void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *); +void grid_view_set_cell(struct grid *, u_int, u_int, + const struct grid_cell *); void grid_view_clear_history(struct grid *); void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int); void grid_view_scroll_region_up(struct grid *, u_int, u_int); @@ -2183,6 +2190,7 @@ void session_renumber_windows(struct session *); /* utf8.c */ u_int utf8_width(u_int); void utf8_set(struct utf8_data *, u_char); +void utf8_copy(struct utf8_data *, const struct utf8_data *); int utf8_open(struct utf8_data *, u_char); int utf8_append(struct utf8_data *, u_char); u_int utf8_combine(const struct utf8_data *); diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 99d5a1efb8e..cb7ede09f03 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.192 2015/10/31 13:12:03 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.193 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -656,10 +656,8 @@ void tty_draw_line(struct tty *tty, const struct window_pane *wp, struct screen *s, u_int py, u_int ox, u_int oy) { - const struct grid_cell *gc; + struct grid_cell gc; struct grid_line *gl; - struct grid_cell tmpgc; - struct utf8_data ud; u_int i, sx; int flags; @@ -686,18 +684,13 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, tty_cursor(tty, ox, oy + py); for (i = 0; i < sx; i++) { - gc = grid_view_peek_cell(s->grid, i, py); + grid_view_get_cell(s->grid, i, py, &gc); if (screen_check_selection(s, i, py)) { - memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc); - grid_cell_get(gc, &ud); - grid_cell_set(&tmpgc, &ud); - tmpgc.flags = gc->flags & - ~(GRID_FLAG_FG256|GRID_FLAG_BG256); - tmpgc.flags |= s->sel.cell.flags & + gc.flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256); + gc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); - tty_cell(tty, &tmpgc, wp); - } else - tty_cell(tty, gc, wp); + } + tty_cell(tty, &gc, wp); } if (sx < tty->sx) { @@ -1078,7 +1071,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); /* Is the cursor in the very last position? */ - width = grid_cell_width(ctx->cell); + width = ctx->cell->data.width; if (ctx->ocx > wp->sx - width) { if (ctx->xoff != 0 || wp->sx != tty->sx) { /* @@ -1095,7 +1088,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) * move as far left as possible and redraw the last * cell to move into the last position. */ - cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell); + cx = screen_size_x(s) - ctx->last_cell.data.width; tty_cursor_pane(tty, ctx, cx, ctx->ocy); tty_cell(tty, &ctx->last_cell, wp); } @@ -1155,8 +1148,7 @@ void tty_cell(struct tty *tty, const struct grid_cell *gc, const struct window_pane *wp) { - struct utf8_data ud; - u_int i; + u_int i; /* Skip last character if terminal is stupid. */ if (tty->term->flags & TERM_EARLYWRAP && @@ -1171,23 +1163,22 @@ tty_cell(struct tty *tty, const struct grid_cell *gc, tty_attributes(tty, gc, wp); /* Get the cell and if ASCII write with putc to do ACS translation. */ - grid_cell_get(gc, &ud); - if (ud.size == 1) { - if (*ud.data < 0x20 || *ud.data == 0x7f) + if (gc->data.size == 1) { + if (*gc->data.data < 0x20 || *gc->data.data == 0x7f) return; - tty_putc(tty, *ud.data); + tty_putc(tty, *gc->data.data); return; } /* If not UTF-8, write _. */ if (!(tty->flags & TTY_UTF8)) { - for (i = 0; i < ud.width; i++) + for (i = 0; i < gc->data.width; i++) tty_putc(tty, '_'); return; } /* Write the data. */ - tty_putn(tty, ud.data, ud.size, ud.width); + tty_putn(tty, gc->data.data, gc->data.size, gc->data.width); } void diff --git a/usr.bin/tmux/utf8.c b/usr.bin/tmux/utf8.c index bb4583dcb24..05de823f65e 100644 --- a/usr.bin/tmux/utf8.c +++ b/usr.bin/tmux/utf8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utf8.c,v 1.19 2015/11/12 22:04:37 nicm Exp $ */ +/* $OpenBSD: utf8.c,v 1.20 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -352,10 +352,27 @@ static void utf8_build(void); void utf8_set(struct utf8_data *ud, u_char ch) { + u_int i; + *ud->data = ch; ud->size = 1; ud->width = 1; + + for (i = ud->size; i < sizeof ud->data; i++) + ud->data[i] = '\0'; +} + +/* Copy UTF-8 character. */ +void +utf8_copy(struct utf8_data *to, const struct utf8_data *from) +{ + u_int i; + + memcpy(to, from, sizeof *to); + + for (i = to->size; i < sizeof to->data; i++) + to->data[i] = '\0'; } /* diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 94a14603db6..8ed0f133b46 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.139 2015/11/12 11:09:11 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.140 2015/11/13 08:09:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -942,21 +942,21 @@ int window_copy_search_compare(struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis) { - const struct grid_cell *gc, *sgc; - struct utf8_data ud, sud; + struct grid_cell gc, sgc; + const struct utf8_data *ud, *sud; - gc = grid_peek_cell(gd, px, py); - grid_cell_get(gc, &ud); - sgc = grid_peek_cell(sgd, spx, 0); - grid_cell_get(sgc, &sud); + grid_get_cell(gd, px, py, &gc); + ud = &gc.data; + grid_get_cell(sgd, spx, 0, &sgc); + sud = &sgc.data; - if (ud.size != sud.size || ud.width != sud.width) + if (ud->size != sud->size || ud->width != sud->width) return (0); - if (cis && ud.size == 1) - return (tolower(ud.data[0]) == sud.data[0]); + if (cis && ud->size == 1) + return (tolower(ud->data[0]) == sud->data[0]); - return (memcmp(ud.data, sud.data, ud.size) == 0); + return (memcmp(ud->data, sud->data, ud->size) == 0); } int @@ -1541,12 +1541,12 @@ window_copy_append_selection(struct window_pane *wp, const char *bufname) } void -window_copy_copy_line(struct window_pane *wp, - char **buf, size_t *off, u_int sy, u_int sx, u_int ex) +window_copy_copy_line(struct window_pane *wp, char **buf, size_t *off, u_int sy, + u_int sx, u_int ex) { struct window_copy_mode_data *data = wp->modedata; struct grid *gd = data->backing->grid; - const struct grid_cell *gc; + struct grid_cell gc; struct grid_line *gl; struct utf8_data ud; u_int i, xx, wrapped = 0; @@ -1575,11 +1575,11 @@ window_copy_copy_line(struct window_pane *wp, if (sx < ex) { for (i = sx; i < ex; i++) { - gc = grid_peek_cell(gd, i, sy); - if (gc->flags & GRID_FLAG_PADDING) + grid_get_cell(gd, i, sy, &gc); + if (gc.flags & GRID_FLAG_PADDING) continue; - grid_cell_get(gc, &ud); - if (ud.size == 1 && (gc->attr & GRID_ATTR_CHARSET)) { + utf8_copy(&ud, &gc.data); + if (ud.size == 1 && (gc.attr & GRID_ATTR_CHARSET)) { s = tty_acs_get(NULL, ud.data[0]); if (s != NULL && strlen(s) <= sizeof ud.data) { ud.size = strlen(s); @@ -1618,16 +1618,17 @@ int window_copy_in_set(struct window_pane *wp, u_int px, u_int py, const char *set) { struct window_copy_mode_data *data = wp->modedata; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; + const struct utf8_data *ud; + + grid_get_cell(data->backing->grid, px, py, &gc); - gc = grid_peek_cell(data->backing->grid, px, py); - grid_cell_get(gc, &ud); - if (ud.size != 1 || gc->flags & GRID_FLAG_PADDING) + ud = &gc.data; + if (ud->size != 1 || (gc.flags & GRID_FLAG_PADDING)) return (0); - if (*ud.data == 0x00 || *ud.data == 0x7f) + if (*ud->data == 0x00 || *ud->data == 0x7f) return (0); - return (strchr(set, *ud.data) != NULL); + return (strchr(set, *ud->data) != NULL); } u_int @@ -1635,8 +1636,7 @@ window_copy_find_length(struct window_pane *wp, u_int py) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = data->backing; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int px; /* @@ -1649,9 +1649,8 @@ window_copy_find_length(struct window_pane *wp, u_int py) if (px > screen_size_x(s)) px = screen_size_x(s); while (px > 0) { - gc = grid_peek_cell(s->grid, px - 1, py); - grid_cell_get(gc, &ud); - if (ud.size != 1 || *ud.data != ' ') + grid_get_cell(s->grid, px - 1, py, &gc); + if (gc.data.size != 1 || *gc.data.data != ' ') break; px--; } @@ -1685,17 +1684,15 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; u_int px, py, xx; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; px = 0; py = screen_hsize(data->backing) + data->cy - data->oy; xx = window_copy_find_length(wp, py); while (px < xx) { - gc = grid_peek_cell(data->backing->grid, px, py); - grid_cell_get(gc, &ud); - if (ud.size != 1 || *ud.data != ' ') + grid_get_cell(data->backing->grid, px, py, &gc); + if (gc.data.size != 1 || *gc.data.data != ' ') break; px++; } @@ -1909,8 +1906,7 @@ window_copy_cursor_jump(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int px, py, xx; px = data->cx + 1; @@ -1918,10 +1914,9 @@ window_copy_cursor_jump(struct window_pane *wp) xx = window_copy_find_length(wp, py); while (px < xx) { - gc = grid_peek_cell(back_s->grid, px, py); - grid_cell_get(gc, &ud); - if (!(gc->flags & GRID_FLAG_PADDING) && - ud.size == 1 && *ud.data == data->jumpchar) { + grid_get_cell(back_s->grid, px, py, &gc); + if (!(gc.flags & GRID_FLAG_PADDING) && + gc.data.size == 1 && *gc.data.data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); @@ -1936,8 +1931,7 @@ window_copy_cursor_jump_back(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int px, py; px = data->cx; @@ -1947,10 +1941,9 @@ window_copy_cursor_jump_back(struct window_pane *wp) px--; for (;;) { - gc = grid_peek_cell(back_s->grid, px, py); - grid_cell_get(gc, &ud); - if (!(gc->flags & GRID_FLAG_PADDING) && - ud.size == 1 && *ud.data == data->jumpchar) { + grid_get_cell(back_s->grid, px, py, &gc); + if (!(gc.flags & GRID_FLAG_PADDING) && + gc.data.size == 1 && *gc.data.data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); @@ -1967,8 +1960,7 @@ window_copy_cursor_jump_to(struct window_pane *wp, int jump_again) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int px, py, xx; px = data->cx + 1 + jump_again; @@ -1976,10 +1968,9 @@ window_copy_cursor_jump_to(struct window_pane *wp, int jump_again) xx = window_copy_find_length(wp, py); while (px < xx) { - gc = grid_peek_cell(back_s->grid, px, py); - grid_cell_get(gc, &ud); - if (!(gc->flags & GRID_FLAG_PADDING) && - ud.size == 1 && *ud.data == data->jumpchar) { + grid_get_cell(back_s->grid, px, py, &gc); + if (!(gc.flags & GRID_FLAG_PADDING) && + gc.data.size == 1 && *gc.data.data == data->jumpchar) { window_copy_update_cursor(wp, px - 1, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); @@ -1994,8 +1985,7 @@ window_copy_cursor_jump_to_back(struct window_pane *wp, int jump_again) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - const struct grid_cell *gc; - struct utf8_data ud; + struct grid_cell gc; u_int px, py; px = data->cx; @@ -2008,10 +1998,9 @@ window_copy_cursor_jump_to_back(struct window_pane *wp, int jump_again) px--; for (;;) { - gc = grid_peek_cell(back_s->grid, px, py); - grid_cell_get(gc, &ud); - if (!(gc->flags & GRID_FLAG_PADDING) && - ud.size == 1 && *ud.data == data->jumpchar) { + grid_get_cell(back_s->grid, px, py, &gc); + if (!(gc.flags & GRID_FLAG_PADDING) && + gc.data.size == 1 && *gc.data.data == data->jumpchar) { window_copy_update_cursor(wp, px + 1, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); |