mirror of https://github.com/tmux/tmux.git
There is no point in keeping a bunch of different text buffers for each
line when writing, we only need one as big as the line width - there can't be any more text than that since newer will overwrite older.pull/2195/head
parent
4a93294152
commit
ea5fdd5331
|
@ -48,18 +48,16 @@ struct screen_write_collect_item {
|
||||||
|
|
||||||
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
|
||||||
|
@ -127,13 +125,33 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
@ -142,9 +160,9 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *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;
|
||||||
|
@ -186,7 +204,6 @@ screen_write_stop(struct screen_write_ctx *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
free(ctx->item);
|
free(ctx->item);
|
||||||
free(ctx->list); /* flush will have emptied */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset screen state. */
|
/* Reset screen state. */
|
||||||
|
@ -1319,7 +1336,7 @@ screen_write_collect_clear_end(struct screen_write_ctx *ctx, u_int y, u_int x,
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -1351,15 +1368,19 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx)
|
||||||
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. */
|
||||||
|
@ -1412,7 +1433,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -1423,6 +1444,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1442,14 +1464,13 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||||
|
|
||||||
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--) {
|
||||||
|
@ -1465,7 +1486,8 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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++) {
|
||||||
|
@ -1524,9 +1546,9 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
||||||
|
|
||||||
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. */
|
||||||
|
|
10
screen.c
10
screen.c
|
@ -85,6 +85,8 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
||||||
s->tabs = NULL;
|
s->tabs = NULL;
|
||||||
s->sel = NULL;
|
s->sel = NULL;
|
||||||
|
|
||||||
|
s->write_list = NULL;
|
||||||
|
|
||||||
screen_reinit(s);
|
screen_reinit(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +124,9 @@ screen_free(struct screen *s)
|
||||||
free(s->title);
|
free(s->title);
|
||||||
free(s->ccolour);
|
free(s->ccolour);
|
||||||
|
|
||||||
|
if (s->write_list != NULL)
|
||||||
|
screen_write_free_list(s);
|
||||||
|
|
||||||
if (s->saved_grid != NULL)
|
if (s->saved_grid != NULL)
|
||||||
grid_destroy(s->saved_grid);
|
grid_destroy(s->saved_grid);
|
||||||
grid_destroy(s->grid);
|
grid_destroy(s->grid);
|
||||||
|
@ -222,6 +227,11 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
||||||
{
|
{
|
||||||
u_int tcx, tcy;
|
u_int tcx, tcy;
|
||||||
|
|
||||||
|
if (s->write_list != NULL) {
|
||||||
|
screen_write_free_list(s);
|
||||||
|
s->write_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (cx == NULL)
|
if (cx == NULL)
|
||||||
cx = &tcx;
|
cx = &tcx;
|
||||||
*cx = s->cx;
|
*cx = s->cx;
|
||||||
|
|
4
tmux.h
4
tmux.h
|
@ -769,6 +769,8 @@ struct screen {
|
||||||
|
|
||||||
bitstr_t *tabs;
|
bitstr_t *tabs;
|
||||||
struct screen_sel *sel;
|
struct screen_sel *sel;
|
||||||
|
|
||||||
|
struct screen_write_collect_line *write_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Screen write context. */
|
/* Screen write context. */
|
||||||
|
@ -2380,6 +2382,8 @@ void grid_view_delete_cells(struct grid *, u_int, u_int, u_int, u_int);
|
||||||
char *grid_view_string_cells(struct grid *, u_int, u_int, u_int);
|
char *grid_view_string_cells(struct grid *, u_int, u_int, u_int);
|
||||||
|
|
||||||
/* screen-write.c */
|
/* screen-write.c */
|
||||||
|
void screen_write_make_list(struct screen *);
|
||||||
|
void screen_write_free_list(struct screen *);
|
||||||
void screen_write_start(struct screen_write_ctx *, struct window_pane *,
|
void screen_write_start(struct screen_write_ctx *, struct window_pane *,
|
||||||
struct screen *);
|
struct screen *);
|
||||||
void screen_write_stop(struct screen_write_ctx *);
|
void screen_write_stop(struct screen_write_ctx *);
|
||||||
|
|
Loading…
Reference in New Issue