aboutsummaryrefslogtreecommitdiff
path: root/screen-write.c
diff options
context:
space:
mode:
Diffstat (limited to 'screen-write.c')
-rw-r--r--screen-write.c421
1 files changed, 245 insertions, 176 deletions
diff --git a/screen-write.c b/screen-write.c
index 8072981f..761ec99f 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -25,7 +25,10 @@
static void screen_write_initctx(struct screen_write_ctx *,
struct tty_ctx *);
-static void screen_write_flush(struct screen_write_ctx *);
+static void screen_write_collect_clear(struct screen_write_ctx *, u_int,
+ u_int);
+static void screen_write_collect_scroll(struct screen_write_ctx *);
+static void screen_write_collect_flush(struct screen_write_ctx *);
static int screen_write_overwrite(struct screen_write_ctx *,
struct grid_cell *, u_int);
@@ -36,23 +39,29 @@ static const struct grid_cell screen_write_pad_cell = {
GRID_FLAG_PADDING, 0, 8, 8, { { 0 }, 0, 0, 0 }
};
-#define screen_dirty_bit(s, x, y) (((y) * screen_size_x(s)) + (x))
-#define screen_dirty_clear(s, sx, sy, ex, ey) \
- do { \
- if (s->dirty != NULL) { \
- bit_nclear(s->dirty, \
- screen_dirty_bit(s, sx, sy), \
- screen_dirty_bit(s, ex, ey)); \
- } \
- } while (0)
+struct screen_write_collect_item {
+ u_int x;
+
+ u_int used;
+ char data[256];
+
+ struct grid_cell gc;
+
+ TAILQ_ENTRY (screen_write_collect_item) entry;
+};
+struct screen_write_collect_line {
+ TAILQ_HEAD(, screen_write_collect_item) items;
+};
/* Initialize writing with a window. */
void
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
struct screen *s)
{
- u_int size;
char tmp[16];
+ u_int y;
+
+ memset(ctx, 0, sizeof *ctx);
ctx->wp = wp;
if (wp != NULL && s == NULL)
@@ -60,15 +69,10 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
else
ctx->s = s;
- size = screen_size_x(ctx->s) * screen_size_y(ctx->s);
- if (ctx->s->dirtysize != size) {
- free(ctx->s->dirty);
- ctx->s->dirty = NULL;
- ctx->s->dirtysize = size;
- }
- ctx->dirty = 0;
-
- ctx->cells = ctx->written = ctx->skipped = 0;
+ ctx->list = xcalloc(screen_size_y(ctx->s), sizeof *ctx->list);
+ for (y = 0; y < screen_size_y(ctx->s); y++)
+ TAILQ_INIT(&ctx->list[y].items);
+ ctx->item = xcalloc(1, sizeof *ctx->item);
if (wp != NULL)
snprintf(tmp, sizeof tmp, "pane %%%u", wp->id);
@@ -80,55 +84,14 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
void
screen_write_stop(struct screen_write_ctx *ctx)
{
- screen_write_flush(ctx);
+ screen_write_collect_end(ctx);
+ screen_write_collect_flush(ctx);
- log_debug("%s: %u of %u written (dirty %u, skipped %u)", __func__,
- ctx->written, ctx->cells, ctx->cells - ctx->written, ctx->skipped);
-}
+ log_debug("%s: %u cells (%u written, %u skipped)", __func__,
+ ctx->cells, ctx->written, ctx->skipped);
-/* Flush outstanding cell writes. */
-static void
-screen_write_flush(struct screen_write_ctx *ctx)
-{
- struct screen *s = ctx->s;
- struct tty_ctx ttyctx;
- u_int x, y, offset, cx, cy, dirty;
- struct grid_cell gc;
-
- if (ctx->dirty == 0)
- return;
- dirty = 0;
- log_debug("%s: dirty %u", __func__, ctx->dirty);
-
- cx = s->cx;
- cy = s->cy;
-
- offset = 0;
- for (y = 0; y < screen_size_y(s); y++) {
- for (x = 0; x < screen_size_x(s); x++) {
- offset++;
- if (!bit_test(s->dirty, offset - 1))
- continue;
- bit_clear(s->dirty, offset - 1);
-
- screen_write_cursormove(ctx, x, y);
- grid_view_get_cell(s->grid, x, y, &gc);
-
- screen_write_initctx(ctx, &ttyctx);
- ttyctx.cell = &gc;
- tty_write(tty_cmd_cell, &ttyctx);
- ctx->written++;
-
- if (++dirty == ctx->dirty)
- break;
- }
- if (dirty == ctx->dirty)
- break;
- }
- ctx->dirty = 0;
-
- s->cx = cx;
- s->cy = cy;
+ free(ctx->item);
+ free(ctx->list); /* flush will have emptied */
}
/* Reset screen state. */
@@ -563,12 +526,9 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
struct tty_ctx ttyctx;
struct grid_cell gc;
u_int xx, yy;
- u_int sx = screen_size_x(s), sy = screen_size_y(s);
screen_write_initctx(ctx, &ttyctx);
- screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
-
memcpy(&gc, &grid_default_cell, sizeof gc);
utf8_set(&gc.data, 'E');
@@ -583,6 +543,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
s->rupper = 0;
s->rlower = screen_size_y(s) - 1;
+ screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1);
tty_write(tty_cmd_alignmenttest, &ttyctx);
}
@@ -604,12 +565,12 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
if (s->cx > screen_size_x(s) - 1)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = nx;
tty_write(tty_cmd_insertcharacter, &ttyctx);
}
@@ -632,12 +593,12 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
if (s->cx > screen_size_x(s) - 1)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = nx;
tty_write(tty_cmd_deletecharacter, &ttyctx);
}
@@ -662,9 +623,9 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx)
screen_write_initctx(ctx, &ttyctx);
- screen_dirty_clear(s, s->cx, s->cy, s->cx + nx - 1, s->cy);
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, 8);
+ screen_write_collect_flush(ctx);
ttyctx.num = nx;
tty_write(tty_cmd_clearcharacter, &ttyctx);
}
@@ -686,12 +647,12 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
grid_view_insert_lines(gd, s->cy, ny, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = ny;
tty_write(tty_cmd_insertline, &ttyctx);
return;
@@ -702,7 +663,6 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
@@ -711,6 +671,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
else
grid_view_insert_lines_region(gd, s->rlower, s->cy, ny, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = ny;
tty_write(tty_cmd_insertline, &ttyctx);
}
@@ -732,12 +693,12 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
grid_view_delete_lines(gd, s->cy, ny, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = ny;
tty_write(tty_cmd_deleteline, &ttyctx);
return;
@@ -748,7 +709,6 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
- screen_write_flush(ctx);
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
@@ -757,6 +717,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
else
grid_view_delete_lines_region(gd, s->rlower, s->cy, ny, bg);
+ screen_write_collect_flush(ctx);
ttyctx.num = ny;
tty_write(tty_cmd_deleteline, &ttyctx);
}
@@ -777,9 +738,9 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
- screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
+ screen_write_collect_clear(ctx, s->cy, 1);
tty_write(tty_cmd_clearline, &ttyctx);
}
@@ -799,9 +760,12 @@ screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
- screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
+ if (s->cx == 0)
+ screen_write_collect_clear(ctx, s->cy, 1);
+ else
+ screen_write_collect_flush(ctx);
tty_write(tty_cmd_clearendofline, &ttyctx);
}
@@ -816,14 +780,15 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
- if (s->cx > sx - 1) {
- screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
+ if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
- } else {
- screen_dirty_clear(s, 0, s->cy, s->cx, s->cy);
+ else
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
- }
+ if (s->cx > sx - 1)
+ screen_write_collect_clear(ctx, s->cy, 1);
+ else
+ screen_write_collect_flush(ctx);
tty_write(tty_cmd_clearstartofline, &ttyctx);
}
@@ -851,12 +816,12 @@ screen_write_reverseindex(struct screen_write_ctx *ctx)
screen_write_initctx(ctx, &ttyctx);
- if (s->cy == s->rupper) {
- screen_write_flush(ctx);
+ if (s->cy == s->rupper)
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
- } else if (s->cy > 0)
+ else if (s->cy > 0)
s->cy--;
+ screen_write_collect_flush(ctx);
tty_write(tty_cmd_reverseindex, &ttyctx);
}
@@ -887,27 +852,24 @@ void
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
{
struct screen *s = ctx->s;
+ struct grid *gd = s->grid;
struct grid_line *gl;
- struct tty_ctx ttyctx;
- u_int sx = screen_size_x(s), sy = screen_size_y(s);
-
- screen_write_initctx(ctx, &ttyctx);
+ struct tty_ctx ttyctx;
- gl = &s->grid->linedata[s->grid->hsize + s->cy];
+ gl = &gd->linedata[gd->hsize + s->cy];
if (wrapped)
gl->flags |= GRID_LINE_WRAPPED;
else
gl->flags &= ~GRID_LINE_WRAPPED;
if (s->cy == s->rlower) {
- screen_dirty_clear(s, 0, s->rupper, sx - 1, s->rupper);
- screen_write_flush(ctx);
- grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
- } else if (s->cy < sy - 1)
- s->cy++;
+ grid_view_scroll_region_up(gd, s->rupper, s->rlower);
- ttyctx.num = wrapped;
- tty_write(tty_cmd_linefeed, &ttyctx);
+ screen_write_collect_scroll(ctx);
+ screen_write_initctx(ctx, &ttyctx);
+ tty_write(tty_cmd_linefeed, &ttyctx);
+ } else if (s->cy < screen_size_y(s) - 1)
+ s->cy++;
}
/* Carriage return (cursor to start of line). */
@@ -932,18 +894,16 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
ttyctx.bg = bg;
/* Scroll into history if it is enabled and clearing entire screen. */
- if (s->cx == 0 && s->cy == 0 && gd->flags & GRID_HISTORY) {
- screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
+ if (s->cx == 0 && s->cy == 0 && (gd->flags & GRID_HISTORY))
grid_view_clear_history(gd, bg);
- } else {
- if (s->cx <= sx - 1) {
- screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
+ else {
+ if (s->cx <= sx - 1)
grid_view_clear(gd, s->cx, s->cy, sx - s->cx, 1, bg);
- }
- screen_dirty_clear(s, 0, s->cy + 1, sx - 1, sy - 1);
grid_view_clear(gd, 0, s->cy + 1, sx, sy - (s->cy + 1), bg);
}
+ screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1));
+ screen_write_collect_flush(ctx);
tty_write(tty_cmd_clearendofscreen, &ttyctx);
}
@@ -958,18 +918,15 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
- if (s->cy > 0) {
- screen_dirty_clear(s, 0, 0, sx - 1, s->cy);
+ if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy, bg);
- }
- if (s->cx > sx - 1) {
- screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
- grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
- } else {
- screen_dirty_clear(s, 0, s->cy, s->cx, s->cy);
- grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
- }
+ if (s->cx > sx - 1)
+ grid_view_clear(s->grid, 0, s->cy, sx, 1, 8);
+ else
+ grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, 8);
+ screen_write_collect_clear(ctx, 0, s->cy);
+ screen_write_collect_flush(ctx);
tty_write(tty_cmd_clearstartofscreen, &ttyctx);
}
@@ -984,14 +941,13 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
screen_write_initctx(ctx, &ttyctx);
ttyctx.bg = bg;
- screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
-
/* Scroll into history if it is enabled. */
if (s->grid->flags & GRID_HISTORY)
grid_view_clear_history(s->grid, bg);
else
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
+ screen_write_collect_clear(ctx, 0, sy);
tty_write(tty_cmd_clearscreen, &ttyctx);
}
@@ -1006,39 +962,165 @@ screen_write_clearhistory(struct screen_write_ctx *ctx)
gd->hscrolled = gd->hsize = 0;
}
+/* Clear a collected line. */
+static void
+screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n)
+{
+ struct screen_write_collect_item *ci, *tmp;
+ u_int i;
+ size_t size;
+
+ for (i = y ; i < y + n; i++) {
+ if (TAILQ_EMPTY(&ctx->list[i].items))
+ continue;
+ size = 0;
+ TAILQ_FOREACH_SAFE(ci, &ctx->list[i].items, entry, tmp) {
+ size += ci->used;
+ TAILQ_REMOVE(&ctx->list[i].items, ci, entry);
+ free(ci);
+ }
+ ctx->skipped += size;
+ log_debug("discarding %zu bytes on line %u", size, i);
+ }
+}
+
+/* Scroll collected lines up. */
+static void
+screen_write_collect_scroll(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+ struct screen_write_collect_line *cl;
+ u_int y;
+
+ screen_write_collect_clear(ctx, s->rupper, 1);
+ for (y = s->rupper; y < s->rlower; y++) {
+ cl = &ctx->list[y + 1];
+ TAILQ_CONCAT(&ctx->list[y].items, &cl->items, entry);
+ TAILQ_INIT(&cl->items);
+ }
+}
+
+/* Flush collected lines. */
+static void
+screen_write_collect_flush(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+ struct screen_write_collect_item *ci, *tmp;
+ u_int y, cx, cy;
+ struct tty_ctx ttyctx;
+
+ cx = s->cx; cy = s->cy;
+ for (y = 0; y < screen_size_y(s); y++) {
+ TAILQ_FOREACH_SAFE(ci, &ctx->list[y].items, entry, tmp) {
+ screen_write_cursormove(ctx, ci->x, y);
+ screen_write_initctx(ctx, &ttyctx);
+ ttyctx.cell = &ci->gc;
+ ttyctx.ptr = ci->data;
+ ttyctx.num = ci->used;
+ tty_write(tty_cmd_cells, &ttyctx);
+ ctx->written += ci->used;
+
+ TAILQ_REMOVE(&ctx->list[y].items, ci, entry);
+ free(ci);
+ }
+ }
+ s->cx = cx; s->cy = cy;
+}
+
+/* Finish and store collected cells. */
+void
+screen_write_collect_end(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+ struct screen_write_collect_item *ci = ctx->item;
+ struct grid_cell gc;
+
+ if (ci->used == 0)
+ return;
+ ci->data[ci->used] = '\0';
+
+ ci->x = s->cx;
+ TAILQ_INSERT_TAIL(&ctx->list[s->cy].items, ci, entry);
+ ctx->item = xcalloc(1, sizeof *ctx->item);
+
+ log_debug("%s: %u %s (at %u,%u)", __func__, ci->used, ci->data, s->cx,
+ s->cy);
+
+ memcpy(&gc, &ci->gc, sizeof gc);
+ grid_view_set_cells(s->grid, s->cx, s->cy, &gc, ci->data, ci->used);
+ s->cx += ci->used;
+}
+
+/* Write cell data, collecting if necessary. */
+void
+screen_write_collect_add(struct screen_write_ctx *ctx,
+ const struct grid_cell *gc)
+{
+ struct screen *s = ctx->s;
+ struct screen_write_collect_item *ci;
+ u_int sx = screen_size_x(s);
+ int collect;
+
+ /*
+ * Don't need to check that the attributes and whatnot are still the
+ * same - input_parse will do a flush when anything that isn't a plain
+ * character is encountered. Also nothing should make it here that
+ * isn't a single ASCII character.
+ */
+
+ collect = 1;
+ if (gc->data.width != 1)
+ collect = 0;
+ else if (gc->attr & GRID_ATTR_CHARSET)
+ collect = 0;
+ else if (~s->mode & MODE_WRAP)
+ collect = 0;
+ else if (s->mode & MODE_INSERT)
+ collect = 0;
+ else if (s->sel.flag)
+ collect = 0;
+ if (!collect) {
+ screen_write_collect_end(ctx);
+ screen_write_cell(ctx, gc);
+ return;
+ }
+ ctx->cells++;
+
+ if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
+ screen_write_collect_end(ctx);
+ if (s->cx > sx - 1) {
+ screen_write_linefeed(ctx, 1);
+ s->cx = 0;
+ }
+
+ ci = ctx->item; /* may have changed */
+ if (ci->used == 0)
+ memcpy(&ci->gc, gc, sizeof ci->gc);
+ ci->data[ci->used++] = gc->data.data[0];
+ if (ci->used == (sizeof ci->data) - 1)
+ screen_write_collect_end(ctx);
+}
+
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
- struct tty_ctx ttyctx;
- u_int width, xx, last;
- u_int sx = screen_size_x(s), sy = screen_size_y(s);
struct grid_line *gl;
- struct grid_cell tmp_gc, now_gc;
struct grid_cell_entry *gce;
- int insert, skip, selected;
-
- ctx->cells++;
+ struct grid_cell tmp_gc, now_gc;
+ struct tty_ctx ttyctx;
+ u_int sx = screen_size_x(s), sy = screen_size_y(s);
+ u_int width = gc->data.width, xx, last;
+ int selected, skip = 1;
- /* Ignore padding. */
+ /* Ignore padding cells. */
if (gc->flags & GRID_FLAG_PADDING)
return;
- width = gc->data.width;
-
- /*
- * If this is a wide character and there is no room on the screen for
- * the entire character, don't print it.
- */
- if (!(s->mode & MODE_WRAP) && (width > 1 &&
- (width > sx || (s->cx != sx && s->cx > sx - width))))
- return;
+ ctx->cells++;
- /*
- * If the width is zero, combine onto the previous character, if
- * there is space.
- */
+ /* If the width is zero, combine onto the previous character. */
if (width == 0) {
if ((gc = screen_write_combine(ctx, &gc->data, &xx)) != 0) {
screen_write_cursormove(ctx, xx, s->cy);
@@ -1049,29 +1131,27 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
return;
}
+ /* If this character doesn't fit, ignore it. */
+ if ((~s->mode & MODE_WRAP) &&
+ width > 1 &&
+ (width > sx || (s->cx != sx && s->cx > sx - width)))
+ return;
+
/* If in insert mode, make space for the cells. */
if (s->mode & MODE_INSERT) {
- if (s->cx <= sx - width) {
- screen_write_flush(ctx);
- xx = sx - s->cx - width;
- grid_view_insert_cells(s->grid, s->cx, s->cy, xx, 8);
- }
- insert = 1;
- } else
- insert = 0;
- skip = !insert;
+ grid_view_insert_cells(s->grid, s->cx, s->cy, width, 8);
+ skip = 0;
+ }
/* Check this will fit on the current line and wrap if not. */
if ((s->mode & MODE_WRAP) && s->cx > sx - width) {
screen_write_linefeed(ctx, 1);
- s->cx = 0; /* carriage return */
+ s->cx = 0;
}
/* Sanity check cursor position. */
if (s->cx > sx - width || s->cy > sy - 1)
return;
-
- /* Initialise the redraw context. */
screen_write_initctx(ctx, &ttyctx);
/* Handle overwriting of UTF-8 characters. */
@@ -1109,6 +1189,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
skip = 0;
else if (gc->data.width != 1)
skip = 0;
+ else if (gc->data.size != 1)
+ skip = 0;
else if (gce->data.data != gc->data.data[0])
skip = 0;
}
@@ -1116,18 +1198,18 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Update the selection the flag and set the cell. */
selected = screen_check_selection(s, s->cx, s->cy);
- if (selected && ~gc->flags & GRID_FLAG_SELECTED) {
- skip = 0;
+ if (selected && (~gc->flags & GRID_FLAG_SELECTED)) {
memcpy(&tmp_gc, gc, sizeof tmp_gc);
tmp_gc.flags |= GRID_FLAG_SELECTED;
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
- } else if (!selected && gc->flags & GRID_FLAG_SELECTED) {
- skip = 0;
+ } else if (!selected && (gc->flags & GRID_FLAG_SELECTED)) {
memcpy(&tmp_gc, gc, sizeof tmp_gc);
tmp_gc.flags &= ~GRID_FLAG_SELECTED;
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
} else if (!skip)
grid_view_set_cell(gd, s->cx, s->cy, gc);
+ if (selected)
+ skip = 0;
/*
* Move the cursor. If not wrapping, stick at the last character and
@@ -1140,34 +1222,21 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
s->cx = sx - last;
/* Create space for character in insert mode. */
- if (insert) {
+ if (s->mode & MODE_INSERT) {
+ screen_write_collect_flush(ctx);
ttyctx.num = width;
tty_write(tty_cmd_insertcharacter, &ttyctx);
}
/* Write to the screen. */
- if (selected) {
- screen_write_flush(ctx);
- screen_select_cell(s, &tmp_gc, gc);
- ttyctx.cell = &tmp_gc;
+ if (!skip) {
+ if (selected) {
+ screen_select_cell(s, &tmp_gc, gc);
+ ttyctx.cell = &tmp_gc;
+ } else
+ ttyctx.cell = gc;
tty_write(tty_cmd_cell, &ttyctx);
ctx->written++;
- } else if (!skip) {
- /*
- * If wp is NULL, we are not updating the terminal and don't
- * care about actually writing the cells (tty_write will just
- * return). So don't even bother allocating the dirty array.
- */
- if (ctx->wp != NULL && s->dirty == NULL) {
- log_debug("%s: allocating %u bits", __func__,
- s->dirtysize);
- s->dirty = bit_alloc(s->dirtysize);
- }
- if (s->dirty != NULL) {
- bit_set(s->dirty, screen_dirty_bit(s,
- ttyctx.ocx, ttyctx.ocy));
- ctx->dirty++;
- }
} else
ctx->skipped++;
}