mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 10:08:47 +00:00
Merge branch 'obsd-master' into master
This commit is contained in:
commit
545a610c6b
3
format.c
3
format.c
@ -3038,9 +3038,6 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
|||||||
format_add_cb(ft, "history_bytes", format_cb_history_bytes);
|
format_add_cb(ft, "history_bytes", format_cb_history_bytes);
|
||||||
format_add_cb(ft, "history_all_bytes", format_cb_history_all_bytes);
|
format_add_cb(ft, "history_all_bytes", format_cb_history_all_bytes);
|
||||||
|
|
||||||
format_add(ft, "pane_written", "%zu", wp->written);
|
|
||||||
format_add(ft, "pane_skipped", "%zu", wp->skipped);
|
|
||||||
|
|
||||||
if (window_pane_index(wp, &idx) != 0)
|
if (window_pane_index(wp, &idx) != 0)
|
||||||
fatalx("index not found");
|
fatalx("index not found");
|
||||||
format_add(ft, "pane_index", "%u", idx);
|
format_add(ft, "pane_index", "%u", idx);
|
||||||
|
321
screen-write.c
321
screen-write.c
@ -23,13 +23,11 @@
|
|||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
|
static struct screen_write_citem *screen_write_collect_trim(
|
||||||
|
struct screen_write_ctx *, u_int, u_int, u_int, int *);
|
||||||
static void screen_write_collect_clear(struct screen_write_ctx *, u_int,
|
static void screen_write_collect_clear(struct screen_write_ctx *, u_int,
|
||||||
u_int);
|
u_int);
|
||||||
static void screen_write_collect_clear_end(struct screen_write_ctx *, u_int,
|
static void screen_write_collect_scroll(struct screen_write_ctx *, u_int);
|
||||||
u_int);
|
|
||||||
static void screen_write_collect_clear_start(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 *, int,
|
static void screen_write_collect_flush(struct screen_write_ctx *, int,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
||||||
@ -38,23 +36,44 @@ static int screen_write_overwrite(struct screen_write_ctx *,
|
|||||||
static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
|
static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
|
||||||
const struct utf8_data *, u_int *);
|
const struct utf8_data *, u_int *);
|
||||||
|
|
||||||
struct screen_write_collect_item {
|
struct screen_write_citem {
|
||||||
u_int x;
|
u_int x;
|
||||||
int wrapped;
|
int wrapped;
|
||||||
|
|
||||||
enum { TEXT, CLEAR_END, CLEAR_START } type;
|
enum { TEXT, CLEAR } type;
|
||||||
u_int used;
|
u_int used;
|
||||||
u_int bg;
|
u_int bg;
|
||||||
|
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
|
|
||||||
TAILQ_ENTRY(screen_write_collect_item) entry;
|
TAILQ_ENTRY(screen_write_citem) entry;
|
||||||
};
|
};
|
||||||
struct screen_write_collect_line {
|
struct screen_write_cline {
|
||||||
u_int bg;
|
|
||||||
char *data;
|
char *data;
|
||||||
TAILQ_HEAD(, screen_write_collect_item) items;
|
TAILQ_HEAD(, screen_write_citem) items;
|
||||||
};
|
};
|
||||||
|
TAILQ_HEAD(, screen_write_citem) screen_write_citem_freelist =
|
||||||
|
TAILQ_HEAD_INITIALIZER(screen_write_citem_freelist);
|
||||||
|
|
||||||
|
static struct screen_write_citem *
|
||||||
|
screen_write_get_citem(void)
|
||||||
|
{
|
||||||
|
struct screen_write_citem *ci;
|
||||||
|
|
||||||
|
ci = TAILQ_FIRST(&screen_write_citem_freelist);
|
||||||
|
if (ci != NULL) {
|
||||||
|
TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
|
||||||
|
memset(ci, 0, sizeof *ci);
|
||||||
|
return (ci);
|
||||||
|
}
|
||||||
|
return (xcalloc(1, sizeof *ci));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
screen_write_free_citem(struct screen_write_citem *ci)
|
||||||
|
{
|
||||||
|
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_write_offset_timer(__unused int fd, __unused short events, void *data)
|
screen_write_offset_timer(__unused int fd, __unused short events, void *data)
|
||||||
@ -125,7 +144,8 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|||||||
* Redraw is already deferred to redraw another pane - redraw
|
* Redraw is already deferred to redraw another pane - redraw
|
||||||
* this one also when that happens.
|
* this one also when that happens.
|
||||||
*/
|
*/
|
||||||
log_debug("adding %%%u to deferred redraw", wp->id);
|
log_debug("%s: adding %%%u to deferred redraw", __func__,
|
||||||
|
wp->id);
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -220,7 +240,7 @@ screen_write_init(struct screen_write_ctx *ctx, struct screen *s)
|
|||||||
|
|
||||||
if (ctx->s->write_list == NULL)
|
if (ctx->s->write_list == NULL)
|
||||||
screen_write_make_list(ctx->s);
|
screen_write_make_list(ctx->s);
|
||||||
ctx->item = xcalloc(1, sizeof *ctx->item);
|
ctx->item = screen_write_get_citem();
|
||||||
|
|
||||||
ctx->scrolled = 0;
|
ctx->scrolled = 0;
|
||||||
ctx->bg = 8;
|
ctx->bg = 8;
|
||||||
@ -278,14 +298,7 @@ screen_write_stop(struct screen_write_ctx *ctx)
|
|||||||
screen_write_collect_end(ctx);
|
screen_write_collect_end(ctx);
|
||||||
screen_write_collect_flush(ctx, 0, __func__);
|
screen_write_collect_flush(ctx, 0, __func__);
|
||||||
|
|
||||||
log_debug("%s: %u cells (%u written, %u skipped)", __func__,
|
screen_write_free_citem(ctx->item);
|
||||||
ctx->cells, ctx->written, ctx->skipped);
|
|
||||||
if (ctx->wp != NULL) {
|
|
||||||
ctx->wp->written += ctx->written;
|
|
||||||
ctx->wp->skipped += ctx->skipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(ctx->item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset screen state. */
|
/* Reset screen state. */
|
||||||
@ -1097,6 +1110,7 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
|
struct screen_write_citem *ci = ctx->item;
|
||||||
|
|
||||||
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
||||||
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
|
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
|
||||||
@ -1105,8 +1119,12 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
||||||
|
|
||||||
screen_write_collect_clear(ctx, s->cy, 1);
|
screen_write_collect_clear(ctx, s->cy, 1);
|
||||||
ctx->s->write_list[s->cy].bg = 1 + bg;
|
ci->x = 0;
|
||||||
ctx->item->used = 0;
|
ci->used = sx;
|
||||||
|
ci->type = CLEAR;
|
||||||
|
ci->bg = bg;
|
||||||
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
||||||
|
ctx->item = screen_write_get_citem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear to end of line from cursor. */
|
/* Clear to end of line from cursor. */
|
||||||
@ -1116,7 +1134,7 @@ screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
struct screen_write_collect_item *ci = ctx->item;
|
struct screen_write_citem *ci = ctx->item, *before;
|
||||||
|
|
||||||
if (s->cx == 0) {
|
if (s->cx == 0) {
|
||||||
screen_write_clearline(ctx, bg);
|
screen_write_clearline(ctx, bg);
|
||||||
@ -1129,12 +1147,16 @@ screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
|
|
||||||
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
|
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
|
||||||
|
|
||||||
screen_write_collect_clear_end(ctx, s->cy, s->cx);
|
before = screen_write_collect_trim(ctx, s->cy, s->cx, sx - s->cx, NULL);
|
||||||
ci->x = s->cx;
|
ci->x = s->cx;
|
||||||
ci->type = CLEAR_END;
|
ci->used = sx - s->cx;
|
||||||
|
ci->type = CLEAR;
|
||||||
ci->bg = bg;
|
ci->bg = bg;
|
||||||
|
if (before == NULL)
|
||||||
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
||||||
ctx->item = xcalloc(1, sizeof *ctx->item);
|
else
|
||||||
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
||||||
|
ctx->item = screen_write_get_citem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear to start of line from cursor. */
|
/* Clear to start of line from cursor. */
|
||||||
@ -1143,7 +1165,7 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
struct screen_write_collect_item *ci = ctx->item;
|
struct screen_write_citem *ci = ctx->item, *before;
|
||||||
|
|
||||||
if (s->cx >= sx - 1) {
|
if (s->cx >= sx - 1) {
|
||||||
screen_write_clearline(ctx, bg);
|
screen_write_clearline(ctx, bg);
|
||||||
@ -1155,12 +1177,16 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
else
|
else
|
||||||
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
|
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
|
||||||
|
|
||||||
screen_write_collect_clear_start(ctx, s->cy, s->cx);
|
before = screen_write_collect_trim(ctx, s->cy, 0, s->cx + 1, NULL);
|
||||||
ci->x = s->cx;
|
ci->x = 0;
|
||||||
ci->type = CLEAR_START;
|
ci->used = s->cx + 1;
|
||||||
|
ci->type = CLEAR;
|
||||||
ci->bg = bg;
|
ci->bg = bg;
|
||||||
|
if (before == NULL)
|
||||||
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
||||||
ctx->item = xcalloc(1, sizeof *ctx->item);
|
else
|
||||||
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
||||||
|
ctx->item = screen_write_get_citem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move cursor to px,py. */
|
/* Move cursor to px,py. */
|
||||||
@ -1182,6 +1208,7 @@ screen_write_cursormove(struct screen_write_ctx *ctx, int px, int py,
|
|||||||
if (py != -1 && (u_int)py > screen_size_y(s) - 1)
|
if (py != -1 && (u_int)py > screen_size_y(s) - 1)
|
||||||
py = screen_size_y(s) - 1;
|
py = screen_size_y(s) - 1;
|
||||||
|
|
||||||
|
log_debug("%s: from %u,%u to %u,%u", __func__, s->cx, s->cy, px, py);
|
||||||
screen_write_set_cursor(ctx, px, py);
|
screen_write_set_cursor(ctx, px, py);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,7 +1277,7 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped, u_int bg)
|
|||||||
|
|
||||||
if (s->cy == s->rlower) {
|
if (s->cy == s->rlower) {
|
||||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
||||||
screen_write_collect_scroll(ctx);
|
screen_write_collect_scroll(ctx, bg);
|
||||||
ctx->scrolled++;
|
ctx->scrolled++;
|
||||||
} else if (s->cy < screen_size_y(s) - 1)
|
} else if (s->cy < screen_size_y(s) - 1)
|
||||||
screen_write_set_cursor(ctx, -1, s->cy + 1);
|
screen_write_set_cursor(ctx, -1, s->cy + 1);
|
||||||
@ -1276,7 +1303,7 @@ screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
|||||||
|
|
||||||
for (i = 0; i < lines; i++) {
|
for (i = 0; i < lines; i++) {
|
||||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
||||||
screen_write_collect_scroll(ctx);
|
screen_write_collect_scroll(ctx, bg);
|
||||||
}
|
}
|
||||||
ctx->scrolled += lines;
|
ctx->scrolled += lines;
|
||||||
}
|
}
|
||||||
@ -1390,107 +1417,114 @@ screen_write_clearhistory(struct screen_write_ctx *ctx)
|
|||||||
grid_clear_history(ctx->s->grid);
|
grid_clear_history(ctx->s->grid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear to start of a collected line. */
|
/* Trim collected items. */
|
||||||
static void
|
static struct screen_write_citem *
|
||||||
screen_write_collect_clear_start(struct screen_write_ctx *ctx, u_int y, u_int x)
|
screen_write_collect_trim(struct screen_write_ctx *ctx, u_int y, u_int x,
|
||||||
|
u_int used, int *wrapped)
|
||||||
{
|
{
|
||||||
struct screen_write_collect_item *ci, *tmp;
|
struct screen_write_cline *cl = &ctx->s->write_list[y];
|
||||||
size_t size = 0;
|
struct screen_write_citem *ci, *ci2, *tmp, *before = NULL;
|
||||||
u_int items = 0;
|
u_int sx = x, ex = x + used - 1;
|
||||||
|
u_int csx, cex;
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&ctx->s->write_list[y].items))
|
if (TAILQ_EMPTY(&cl->items))
|
||||||
return;
|
return (NULL);
|
||||||
TAILQ_FOREACH_SAFE(ci, &ctx->s->write_list[y].items, entry, tmp) {
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||||
switch (ci->type) {
|
csx = ci->x;
|
||||||
case CLEAR_START:
|
cex = ci->x + ci->used - 1;
|
||||||
break;
|
|
||||||
case CLEAR_END:
|
|
||||||
if (ci->x <= x)
|
|
||||||
ci->x = x;
|
|
||||||
continue;
|
|
||||||
case TEXT:
|
|
||||||
if (ci->x > x)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
items++;
|
|
||||||
size += ci->used;
|
|
||||||
TAILQ_REMOVE(&ctx->s->write_list[y].items, ci, entry);
|
|
||||||
free(ci);
|
|
||||||
}
|
|
||||||
ctx->skipped += size;
|
|
||||||
log_debug("%s: dropped %u items (%zu bytes) (line %u)", __func__, items,
|
|
||||||
size, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear to end of a collected line. */
|
/* Item is entirely before. */
|
||||||
static void
|
if (cex < sx) {
|
||||||
screen_write_collect_clear_end(struct screen_write_ctx *ctx, u_int y, u_int x)
|
log_debug("%s: %p %u-%u before %u-%u", __func__, ci,
|
||||||
{
|
csx, cex, sx, ex);
|
||||||
struct screen_write_collect_item *ci, *tmp;
|
continue;
|
||||||
size_t size = 0;
|
}
|
||||||
u_int items = 0;
|
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&ctx->s->write_list[y].items))
|
/* Item is entirely after. */
|
||||||
return;
|
if (csx > ex) {
|
||||||
TAILQ_FOREACH_SAFE(ci, &ctx->s->write_list[y].items, entry, tmp) {
|
log_debug("%s: %p %u-%u after %u-%u", __func__, ci,
|
||||||
switch (ci->type) {
|
csx, cex, sx, ex);
|
||||||
case CLEAR_START:
|
before = ci;
|
||||||
if (ci->x >= x)
|
|
||||||
ci->x = x;
|
|
||||||
continue;
|
|
||||||
case CLEAR_END:
|
|
||||||
break;
|
|
||||||
case TEXT:
|
|
||||||
if (ci->x < x)
|
|
||||||
continue;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
items++;
|
|
||||||
size += ci->used;
|
/* Item is entirely inside. */
|
||||||
TAILQ_REMOVE(&ctx->s->write_list[y].items, ci, entry);
|
if (csx >= sx && cex <= ex) {
|
||||||
free(ci);
|
log_debug("%s: %p %u-%u inside %u-%u", __func__, ci,
|
||||||
|
csx, cex, sx, ex);
|
||||||
|
TAILQ_REMOVE(&cl->items, ci, entry);
|
||||||
|
screen_write_free_citem(ci);
|
||||||
|
if (csx == 0 && ci->wrapped && wrapped != NULL)
|
||||||
|
*wrapped = 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ctx->skipped += size;
|
|
||||||
log_debug("%s: dropped %u items (%zu bytes) (line %u)", __func__, items,
|
/* Item under the start. */
|
||||||
size, y);
|
if (csx < sx && cex >= sx && cex <= ex) {
|
||||||
|
log_debug("%s: %p %u-%u start %u-%u", __func__, ci,
|
||||||
|
csx, cex, sx, ex);
|
||||||
|
ci->used = sx - csx;
|
||||||
|
log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
|
||||||
|
ci->x + ci->used + 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Item covers the end. */
|
||||||
|
if (cex > ex && csx >= sx && csx <= ex) {
|
||||||
|
log_debug("%s: %p %u-%u end %u-%u", __func__, ci,
|
||||||
|
csx, cex, sx, ex);
|
||||||
|
ci->x = ex + 1;
|
||||||
|
ci->used = cex - ex;
|
||||||
|
log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
|
||||||
|
ci->x + ci->used + 1);
|
||||||
|
before = ci;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Item must cover both sides. */
|
||||||
|
log_debug("%s: %p %u-%u under %u-%u", __func__, ci,
|
||||||
|
csx, cex, sx, ex);
|
||||||
|
ci2 = screen_write_get_citem();
|
||||||
|
ci2->type = ci->type;
|
||||||
|
ci2->bg = ci->bg;
|
||||||
|
memcpy(&ci2->gc, &ci->gc, sizeof ci2->gc);
|
||||||
|
TAILQ_INSERT_AFTER(&cl->items, ci, ci2, entry);
|
||||||
|
|
||||||
|
ci->used = sx - csx;
|
||||||
|
ci2->x = ex + 1;
|
||||||
|
ci2->used = cex - ex;
|
||||||
|
|
||||||
|
log_debug("%s: %p now %u-%u (%p) and %u-%u (%p)", __func__, ci,
|
||||||
|
ci->x, ci->x + ci->used - 1, ci, ci2->x,
|
||||||
|
ci2->x + ci2->used - 1, ci2);
|
||||||
|
before = ci2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (before);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear collected lines. */
|
/* 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_write_collect_item *ci, *tmp;
|
struct screen_write_cline *cl;
|
||||||
struct screen_write_collect_line *cl;
|
u_int i;
|
||||||
u_int i, items;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
for (i = y; i < y + n; i++) {
|
for (i = y; i < y + n; i++) {
|
||||||
if (TAILQ_EMPTY(&ctx->s->write_list[i].items))
|
|
||||||
continue;
|
|
||||||
items = 0;
|
|
||||||
size = 0;
|
|
||||||
cl = &ctx->s->write_list[i];
|
cl = &ctx->s->write_list[i];
|
||||||
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
TAILQ_CONCAT(&screen_write_citem_freelist, &cl->items, entry);
|
||||||
items++;
|
|
||||||
size += ci->used;
|
|
||||||
TAILQ_REMOVE(&cl->items, ci, entry);
|
|
||||||
free(ci);
|
|
||||||
}
|
|
||||||
ctx->skipped += size;
|
|
||||||
log_debug("%s: dropped %u items (%zu bytes) (line %u)",
|
|
||||||
__func__, items, size, y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scroll collected lines up. */
|
/* Scroll collected lines up. */
|
||||||
static void
|
static void
|
||||||
screen_write_collect_scroll(struct screen_write_ctx *ctx)
|
screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_collect_line *cl;
|
struct screen_write_cline *cl;
|
||||||
u_int y;
|
u_int y;
|
||||||
char *saved;
|
char *saved;
|
||||||
|
struct screen_write_citem *ci;
|
||||||
|
|
||||||
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);
|
||||||
@ -1500,11 +1534,16 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx)
|
|||||||
for (y = s->rupper; y < s->rlower; y++) {
|
for (y = s->rupper; y < s->rlower; y++) {
|
||||||
cl = &ctx->s->write_list[y + 1];
|
cl = &ctx->s->write_list[y + 1];
|
||||||
TAILQ_CONCAT(&ctx->s->write_list[y].items, &cl->items, entry);
|
TAILQ_CONCAT(&ctx->s->write_list[y].items, &cl->items, entry);
|
||||||
ctx->s->write_list[y].bg = cl->bg;
|
|
||||||
ctx->s->write_list[y].data = cl->data;
|
ctx->s->write_list[y].data = cl->data;
|
||||||
}
|
}
|
||||||
ctx->s->write_list[s->rlower].bg = 1 + 8;
|
|
||||||
ctx->s->write_list[s->rlower].data = saved;
|
ctx->s->write_list[s->rlower].data = saved;
|
||||||
|
|
||||||
|
ci = screen_write_get_citem();
|
||||||
|
ci->x = 0;
|
||||||
|
ci->used = screen_size_x(s);
|
||||||
|
ci->type = CLEAR;
|
||||||
|
ci->bg = bg;
|
||||||
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->rlower].items, ci, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush collected lines. */
|
/* Flush collected lines. */
|
||||||
@ -1513,11 +1552,10 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
const char *from)
|
const char *from)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_collect_item *ci, *tmp;
|
struct screen_write_citem *ci, *tmp;
|
||||||
struct screen_write_collect_line *cl;
|
struct screen_write_cline *cl;
|
||||||
u_int y, cx, cy, items = 0;
|
u_int y, cx, cy, last, items = 0;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
size_t written = 0;
|
|
||||||
|
|
||||||
if (ctx->scrolled != 0) {
|
if (ctx->scrolled != 0) {
|
||||||
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
||||||
@ -1539,22 +1577,18 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
cx = s->cx; cy = s->cy;
|
cx = s->cx; cy = s->cy;
|
||||||
for (y = 0; y < screen_size_y(s); y++) {
|
for (y = 0; y < screen_size_y(s); y++) {
|
||||||
cl = &ctx->s->write_list[y];
|
cl = &ctx->s->write_list[y];
|
||||||
if (cl->bg != 0) {
|
last = UINT_MAX;
|
||||||
screen_write_set_cursor(ctx, 0, y);
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
|
||||||
ttyctx.bg = cl->bg - 1;
|
|
||||||
tty_write(tty_cmd_clearline, &ttyctx);
|
|
||||||
}
|
|
||||||
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||||
|
if (last != UINT_MAX && ci->x <= last) {
|
||||||
|
fatalx("collect list not in order: %u <= %u",
|
||||||
|
ci->x, last);
|
||||||
|
}
|
||||||
screen_write_set_cursor(ctx, ci->x, y);
|
screen_write_set_cursor(ctx, ci->x, y);
|
||||||
if (ci->type == CLEAR_END) {
|
if (ci->type == CLEAR) {
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
screen_write_initctx(ctx, &ttyctx, 1);
|
||||||
ttyctx.bg = ci->bg;
|
ttyctx.bg = ci->bg;
|
||||||
tty_write(tty_cmd_clearendofline, &ttyctx);
|
ttyctx.num = ci->used;
|
||||||
} else if (ci->type == CLEAR_START) {
|
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
|
||||||
ttyctx.bg = ci->bg;
|
|
||||||
tty_write(tty_cmd_clearstartofline, &ttyctx);
|
|
||||||
} else {
|
} else {
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.cell = &ci->gc;
|
ttyctx.cell = &ci->gc;
|
||||||
@ -1563,20 +1597,16 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
ttyctx.num = ci->used;
|
ttyctx.num = ci->used;
|
||||||
tty_write(tty_cmd_cells, &ttyctx);
|
tty_write(tty_cmd_cells, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
items++;
|
items++;
|
||||||
written += ci->used;
|
|
||||||
|
|
||||||
TAILQ_REMOVE(&cl->items, ci, entry);
|
TAILQ_REMOVE(&cl->items, ci, entry);
|
||||||
free(ci);
|
screen_write_free_citem(ci);
|
||||||
|
last = ci->x;
|
||||||
}
|
}
|
||||||
cl->bg = 0;
|
|
||||||
}
|
}
|
||||||
s->cx = cx; s->cy = cy;
|
s->cx = cx; s->cy = cy;
|
||||||
|
|
||||||
log_debug("%s: flushed %u items (%zu bytes) (%s)", __func__, items,
|
log_debug("%s: flushed %u items (%s)", __func__, items, from);
|
||||||
written, from);
|
|
||||||
ctx->written += written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish and store collected cells. */
|
/* Finish and store collected cells. */
|
||||||
@ -1584,17 +1614,24 @@ void
|
|||||||
screen_write_collect_end(struct screen_write_ctx *ctx)
|
screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_collect_item *ci = ctx->item;
|
struct screen_write_citem *ci = ctx->item, *before;
|
||||||
struct screen_write_collect_line *cl = &s->write_list[s->cy];
|
struct screen_write_cline *cl = &s->write_list[s->cy];
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
u_int xx;
|
u_int xx;
|
||||||
|
int wrapped = ci->wrapped;
|
||||||
|
|
||||||
if (ci->used == 0)
|
if (ci->used == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,
|
||||||
|
&wrapped);
|
||||||
ci->x = s->cx;
|
ci->x = s->cx;
|
||||||
|
ci->wrapped = wrapped;
|
||||||
|
if (before == NULL)
|
||||||
TAILQ_INSERT_TAIL(&cl->items, ci, entry);
|
TAILQ_INSERT_TAIL(&cl->items, ci, entry);
|
||||||
ctx->item = xcalloc(1, sizeof *ctx->item);
|
else
|
||||||
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
||||||
|
ctx->item = screen_write_get_citem();
|
||||||
|
|
||||||
log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used,
|
log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used,
|
||||||
(int)ci->used, cl->data + ci->x, s->cx, s->cy);
|
(int)ci->used, cl->data + ci->x, s->cx, s->cy);
|
||||||
@ -1631,7 +1668,7 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
|||||||
const struct grid_cell *gc)
|
const struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_collect_item *ci;
|
struct screen_write_citem *ci;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
int collect;
|
int collect;
|
||||||
|
|
||||||
@ -1658,7 +1695,6 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
|||||||
screen_write_cell(ctx, gc);
|
screen_write_cell(ctx, gc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx->cells++;
|
|
||||||
|
|
||||||
if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
|
if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
|
||||||
screen_write_collect_end(ctx);
|
screen_write_collect_end(ctx);
|
||||||
@ -1695,7 +1731,6 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
/* Ignore padding cells. */
|
/* Ignore padding cells. */
|
||||||
if (gc->flags & GRID_FLAG_PADDING)
|
if (gc->flags & GRID_FLAG_PADDING)
|
||||||
return;
|
return;
|
||||||
ctx->cells++;
|
|
||||||
|
|
||||||
/* If the width is zero, combine onto the previous character. */
|
/* If the width is zero, combine onto the previous character. */
|
||||||
if (width == 0) {
|
if (width == 0) {
|
||||||
@ -1822,9 +1857,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
} else
|
} else
|
||||||
ttyctx.cell = gc;
|
ttyctx.cell = gc;
|
||||||
tty_write(tty_cmd_cell, &ttyctx);
|
tty_write(tty_cmd_cell, &ttyctx);
|
||||||
ctx->written++;
|
}
|
||||||
} else
|
|
||||||
ctx->skipped++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combine a UTF-8 zero-width character onto the previous. */
|
/* Combine a UTF-8 zero-width character onto the previous. */
|
||||||
|
2
tmux.1
2
tmux.1
@ -4823,7 +4823,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_pipe" Ta "" Ta "1 if pane is being piped"
|
.It Li "pane_pipe" Ta "" Ta "1 if pane is being piped"
|
||||||
.It Li "pane_right" Ta "" Ta "Right of pane"
|
.It Li "pane_right" Ta "" Ta "Right of pane"
|
||||||
.It Li "pane_search_string" Ta "" Ta "Last search string in copy mode"
|
.It Li "pane_search_string" Ta "" Ta "Last search string in copy mode"
|
||||||
.It Li "pane_skipped" Ta "" Ta "Bytes skipped as not visible in pane"
|
|
||||||
.It Li "pane_start_command" Ta "" Ta "Command pane started with"
|
.It Li "pane_start_command" Ta "" Ta "Command pane started with"
|
||||||
.It Li "pane_synchronized" Ta "" Ta "1 if pane is synchronized"
|
.It Li "pane_synchronized" Ta "" Ta "1 if pane is synchronized"
|
||||||
.It Li "pane_tabs" Ta "" Ta "Pane tab positions"
|
.It Li "pane_tabs" Ta "" Ta "Pane tab positions"
|
||||||
@ -4831,7 +4830,6 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_top" Ta "" Ta "Top of pane"
|
.It Li "pane_top" Ta "" Ta "Top of pane"
|
||||||
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
|
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
|
||||||
.It Li "pane_width" Ta "" Ta "Width of pane"
|
.It Li "pane_width" Ta "" Ta "Width of pane"
|
||||||
.It Li "pane_written" Ta "" Ta "Bytes written by pane (aside from redrawing)"
|
|
||||||
.It Li "pid" Ta "" Ta "Server PID"
|
.It Li "pid" Ta "" Ta "Server PID"
|
||||||
.It Li "popup_key" Ta "" Ta "Key pressed in popup"
|
.It Li "popup_key" Ta "" Ta "Key pressed in popup"
|
||||||
.It Li "popup_mouse_x" Ta "" Ta "Mouse X position in popup"
|
.It Li "popup_mouse_x" Ta "" Ta "Mouse X position in popup"
|
||||||
|
15
tmux.h
15
tmux.h
@ -56,8 +56,8 @@ struct mouse_event;
|
|||||||
struct options;
|
struct options;
|
||||||
struct options_array_item;
|
struct options_array_item;
|
||||||
struct options_entry;
|
struct options_entry;
|
||||||
struct screen_write_collect_item;
|
struct screen_write_citem;
|
||||||
struct screen_write_collect_line;
|
struct screen_write_cline;
|
||||||
struct screen_write_ctx;
|
struct screen_write_ctx;
|
||||||
struct session;
|
struct session;
|
||||||
struct tty_ctx;
|
struct tty_ctx;
|
||||||
@ -821,7 +821,7 @@ struct screen {
|
|||||||
bitstr_t *tabs;
|
bitstr_t *tabs;
|
||||||
struct screen_sel *sel;
|
struct screen_sel *sel;
|
||||||
|
|
||||||
struct screen_write_collect_line *write_list;
|
struct screen_write_cline *write_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Screen write context. */
|
/* Screen write context. */
|
||||||
@ -837,13 +837,9 @@ struct screen_write_ctx {
|
|||||||
screen_write_init_ctx_cb init_ctx_cb;
|
screen_write_init_ctx_cb init_ctx_cb;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
struct screen_write_collect_item *item;
|
struct screen_write_citem *item;
|
||||||
u_int scrolled;
|
u_int scrolled;
|
||||||
u_int bg;
|
u_int bg;
|
||||||
|
|
||||||
u_int cells;
|
|
||||||
u_int written;
|
|
||||||
u_int skipped;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Screen redraw context. */
|
/* Screen redraw context. */
|
||||||
@ -1002,9 +998,6 @@ struct window_pane {
|
|||||||
char *searchstr;
|
char *searchstr;
|
||||||
int searchregex;
|
int searchregex;
|
||||||
|
|
||||||
size_t written;
|
|
||||||
size_t skipped;
|
|
||||||
|
|
||||||
int border_gc_set;
|
int border_gc_set;
|
||||||
struct grid_cell border_gc;
|
struct grid_cell border_gc;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user