version 1.162, 2020/04/16 13:35:24 |
version 1.163, 2020/04/16 16:13:56 |
|
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
static void screen_write_initctx(struct screen_write_ctx *, |
|
struct tty_ctx *); |
|
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_scroll(struct screen_write_ctx *); |
static void screen_write_collect_scroll(struct screen_write_ctx *); |
|
|
evtimer_add(&w->offset_timer, &tv); |
evtimer_add(&w->offset_timer, &tv); |
} |
} |
|
|
|
/* Set up context for TTY command. */ |
|
static void |
|
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, |
|
int sync) |
|
{ |
|
struct screen *s = ctx->s; |
|
|
|
memset(ttyctx, 0, sizeof *ttyctx); |
|
|
|
ttyctx->wp = ctx->wp; |
|
|
|
ttyctx->ocx = s->cx; |
|
ttyctx->ocy = s->cy; |
|
|
|
ttyctx->orlower = s->rlower; |
|
ttyctx->orupper = s->rupper; |
|
|
|
if (sync && !ctx->sync && ttyctx->wp != NULL) { |
|
log_debug("%s: starting sync", __func__); |
|
tty_write(tty_cmd_syncstart, ttyctx); |
|
ctx->sync = 1; |
|
} |
|
} |
|
|
/* 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) |
{ |
{ |
struct tty_ctx ttyctx; |
u_int y; |
u_int y; |
|
|
|
memset(ctx, 0, sizeof *ctx); |
memset(ctx, 0, sizeof *ctx); |
|
|
|
|
screen_size_y(ctx->s)); |
screen_size_y(ctx->s)); |
} |
} |
} |
} |
|
|
screen_write_initctx(ctx, &ttyctx); |
|
tty_write(tty_cmd_syncstart, &ttyctx); |
|
} |
} |
|
|
/* Finish writing. */ |
/* Finish writing. */ |
|
|
log_debug("%s: %u cells (%u written, %u skipped)", __func__, |
log_debug("%s: %u cells (%u written, %u skipped)", __func__, |
ctx->cells, ctx->written, ctx->skipped); |
ctx->cells, ctx->written, ctx->skipped); |
|
|
screen_write_initctx(ctx, &ttyctx); |
if (ctx->sync) { |
tty_write(tty_cmd_syncend, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
|
tty_write(tty_cmd_syncend, &ttyctx); |
|
log_debug("%s: ending sync", __func__); |
|
} |
|
|
free(ctx->item); |
free(ctx->item); |
free(ctx->list); /* flush will have emptied */ |
free(ctx->list); /* flush will have emptied */ |
|
|
} |
} |
} |
} |
|
|
/* Set up context for TTY command. */ |
|
static void |
|
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) |
|
{ |
|
struct screen *s = ctx->s; |
|
|
|
memset(ttyctx, 0, sizeof *ttyctx); |
|
|
|
ttyctx->wp = ctx->wp; |
|
|
|
ttyctx->ocx = s->cx; |
|
ttyctx->ocy = s->cy; |
|
|
|
ttyctx->orlower = s->rlower; |
|
ttyctx->orupper = s->rupper; |
|
} |
|
|
|
/* Set a mode. */ |
/* Set a mode. */ |
void |
void |
screen_write_mode_set(struct screen_write_ctx *ctx, int mode) |
screen_write_mode_set(struct screen_write_ctx *ctx, int mode) |
|
|
s->rupper = 0; |
s->rupper = 0; |
s->rlower = screen_size_y(s) - 1; |
s->rlower = screen_size_y(s) - 1; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
|
|
screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1); |
screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1); |
tty_write(tty_cmd_alignmenttest, &ttyctx); |
tty_write(tty_cmd_alignmenttest, &ttyctx); |
|
|
if (s->cx > screen_size_x(s) - 1) |
if (s->cx > screen_size_x(s) - 1) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); |
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); |
|
|
if (s->cx > screen_size_x(s) - 1) |
if (s->cx > screen_size_x(s) - 1) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); |
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); |
|
|
if (s->cx > screen_size_x(s) - 1) |
if (s->cx > screen_size_x(s) - 1) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg); |
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg); |
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_insert_lines(gd, s->cy, ny, bg); |
grid_view_insert_lines(gd, s->cy, ny, bg); |
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (s->cy < s->rupper || s->cy > s->rlower) |
if (s->cy < s->rupper || s->cy > s->rlower) |
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_delete_lines(gd, s->cy, ny, bg); |
grid_view_delete_lines(gd, s->cy, ny, bg); |
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (s->cy < s->rupper || s->cy > s->rlower) |
if (s->cy < s->rupper || s->cy > s->rlower) |
|
|
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg)) |
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg)) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg); |
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg); |
|
|
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && COLOUR_DEFAULT(bg))) |
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && COLOUR_DEFAULT(bg))) |
return; |
return; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = 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); |
|
|
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int sx = screen_size_x(s); |
u_int sx = screen_size_x(s); |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (s->cx > sx - 1) |
if (s->cx > sx - 1) |
|
|
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (s->cy == s->rupper) |
if (s->cy == s->rupper) |
|
|
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int i; |
u_int i; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (lines == 0) |
if (lines == 0) |
|
|
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int sx = screen_size_x(s), sy = screen_size_y(s); |
u_int sx = screen_size_x(s), sy = screen_size_y(s); |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
/* Scroll into history if it is enabled and clearing entire screen. */ |
/* Scroll into history if it is enabled and clearing entire screen. */ |
|
|
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int sx = screen_size_x(s); |
u_int sx = screen_size_x(s); |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
if (s->cy > 0) |
if (s->cy > 0) |
|
|
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
u_int sx = screen_size_x(s), sy = screen_size_y(s); |
u_int sx = screen_size_x(s), sy = screen_size_y(s); |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.bg = bg; |
ttyctx.bg = bg; |
|
|
/* Scroll into history if it is enabled. */ |
/* Scroll into history if it is enabled. */ |
|
|
if (ctx->scrolled > s->rlower - s->rupper + 1) |
if (ctx->scrolled > s->rlower - s->rupper + 1) |
ctx->scrolled = s->rlower - s->rupper + 1; |
ctx->scrolled = s->rlower - s->rupper + 1; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 1); |
ttyctx.num = ctx->scrolled; |
ttyctx.num = ctx->scrolled; |
ttyctx.bg = ctx->bg; |
ttyctx.bg = ctx->bg; |
tty_write(tty_cmd_scrollup, &ttyctx); |
tty_write(tty_cmd_scrollup, &ttyctx); |
|
|
for (y = 0; y < screen_size_y(s); y++) { |
for (y = 0; y < screen_size_y(s); y++) { |
TAILQ_FOREACH_SAFE(ci, &ctx->list[y].items, entry, tmp) { |
TAILQ_FOREACH_SAFE(ci, &ctx->list[y].items, entry, tmp) { |
screen_write_set_cursor(ctx, ci->x, y); |
screen_write_set_cursor(ctx, ci->x, y); |
screen_write_initctx(ctx, &ttyctx); |
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 = ci->data; |
|
|
if ((gc = screen_write_combine(ctx, &gc->data, &xx)) != 0) { |
if ((gc = screen_write_combine(ctx, &gc->data, &xx)) != 0) { |
cx = s->cx; cy = s->cy; |
cx = s->cx; cy = s->cy; |
screen_write_set_cursor(ctx, xx, s->cy); |
screen_write_set_cursor(ctx, xx, s->cy); |
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.cell = gc; |
ttyctx.cell = gc; |
tty_write(tty_cmd_cell, &ttyctx); |
tty_write(tty_cmd_cell, &ttyctx); |
s->cx = cx; s->cy = cy; |
s->cx = cx; s->cy = cy; |
|
|
/* Sanity check cursor position. */ |
/* Sanity check cursor position. */ |
if (s->cx > sx - width || s->cy > sy - 1) |
if (s->cx > sx - width || s->cy > sy - 1) |
return; |
return; |
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
|
|
/* Handle overwriting of UTF-8 characters. */ |
/* Handle overwriting of UTF-8 characters. */ |
gl = grid_get_line(s->grid, s->grid->hsize + s->cy); |
gl = grid_get_line(s->grid, s->grid->hsize + s->cy); |
|
|
{ |
{ |
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.ptr = str; |
ttyctx.ptr = str; |
ttyctx.num = len; |
ttyctx.num = len; |
|
|
|
|
{ |
{ |
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
|
|
screen_write_initctx(ctx, &ttyctx); |
screen_write_initctx(ctx, &ttyctx, 0); |
ttyctx.ptr = str; |
ttyctx.ptr = str; |
ttyctx.num = len; |
ttyctx.num = len; |
|
|