version 1.169, 2020/04/18 07:19:29 |
version 1.170, 2020/04/18 15:12:28 |
|
|
|
|
enum { TEXT, CLEAR_END, CLEAR_START } type; |
enum { TEXT, CLEAR_END, CLEAR_START } type; |
u_int used; |
u_int used; |
union { |
u_int bg; |
u_int bg; |
|
char data[256]; |
|
}; |
|
|
|
struct grid_cell gc; |
struct grid_cell gc; |
|
|
TAILQ_ENTRY(screen_write_collect_item) entry; |
TAILQ_ENTRY(screen_write_collect_item) entry; |
}; |
}; |
struct screen_write_collect_line { |
struct screen_write_collect_line { |
u_int bg; |
u_int bg; |
TAILQ_HEAD(, screen_write_collect_item) items; |
char *data; |
|
TAILQ_HEAD(, screen_write_collect_item) items; |
}; |
}; |
|
|
static void |
static void |
|
|
} |
} |
} |
} |
|
|
|
/* Make write list. */ |
|
void |
|
screen_write_make_list(struct screen *s) |
|
{ |
|
u_int y; |
|
|
|
s->write_list = xcalloc(screen_size_y(s), sizeof *s->write_list); |
|
for (y = 0; y < screen_size_y(s); y++) |
|
TAILQ_INIT(&s->write_list[y].items); |
|
} |
|
|
|
/* Free write list. */ |
|
void |
|
screen_write_free_list(struct screen *s) |
|
{ |
|
u_int y; |
|
|
|
for (y = 0; y < screen_size_y(s); y++) |
|
free(s->write_list[y].data); |
|
free(s->write_list); |
|
} |
|
|
/* Initialize writing with a window. */ |
/* Initialize writing with a window. */ |
void |
void |
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp, |
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp, |
struct screen *s) |
struct screen *s) |
{ |
{ |
u_int y; |
|
|
|
memset(ctx, 0, sizeof *ctx); |
memset(ctx, 0, sizeof *ctx); |
|
|
ctx->wp = wp; |
ctx->wp = wp; |
|
|
else |
else |
ctx->s = s; |
ctx->s = s; |
|
|
ctx->list = xcalloc(screen_size_y(ctx->s), sizeof *ctx->list); |
if (ctx->s->write_list == NULL) |
for (y = 0; y < screen_size_y(ctx->s); y++) |
screen_write_make_list(ctx->s); |
TAILQ_INIT(&ctx->list[y].items); |
ctx->list = ctx->s->write_list; |
ctx->item = xcalloc(1, sizeof *ctx->item); |
ctx->item = xcalloc(1, sizeof *ctx->item); |
|
|
ctx->scrolled = 0; |
ctx->scrolled = 0; |
|
|
} |
} |
|
|
free(ctx->item); |
free(ctx->item); |
free(ctx->list); /* flush will have emptied */ |
|
} |
} |
|
|
/* Reset screen state. */ |
/* Reset screen state. */ |
|
|
return (redundant); |
return (redundant); |
} |
} |
|
|
/* Clear part of a collected line. */ |
/* Clear collected lines. */ |
static void |
static void |
screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n) |
screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n) |
{ |
{ |
|
|
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct screen_write_collect_line *cl; |
struct screen_write_collect_line *cl; |
u_int y; |
u_int y; |
|
char *saved; |
|
|
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy, |
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy, |
s->rupper, s->rlower); |
s->rupper, s->rlower); |
|
|
screen_write_collect_clear(ctx, s->rupper, 1); |
screen_write_collect_clear(ctx, s->rupper, 1); |
|
saved = ctx->list[s->rupper].data; |
for (y = s->rupper; y < s->rlower; y++) { |
for (y = s->rupper; y < s->rlower; y++) { |
cl = &ctx->list[y + 1]; |
cl = &ctx->list[y + 1]; |
TAILQ_CONCAT(&ctx->list[y].items, &cl->items, entry); |
TAILQ_CONCAT(&ctx->list[y].items, &cl->items, entry); |
|
ctx->list[y].data = cl->data; |
} |
} |
|
ctx->list[s->rlower].data = saved; |
} |
} |
|
|
/* Flush collected lines. */ |
/* Flush collected lines. */ |
|
|
screen_write_initctx(ctx, &ttyctx, 0); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.cell = &ci->gc; |
ttyctx.cell = &ci->gc; |
ttyctx.wrapped = ci->wrapped; |
ttyctx.wrapped = ci->wrapped; |
ttyctx.ptr = ci->data; |
ttyctx.ptr = ctx->list[y].data + ci->x; |
ttyctx.num = ci->used; |
ttyctx.num = ci->used; |
tty_write(tty_cmd_cells, &ttyctx); |
tty_write(tty_cmd_cells, &ttyctx); |
} |
} |
|
|
TAILQ_REMOVE(&ctx->list[y].items, ci, entry); |
TAILQ_REMOVE(&ctx->list[y].items, ci, entry); |
free(ci); |
free(ci); |
} |
} |
|
ctx->list[y].bg = 0; |
} |
} |
s->cx = cx; s->cy = cy; |
s->cx = cx; s->cy = cy; |
|
|
|
|
|
|
if (ci->used == 0) |
if (ci->used == 0) |
return; |
return; |
ci->data[ci->used] = '\0'; |
|
|
|
ci->x = s->cx; |
ci->x = s->cx; |
TAILQ_INSERT_TAIL(&ctx->list[s->cy].items, ci, entry); |
TAILQ_INSERT_TAIL(&ctx->list[s->cy].items, ci, entry); |
ctx->item = xcalloc(1, sizeof *ctx->item); |
ctx->item = xcalloc(1, sizeof *ctx->item); |
|
|
log_debug("%s: %u %s (at %u,%u)", __func__, ci->used, ci->data, s->cx, |
log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used, |
s->cy); |
(int)ci->used, ctx->list[s->cy].data + ci->x, s->cx, s->cy); |
|
|
if (s->cx != 0) { |
if (s->cx != 0) { |
for (xx = s->cx; xx > 0; xx--) { |
for (xx = s->cx; xx > 0; xx--) { |
|
|
} |
} |
} |
} |
|
|
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, ci->data, ci->used); |
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, |
|
ctx->list[s->cy].data + ci->x, ci->used); |
screen_write_set_cursor(ctx, s->cx + ci->used, -1); |
screen_write_set_cursor(ctx, s->cx + ci->used, -1); |
|
|
for (xx = s->cx; xx < screen_size_x(s); xx++) { |
for (xx = s->cx; xx < screen_size_x(s); xx++) { |
|
|
|
|
if (ci->used == 0) |
if (ci->used == 0) |
memcpy(&ci->gc, gc, sizeof ci->gc); |
memcpy(&ci->gc, gc, sizeof ci->gc); |
ci->data[ci->used++] = gc->data.data[0]; |
if (ctx->list[s->cy].data == NULL) |
if (ci->used == (sizeof ci->data) - 1) |
ctx->list[s->cy].data = xmalloc(screen_size_x(ctx->s)); |
screen_write_collect_end(ctx); |
ctx->list[s->cy].data[s->cx + ci->used++] = gc->data.data[0]; |
} |
} |
|
|
/* Write cell data. */ |
/* Write cell data. */ |