mirror of
https://github.com/tmux/tmux.git
synced 2025-01-15 05:09:04 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
130b77edc7
@ -45,6 +45,15 @@ grid_view_set_cell(struct grid *gd, u_int px, u_int py,
|
|||||||
grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
|
grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set cells. */
|
||||||
|
void
|
||||||
|
grid_view_set_cells(struct grid *gd, u_int px, u_int py,
|
||||||
|
const struct grid_cell *gc, const char *s, size_t slen)
|
||||||
|
{
|
||||||
|
grid_set_cells(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc, s,
|
||||||
|
slen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear into history. */
|
/* Clear into history. */
|
||||||
void
|
void
|
||||||
grid_view_clear_history(struct grid *gd, u_int bg)
|
grid_view_clear_history(struct grid *gd, u_int bg)
|
||||||
|
66
grid.c
66
grid.c
@ -59,6 +59,25 @@ static size_t grid_string_cells_bg(const struct grid_cell *, int *);
|
|||||||
static void grid_string_cells_code(const struct grid_cell *,
|
static void grid_string_cells_code(const struct grid_cell *,
|
||||||
const struct grid_cell *, char *, size_t, int);
|
const struct grid_cell *, char *, size_t, int);
|
||||||
|
|
||||||
|
/* Store cell in entry. */
|
||||||
|
static void
|
||||||
|
grid_store_cell(struct grid_cell_entry *gce, const struct grid_cell *gc,
|
||||||
|
u_char c)
|
||||||
|
{
|
||||||
|
gce->flags = gc->flags;
|
||||||
|
|
||||||
|
gce->data.fg = gc->fg & 0xff;
|
||||||
|
if (gc->fg & COLOUR_FLAG_256)
|
||||||
|
gce->flags |= GRID_FLAG_FG256;
|
||||||
|
|
||||||
|
gce->data.bg = gc->bg & 0xff;
|
||||||
|
if (gc->bg & COLOUR_FLAG_256)
|
||||||
|
gce->flags |= GRID_FLAG_BG256;
|
||||||
|
|
||||||
|
gce->data.attr = gc->attr;
|
||||||
|
gce->data.data = c;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set cell as extended. */
|
/* Set cell as extended. */
|
||||||
static struct grid_cell *
|
static struct grid_cell *
|
||||||
grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
|
grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
|
||||||
@ -371,11 +390,10 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
|
|||||||
grid_expand_line(gd, py, px + 1, 8);
|
grid_expand_line(gd, py, px + 1, 8);
|
||||||
|
|
||||||
gl = &gd->linedata[py];
|
gl = &gd->linedata[py];
|
||||||
gce = &gl->celldata[px];
|
|
||||||
|
|
||||||
if (px + 1 > gl->cellused)
|
if (px + 1 > gl->cellused)
|
||||||
gl->cellused = px + 1;
|
gl->cellused = px + 1;
|
||||||
|
|
||||||
|
gce = &gl->celldata[px];
|
||||||
extended = (gce->flags & GRID_FLAG_EXTENDED);
|
extended = (gce->flags & GRID_FLAG_EXTENDED);
|
||||||
if (!extended && (gc->data.size != 1 || gc->data.width != 1))
|
if (!extended && (gc->data.size != 1 || gc->data.width != 1))
|
||||||
extended = 1;
|
extended = 1;
|
||||||
@ -383,20 +401,40 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
|
|||||||
extended = 1;
|
extended = 1;
|
||||||
if (!extended && (gc->bg & COLOUR_FLAG_RGB))
|
if (!extended && (gc->bg & COLOUR_FLAG_RGB))
|
||||||
extended = 1;
|
extended = 1;
|
||||||
if (extended) {
|
if (extended)
|
||||||
grid_extended_cell(gl, gce, gc);
|
grid_extended_cell(gl, gce, gc);
|
||||||
return;
|
else
|
||||||
}
|
grid_store_cell(gce, gc, gc->data.data[0]);
|
||||||
|
}
|
||||||
|
|
||||||
gce->flags = gc->flags;
|
/* Set cells at relative position. */
|
||||||
gce->data.attr = gc->attr;
|
void
|
||||||
gce->data.fg = gc->fg & 0xff;
|
grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
|
||||||
if (gc->fg & COLOUR_FLAG_256)
|
const char *s, size_t slen)
|
||||||
gce->flags |= GRID_FLAG_FG256;
|
{
|
||||||
gce->data.bg = gc->bg & 0xff;
|
struct grid_line *gl;
|
||||||
if (gc->bg & COLOUR_FLAG_256)
|
struct grid_cell_entry *gce;
|
||||||
gce->flags |= GRID_FLAG_BG256;
|
struct grid_cell *gcp;
|
||||||
gce->data.data = gc->data.data[0];
|
u_int i;
|
||||||
|
|
||||||
|
if (grid_check_y(gd, py) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grid_expand_line(gd, py, px + slen, 8);
|
||||||
|
|
||||||
|
gl = &gd->linedata[py];
|
||||||
|
if (px + slen > gl->cellused)
|
||||||
|
gl->cellused = px + slen;
|
||||||
|
|
||||||
|
for (i = 0; i < slen; i++) {
|
||||||
|
gce = &gl->celldata[px + i];
|
||||||
|
if (gce->flags & GRID_FLAG_EXTENDED) {
|
||||||
|
gcp = &gl->extddata[gce->offset];
|
||||||
|
memcpy(gcp, gc, sizeof *gcp);
|
||||||
|
utf8_set(&gcp->data, s[i]);
|
||||||
|
} else
|
||||||
|
grid_store_cell(gce, gc, s[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear area. */
|
/* Clear area. */
|
||||||
|
18
input.c
18
input.c
@ -222,6 +222,7 @@ enum input_csi_type {
|
|||||||
INPUT_CSI_SGR,
|
INPUT_CSI_SGR,
|
||||||
INPUT_CSI_SM,
|
INPUT_CSI_SM,
|
||||||
INPUT_CSI_SM_PRIVATE,
|
INPUT_CSI_SM_PRIVATE,
|
||||||
|
INPUT_CSI_SU,
|
||||||
INPUT_CSI_TBC,
|
INPUT_CSI_TBC,
|
||||||
INPUT_CSI_VPA,
|
INPUT_CSI_VPA,
|
||||||
INPUT_CSI_WINOPS,
|
INPUT_CSI_WINOPS,
|
||||||
@ -243,6 +244,7 @@ static const struct input_table_entry input_csi_table[] = {
|
|||||||
{ 'L', "", INPUT_CSI_IL },
|
{ 'L', "", INPUT_CSI_IL },
|
||||||
{ 'M', "", INPUT_CSI_DL },
|
{ 'M', "", INPUT_CSI_DL },
|
||||||
{ 'P', "", INPUT_CSI_DCH },
|
{ 'P', "", INPUT_CSI_DCH },
|
||||||
|
{ 'S', "", INPUT_CSI_SU },
|
||||||
{ 'X', "", INPUT_CSI_ECH },
|
{ 'X', "", INPUT_CSI_ECH },
|
||||||
{ 'Z', "", INPUT_CSI_CBT },
|
{ 'Z', "", INPUT_CSI_CBT },
|
||||||
{ 'c', "", INPUT_CSI_DA },
|
{ 'c', "", INPUT_CSI_DA },
|
||||||
@ -895,6 +897,16 @@ input_parse(struct window_pane *wp)
|
|||||||
fatalx("no transition from state");
|
fatalx("no transition from state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Any state except print stops the current collection. This is
|
||||||
|
* an optimization to avoid checking if the attributes have
|
||||||
|
* changed for every character. It will stop unnecessarily for
|
||||||
|
* sequences that don't make a terminal change, but they should
|
||||||
|
* be the minority.
|
||||||
|
*/
|
||||||
|
if (itr->handler != input_print)
|
||||||
|
screen_write_collect_end(&ictx->ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Execute the handler, if any. Don't switch state if it
|
* Execute the handler, if any. Don't switch state if it
|
||||||
* returns non-zero.
|
* returns non-zero.
|
||||||
@ -920,7 +932,6 @@ input_parse(struct window_pane *wp)
|
|||||||
/* Split the parameter list (if any). */
|
/* Split the parameter list (if any). */
|
||||||
static int
|
static int
|
||||||
input_split(struct input_ctx *ictx)
|
input_split(struct input_ctx *ictx)
|
||||||
|
|
||||||
{
|
{
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
char *ptr, *out;
|
char *ptr, *out;
|
||||||
@ -1021,7 +1032,7 @@ input_print(struct input_ctx *ictx)
|
|||||||
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
|
||||||
utf8_set(&ictx->cell.cell.data, ictx->ch);
|
utf8_set(&ictx->cell.cell.data, ictx->ch);
|
||||||
screen_write_cell(&ictx->ctx, &ictx->cell.cell);
|
screen_write_collect_add(&ictx->ctx, &ictx->cell.cell);
|
||||||
|
|
||||||
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
|
||||||
@ -1404,6 +1415,9 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
case INPUT_CSI_SM_PRIVATE:
|
case INPUT_CSI_SM_PRIVATE:
|
||||||
input_csi_dispatch_sm_private(ictx);
|
input_csi_dispatch_sm_private(ictx);
|
||||||
break;
|
break;
|
||||||
|
case INPUT_CSI_SU:
|
||||||
|
screen_write_scrollup(sctx, input_get(ictx, 0, 1, 1));
|
||||||
|
break;
|
||||||
case INPUT_CSI_TBC:
|
case INPUT_CSI_TBC:
|
||||||
switch (input_get(ictx, 0, 0, 0)) {
|
switch (input_get(ictx, 0, 0, 0)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -423,6 +423,9 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
|
|||||||
if (status_at_line(c) == 0)
|
if (status_at_line(c) == 0)
|
||||||
yoff++;
|
yoff++;
|
||||||
|
|
||||||
|
log_debug("%s: redraw pane %%%u (at %u,%u)", c->tty.path, wp->id,
|
||||||
|
wp->xoff, yoff);
|
||||||
|
|
||||||
for (i = 0; i < wp->sy; i++)
|
for (i = 0; i < wp->sy; i++)
|
||||||
tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
|
tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
|
||||||
tty_reset(&c->tty);
|
tty_reset(&c->tty);
|
||||||
|
554
screen-write.c
554
screen-write.c
@ -25,7 +25,10 @@
|
|||||||
|
|
||||||
static void screen_write_initctx(struct screen_write_ctx *,
|
static void screen_write_initctx(struct screen_write_ctx *,
|
||||||
struct tty_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 *,
|
static int screen_write_overwrite(struct screen_write_ctx *,
|
||||||
struct grid_cell *, u_int);
|
struct grid_cell *, u_int);
|
||||||
@ -36,24 +39,29 @@ static const struct grid_cell screen_write_pad_cell = {
|
|||||||
GRID_FLAG_PADDING, 0, 8, 8, { { 0 }, 0, 0, 0 }
|
GRID_FLAG_PADDING, 0, 8, 8, { { 0 }, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define screen_dirty_bit(s, x, y) (((y) * screen_size_x(s)) + (x))
|
struct screen_write_collect_item {
|
||||||
#define screen_dirty_clear(s, sx, sy, ex, ey) \
|
u_int x;
|
||||||
do { \
|
|
||||||
if (s->dirty != NULL) { \
|
u_int used;
|
||||||
bit_nclear(s->dirty, \
|
char data[256];
|
||||||
screen_dirty_bit(s, sx, sy), \
|
|
||||||
screen_dirty_bit(s, ex, ey)); \
|
struct grid_cell gc;
|
||||||
} \
|
|
||||||
} while (0)
|
TAILQ_ENTRY (screen_write_collect_item) entry;
|
||||||
|
};
|
||||||
|
struct screen_write_collect_line {
|
||||||
|
TAILQ_HEAD(, screen_write_collect_item) items;
|
||||||
|
};
|
||||||
|
|
||||||
/* 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 size;
|
char tmp[16];
|
||||||
char tmp[16];
|
u_int y;
|
||||||
const char *cp = tmp;
|
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
|
||||||
ctx->wp = wp;
|
ctx->wp = wp;
|
||||||
if (wp != NULL && s == NULL)
|
if (wp != NULL && s == NULL)
|
||||||
@ -61,77 +69,29 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
|||||||
else
|
else
|
||||||
ctx->s = s;
|
ctx->s = s;
|
||||||
|
|
||||||
size = screen_size_x(ctx->s) * screen_size_y(ctx->s);
|
ctx->list = xcalloc(screen_size_y(ctx->s), sizeof *ctx->list);
|
||||||
if (ctx->s->dirtysize != size) {
|
for (y = 0; y < screen_size_y(ctx->s); y++)
|
||||||
free(ctx->s->dirty);
|
TAILQ_INIT(&ctx->list[y].items);
|
||||||
ctx->s->dirty = NULL;
|
ctx->item = xcalloc(1, sizeof *ctx->item);
|
||||||
ctx->s->dirtysize = size;
|
|
||||||
}
|
|
||||||
ctx->dirty = 0;
|
|
||||||
|
|
||||||
ctx->cells = ctx->written = ctx->skipped = 0;
|
if (wp != NULL)
|
||||||
|
|
||||||
if (wp == NULL)
|
|
||||||
cp = "no pane";
|
|
||||||
else
|
|
||||||
snprintf(tmp, sizeof tmp, "pane %%%u", wp->id);
|
snprintf(tmp, sizeof tmp, "pane %%%u", wp->id);
|
||||||
log_debug("%s: size %ux%u, %s", __func__, screen_size_x(ctx->s),
|
log_debug("%s: size %ux%u, %s", __func__, screen_size_x(ctx->s),
|
||||||
screen_size_y(ctx->s), cp);
|
screen_size_y(ctx->s), wp == NULL ? "no pane" : tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish writing. */
|
/* Finish writing. */
|
||||||
void
|
void
|
||||||
screen_write_stop(struct screen_write_ctx *ctx)
|
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__,
|
log_debug("%s: %u cells (%u written, %u skipped)", __func__,
|
||||||
ctx->written, ctx->cells, ctx->cells - ctx->written, ctx->skipped);
|
ctx->cells, ctx->written, ctx->skipped);
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush outstanding cell writes. */
|
free(ctx->item);
|
||||||
static void
|
free(ctx->list); /* flush will have emptied */
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset screen state. */
|
/* Reset screen state. */
|
||||||
@ -566,12 +526,9 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
|
|||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
u_int xx, yy;
|
u_int xx, yy;
|
||||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
|
|
||||||
|
|
||||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
utf8_set(&gc.data, 'E');
|
utf8_set(&gc.data, 'E');
|
||||||
|
|
||||||
@ -586,6 +543,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
|
|||||||
s->rupper = 0;
|
s->rupper = 0;
|
||||||
s->rlower = screen_size_y(s) - 1;
|
s->rlower = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,14 +562,16 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
|||||||
if (nx == 0)
|
if (nx == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
if (s->cx <= screen_size_x(s) - 1)
|
|
||||||
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);
|
|
||||||
|
|
||||||
ttyctx.num = nx;
|
|
||||||
ttyctx.bg = bg;
|
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);
|
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,14 +590,16 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
|||||||
if (nx == 0)
|
if (nx == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
if (s->cx <= screen_size_x(s) - 1)
|
|
||||||
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg);
|
|
||||||
|
|
||||||
ttyctx.num = nx;
|
|
||||||
ttyctx.bg = bg;
|
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);
|
tty_write(tty_cmd_deletecharacter, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,14 +618,14 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx)
|
|||||||
if (nx == 0)
|
if (nx == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
|
|
||||||
if (s->cx <= screen_size_x(s) - 1) {
|
|
||||||
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);
|
|
||||||
} else
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
|
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, 8);
|
||||||
|
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
ttyctx.num = nx;
|
ttyctx.num = nx;
|
||||||
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
||||||
}
|
}
|
||||||
@ -673,6 +635,7 @@ void
|
|||||||
screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
@ -684,13 +647,13 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
|||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
grid_view_insert_lines(s->grid, s->cy, ny, bg);
|
|
||||||
|
|
||||||
ttyctx.num = ny;
|
|
||||||
ttyctx.bg = bg;
|
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);
|
tty_write(tty_cmd_insertline, &ttyctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -700,18 +663,16 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
|||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
if (s->cy < s->rupper || s->cy > s->rlower)
|
if (s->cy < s->rupper || s->cy > s->rlower)
|
||||||
grid_view_insert_lines(s->grid, s->cy, ny, bg);
|
grid_view_insert_lines(gd, s->cy, ny, bg);
|
||||||
else {
|
else
|
||||||
grid_view_insert_lines_region(s->grid, s->rlower, s->cy, ny,
|
grid_view_insert_lines_region(gd, s->rlower, s->cy, ny, bg);
|
||||||
bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
ttyctx.num = ny;
|
ttyctx.num = ny;
|
||||||
ttyctx.bg = bg;
|
|
||||||
tty_write(tty_cmd_insertline, &ttyctx);
|
tty_write(tty_cmd_insertline, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,6 +681,7 @@ void
|
|||||||
screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
@ -731,13 +693,13 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
|||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
grid_view_delete_lines(s->grid, s->cy, ny, bg);
|
|
||||||
|
|
||||||
ttyctx.num = ny;
|
|
||||||
ttyctx.bg = bg;
|
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);
|
tty_write(tty_cmd_deleteline, &ttyctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -747,18 +709,16 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
|||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_flush(ctx);
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
if (s->cy < s->rupper || s->cy > s->rlower)
|
if (s->cy < s->rupper || s->cy > s->rlower)
|
||||||
grid_view_delete_lines(s->grid, s->cy, ny, bg);
|
grid_view_delete_lines(gd, s->cy, ny, bg);
|
||||||
else {
|
else
|
||||||
grid_view_delete_lines_region(s->grid, s->rlower, s->cy, ny,
|
grid_view_delete_lines_region(gd, s->rlower, s->cy, ny, bg);
|
||||||
bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
ttyctx.num = ny;
|
ttyctx.num = ny;
|
||||||
ttyctx.bg = bg;
|
|
||||||
tty_write(tty_cmd_deleteline, &ttyctx);
|
tty_write(tty_cmd_deleteline, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,16 +731,16 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int 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);
|
|
||||||
ttyctx.bg = bg;
|
|
||||||
|
|
||||||
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
||||||
if (gl->cellsize == 0 && bg == 8)
|
if (gl->cellsize == 0 && bg == 8)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
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);
|
||||||
|
|
||||||
|
screen_write_collect_clear(ctx, s->cy, 1);
|
||||||
tty_write(tty_cmd_clearline, &ttyctx);
|
tty_write(tty_cmd_clearline, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,16 +753,19 @@ screen_write_clearendofline(struct screen_write_ctx *ctx, u_int 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);
|
|
||||||
ttyctx.bg = bg;
|
|
||||||
|
|
||||||
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
||||||
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && bg == 8))
|
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && bg == 8))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (s->cx == 0)
|
||||||
|
screen_write_collect_clear(ctx, s->cy, 1);
|
||||||
|
else
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
tty_write(tty_cmd_clearendofline, &ttyctx);
|
tty_write(tty_cmd_clearendofline, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,14 +780,15 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
if (s->cx > sx - 1) {
|
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);
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
||||||
} else {
|
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);
|
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);
|
tty_write(tty_cmd_clearstartofline, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,12 +816,12 @@ screen_write_reverseindex(struct screen_write_ctx *ctx)
|
|||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
if (s->cy == s->rupper) {
|
if (s->cy == s->rupper)
|
||||||
screen_write_flush(ctx);
|
|
||||||
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
|
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
|
||||||
} else if (s->cy > 0)
|
else if (s->cy > 0)
|
||||||
s->cy--;
|
s->cy--;
|
||||||
|
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
tty_write(tty_cmd_reverseindex, &ttyctx);
|
tty_write(tty_cmd_reverseindex, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,6 +839,8 @@ screen_write_scrollregion(struct screen_write_ctx *ctx, u_int rupper,
|
|||||||
if (rupper >= rlower) /* cannot be one line */
|
if (rupper >= rlower) /* cannot be one line */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
|
|
||||||
/* Cursor moves to top-left. */
|
/* Cursor moves to top-left. */
|
||||||
s->cx = 0;
|
s->cx = 0;
|
||||||
s->cy = 0;
|
s->cy = 0;
|
||||||
@ -888,27 +854,41 @@ void
|
|||||||
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
struct grid_line *gl;
|
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);
|
gl = &gd->linedata[gd->hsize + s->cy];
|
||||||
|
|
||||||
gl = &s->grid->linedata[s->grid->hsize + s->cy];
|
|
||||||
if (wrapped)
|
if (wrapped)
|
||||||
gl->flags |= GRID_LINE_WRAPPED;
|
gl->flags |= GRID_LINE_WRAPPED;
|
||||||
else
|
else
|
||||||
gl->flags &= ~GRID_LINE_WRAPPED;
|
gl->flags &= ~GRID_LINE_WRAPPED;
|
||||||
|
|
||||||
if (s->cy == s->rlower) {
|
if (s->cy == s->rlower) {
|
||||||
screen_dirty_clear(s, 0, s->rupper, sx - 1, s->rupper);
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower);
|
||||||
screen_write_flush(ctx);
|
screen_write_collect_scroll(ctx);
|
||||||
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
|
ctx->scrolled++;
|
||||||
} else if (s->cy < sy - 1)
|
} else if (s->cy < screen_size_y(s) - 1)
|
||||||
s->cy++;
|
s->cy++;
|
||||||
|
}
|
||||||
|
|
||||||
ttyctx.num = wrapped;
|
/* Scroll up. */
|
||||||
tty_write(tty_cmd_linefeed, &ttyctx);
|
void
|
||||||
|
screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines)
|
||||||
|
{
|
||||||
|
struct screen *s = ctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if (lines == 0)
|
||||||
|
lines = 1;
|
||||||
|
else if (lines > s->rlower - s->rupper + 1)
|
||||||
|
lines = s->rlower - s->rupper + 1;
|
||||||
|
|
||||||
|
for (i = 0; i < lines; i++) {
|
||||||
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower);
|
||||||
|
screen_write_collect_scroll(ctx);
|
||||||
|
}
|
||||||
|
ctx->scrolled += lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Carriage return (cursor to start of line). */
|
/* Carriage return (cursor to start of line). */
|
||||||
@ -925,6 +905,7 @@ void
|
|||||||
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
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);
|
||||||
|
|
||||||
@ -932,20 +913,16 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
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. */
|
||||||
if (s->cx == 0 && s->cy == 0 && s->grid->flags & GRID_HISTORY) {
|
if (s->cx == 0 && s->cy == 0 && (gd->flags & GRID_HISTORY))
|
||||||
screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
|
grid_view_clear_history(gd, bg);
|
||||||
grid_view_clear_history(s->grid, bg);
|
else {
|
||||||
} else {
|
if (s->cx <= sx - 1)
|
||||||
if (s->cx <= sx - 1) {
|
grid_view_clear(gd, s->cx, s->cy, sx - s->cx, 1, bg);
|
||||||
screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy);
|
grid_view_clear(gd, 0, s->cy + 1, sx, sy - (s->cy + 1), bg);
|
||||||
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1,
|
|
||||||
bg);
|
|
||||||
}
|
|
||||||
screen_dirty_clear(s, 0, s->cy + 1, sx - 1, sy - 1);
|
|
||||||
grid_view_clear(s->grid, 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);
|
tty_write(tty_cmd_clearendofscreen, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,18 +937,15 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
if (s->cy > 0) {
|
if (s->cy > 0)
|
||||||
screen_dirty_clear(s, 0, 0, sx - 1, s->cy);
|
|
||||||
grid_view_clear(s->grid, 0, 0, sx, s->cy, bg);
|
grid_view_clear(s->grid, 0, 0, sx, s->cy, bg);
|
||||||
}
|
if (s->cx > sx - 1)
|
||||||
if (s->cx > sx - 1) {
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, 8);
|
||||||
screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy);
|
else
|
||||||
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, 8);
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
screen_write_collect_clear(ctx, 0, s->cy);
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
tty_write(tty_cmd_clearstartofscreen, &ttyctx);
|
tty_write(tty_cmd_clearstartofscreen, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,14 +960,13 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
screen_dirty_clear(s, 0, 0, sx - 1, sy - 1);
|
|
||||||
|
|
||||||
/* Scroll into history if it is enabled. */
|
/* Scroll into history if it is enabled. */
|
||||||
if (s->grid->flags & GRID_HISTORY)
|
if (s->grid->flags & GRID_HISTORY)
|
||||||
grid_view_clear_history(s->grid, bg);
|
grid_view_clear_history(s->grid, bg);
|
||||||
else
|
else
|
||||||
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
|
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
|
||||||
|
|
||||||
|
screen_write_collect_clear(ctx, 0, sy);
|
||||||
tty_write(tty_cmd_clearscreen, &ttyctx);
|
tty_write(tty_cmd_clearscreen, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,39 +981,177 @@ screen_write_clearhistory(struct screen_write_ctx *ctx)
|
|||||||
gd->hscrolled = gd->hsize = 0;
|
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;
|
||||||
|
|
||||||
|
if (ctx->scrolled != 0) {
|
||||||
|
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
||||||
|
ctx->scrolled, s->rupper, s->rlower);
|
||||||
|
if (ctx->scrolled > s->rlower - s->rupper + 1)
|
||||||
|
ctx->scrolled = s->rlower - s->rupper + 1;
|
||||||
|
|
||||||
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
ttyctx.num = ctx->scrolled;
|
||||||
|
tty_write(tty_cmd_scrollup, &ttyctx);
|
||||||
|
}
|
||||||
|
ctx->scrolled = 0;
|
||||||
|
|
||||||
|
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. */
|
/* Write cell data. */
|
||||||
void
|
void
|
||||||
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid *gd = s->grid;
|
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_line *gl;
|
||||||
struct grid_cell tmp_gc, now_gc;
|
|
||||||
struct grid_cell_entry *gce;
|
struct grid_cell_entry *gce;
|
||||||
int insert, skip, selected;
|
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;
|
||||||
|
|
||||||
ctx->cells++;
|
/* Ignore padding cells. */
|
||||||
|
|
||||||
/* Ignore padding. */
|
|
||||||
if (gc->flags & GRID_FLAG_PADDING)
|
if (gc->flags & GRID_FLAG_PADDING)
|
||||||
return;
|
return;
|
||||||
width = gc->data.width;
|
ctx->cells++;
|
||||||
|
|
||||||
/*
|
/* If the width is zero, combine onto the previous character. */
|
||||||
* 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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the width is zero, combine onto the previous character, if
|
|
||||||
* there is space.
|
|
||||||
*/
|
|
||||||
if (width == 0) {
|
if (width == 0) {
|
||||||
if ((gc = screen_write_combine(ctx, &gc->data, &xx)) != 0) {
|
if ((gc = screen_write_combine(ctx, &gc->data, &xx)) != 0) {
|
||||||
screen_write_cursormove(ctx, xx, s->cy);
|
screen_write_cursormove(ctx, xx, s->cy);
|
||||||
@ -1051,29 +1162,27 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
return;
|
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 in insert mode, make space for the cells. */
|
||||||
if (s->mode & MODE_INSERT) {
|
if (s->mode & MODE_INSERT) {
|
||||||
if (s->cx <= sx - width) {
|
grid_view_insert_cells(s->grid, s->cx, s->cy, width, 8);
|
||||||
screen_write_flush(ctx);
|
skip = 0;
|
||||||
xx = sx - s->cx - width;
|
}
|
||||||
grid_view_insert_cells(s->grid, s->cx, s->cy, xx, 8);
|
|
||||||
}
|
|
||||||
insert = 1;
|
|
||||||
} else
|
|
||||||
insert = 0;
|
|
||||||
skip = !insert;
|
|
||||||
|
|
||||||
/* Check this will fit on the current line and wrap if not. */
|
/* Check this will fit on the current line and wrap if not. */
|
||||||
if ((s->mode & MODE_WRAP) && s->cx > sx - width) {
|
if ((s->mode & MODE_WRAP) && s->cx > sx - width) {
|
||||||
screen_write_linefeed(ctx, 1);
|
screen_write_linefeed(ctx, 1);
|
||||||
s->cx = 0; /* carriage return */
|
s->cx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
/* Initialise the redraw context. */
|
|
||||||
screen_write_initctx(ctx, &ttyctx);
|
screen_write_initctx(ctx, &ttyctx);
|
||||||
|
|
||||||
/* Handle overwriting of UTF-8 characters. */
|
/* Handle overwriting of UTF-8 characters. */
|
||||||
@ -1111,6 +1220,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
skip = 0;
|
skip = 0;
|
||||||
else if (gc->data.width != 1)
|
else if (gc->data.width != 1)
|
||||||
skip = 0;
|
skip = 0;
|
||||||
|
else if (gc->data.size != 1)
|
||||||
|
skip = 0;
|
||||||
else if (gce->data.data != gc->data.data[0])
|
else if (gce->data.data != gc->data.data[0])
|
||||||
skip = 0;
|
skip = 0;
|
||||||
}
|
}
|
||||||
@ -1118,18 +1229,18 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
|
|
||||||
/* Update the selection the flag and set the cell. */
|
/* Update the selection the flag and set the cell. */
|
||||||
selected = screen_check_selection(s, s->cx, s->cy);
|
selected = screen_check_selection(s, s->cx, s->cy);
|
||||||
if (selected && ~gc->flags & GRID_FLAG_SELECTED) {
|
if (selected && (~gc->flags & GRID_FLAG_SELECTED)) {
|
||||||
skip = 0;
|
|
||||||
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
||||||
tmp_gc.flags |= GRID_FLAG_SELECTED;
|
tmp_gc.flags |= GRID_FLAG_SELECTED;
|
||||||
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
||||||
} else if (!selected && gc->flags & GRID_FLAG_SELECTED) {
|
} else if (!selected && (gc->flags & GRID_FLAG_SELECTED)) {
|
||||||
skip = 0;
|
|
||||||
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
||||||
tmp_gc.flags &= ~GRID_FLAG_SELECTED;
|
tmp_gc.flags &= ~GRID_FLAG_SELECTED;
|
||||||
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
||||||
} else if (!skip)
|
} else if (!skip)
|
||||||
grid_view_set_cell(gd, s->cx, s->cy, gc);
|
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
|
* Move the cursor. If not wrapping, stick at the last character and
|
||||||
@ -1142,34 +1253,21 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
s->cx = sx - last;
|
s->cx = sx - last;
|
||||||
|
|
||||||
/* Create space for character in insert mode. */
|
/* Create space for character in insert mode. */
|
||||||
if (insert) {
|
if (s->mode & MODE_INSERT) {
|
||||||
|
screen_write_collect_flush(ctx);
|
||||||
ttyctx.num = width;
|
ttyctx.num = width;
|
||||||
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write to the screen. */
|
/* Write to the screen. */
|
||||||
if (selected) {
|
if (!skip) {
|
||||||
screen_write_flush(ctx);
|
if (selected) {
|
||||||
screen_select_cell(s, &tmp_gc, gc);
|
screen_select_cell(s, &tmp_gc, gc);
|
||||||
ttyctx.cell = &tmp_gc;
|
ttyctx.cell = &tmp_gc;
|
||||||
|
} else
|
||||||
|
ttyctx.cell = gc;
|
||||||
tty_write(tty_cmd_cell, &ttyctx);
|
tty_write(tty_cmd_cell, &ttyctx);
|
||||||
ctx->written++;
|
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
|
} else
|
||||||
ctx->skipped++;
|
ctx->skipped++;
|
||||||
}
|
}
|
||||||
@ -1277,6 +1375,7 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|||||||
return (done);
|
return (done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set external clipboard. */
|
||||||
void
|
void
|
||||||
screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
|
screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
|
||||||
{
|
{
|
||||||
@ -1289,6 +1388,7 @@ screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
|
|||||||
tty_write(tty_cmd_setselection, &ttyctx);
|
tty_write(tty_cmd_setselection, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write unmodified string. */
|
||||||
void
|
void
|
||||||
screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
|
screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
|
||||||
{
|
{
|
||||||
|
6
screen.c
6
screen.c
@ -40,9 +40,6 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
|||||||
s->ccolour = xstrdup("");
|
s->ccolour = xstrdup("");
|
||||||
s->tabs = NULL;
|
s->tabs = NULL;
|
||||||
|
|
||||||
s->dirty = NULL;
|
|
||||||
s->dirtysize = 0;
|
|
||||||
|
|
||||||
screen_reinit(s);
|
screen_reinit(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +66,6 @@ screen_reinit(struct screen *s)
|
|||||||
void
|
void
|
||||||
screen_free(struct screen *s)
|
screen_free(struct screen *s)
|
||||||
{
|
{
|
||||||
free(s->dirty);
|
|
||||||
free(s->tabs);
|
free(s->tabs);
|
||||||
free(s->title);
|
free(s->title);
|
||||||
free(s->ccolour);
|
free(s->ccolour);
|
||||||
@ -358,7 +354,7 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
|
|||||||
xx = sel->sx - 1;
|
xx = sel->sx - 1;
|
||||||
else
|
else
|
||||||
xx = sel->sx;
|
xx = sel->sx;
|
||||||
if (py == sel->sy && px > xx)
|
if (py == sel->sy && (sel->sx == 0 || px > xx))
|
||||||
return (0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
/* starting line == ending line. */
|
/* starting line == ending line. */
|
||||||
|
@ -961,6 +961,7 @@ server_client_loop(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resize timer event. */
|
||||||
static void
|
static void
|
||||||
server_client_resize_event(__unused int fd, __unused short events, void *data)
|
server_client_resize_event(__unused int fd, __unused short events, void *data)
|
||||||
{
|
{
|
||||||
|
23
tmux.h
23
tmux.h
@ -243,6 +243,7 @@ enum tty_code_code {
|
|||||||
TTYC_ICH1, /* insert_character, ic */
|
TTYC_ICH1, /* insert_character, ic */
|
||||||
TTYC_IL, /* parm_insert_line, IL */
|
TTYC_IL, /* parm_insert_line, IL */
|
||||||
TTYC_IL1, /* insert_line, il */
|
TTYC_IL1, /* insert_line, il */
|
||||||
|
TTYC_INDN, /* parm_index, indn */
|
||||||
TTYC_INVIS, /* enter_secure_mode, mk */
|
TTYC_INVIS, /* enter_secure_mode, mk */
|
||||||
TTYC_IS1, /* init_1string, i1 */
|
TTYC_IS1, /* init_1string, i1 */
|
||||||
TTYC_IS2, /* init_2string, i2 */
|
TTYC_IS2, /* init_2string, i2 */
|
||||||
@ -653,17 +654,19 @@ struct screen {
|
|||||||
|
|
||||||
bitstr_t *tabs;
|
bitstr_t *tabs;
|
||||||
|
|
||||||
bitstr_t *dirty;
|
|
||||||
u_int dirtysize;
|
|
||||||
|
|
||||||
struct screen_sel sel;
|
struct screen_sel sel;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Screen write context. */
|
/* Screen write context. */
|
||||||
|
struct screen_write_collect_item;
|
||||||
|
struct screen_write_collect_line;
|
||||||
struct screen_write_ctx {
|
struct screen_write_ctx {
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
u_int dirty;
|
|
||||||
|
struct screen_write_collect_item *item;
|
||||||
|
struct screen_write_collect_line *list;
|
||||||
|
u_int scrolled;
|
||||||
|
|
||||||
u_int cells;
|
u_int cells;
|
||||||
u_int written;
|
u_int written;
|
||||||
@ -1044,7 +1047,7 @@ struct tty {
|
|||||||
|
|
||||||
struct grid_cell cell;
|
struct grid_cell cell;
|
||||||
|
|
||||||
int last_wp;
|
int last_wp;
|
||||||
struct grid_cell last_cell;
|
struct grid_cell last_cell;
|
||||||
|
|
||||||
#define TTY_NOCURSOR 0x1
|
#define TTY_NOCURSOR 0x1
|
||||||
@ -1645,6 +1648,7 @@ void tty_write(void (*)(struct tty *, const struct tty_ctx *),
|
|||||||
struct tty_ctx *);
|
struct tty_ctx *);
|
||||||
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_cell(struct tty *, const struct tty_ctx *);
|
void tty_cmd_cell(struct tty *, const struct tty_ctx *);
|
||||||
|
void tty_cmd_cells(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_clearendofline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_clearendofline(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_clearendofscreen(struct tty *, const struct tty_ctx *);
|
void tty_cmd_clearendofscreen(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_clearline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_clearline(struct tty *, const struct tty_ctx *);
|
||||||
@ -1658,6 +1662,7 @@ void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *);
|
|||||||
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
|
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
|
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
|
||||||
|
void tty_cmd_scrollup(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
|
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
|
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
||||||
@ -1913,6 +1918,8 @@ void grid_clear_history(struct grid *);
|
|||||||
const struct grid_line *grid_peek_line(struct grid *, u_int);
|
const struct grid_line *grid_peek_line(struct grid *, u_int);
|
||||||
void grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
void grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
||||||
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
|
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
|
||||||
|
void grid_set_cells(struct grid *, u_int, u_int, const struct grid_cell *,
|
||||||
|
const char *, size_t);
|
||||||
void grid_clear(struct grid *, u_int, u_int, u_int, u_int, u_int);
|
void grid_clear(struct grid *, u_int, u_int, u_int, u_int, u_int);
|
||||||
void grid_clear_lines(struct grid *, u_int, u_int, u_int);
|
void grid_clear_lines(struct grid *, u_int, u_int, u_int);
|
||||||
void grid_move_lines(struct grid *, u_int, u_int, u_int, u_int);
|
void grid_move_lines(struct grid *, u_int, u_int, u_int, u_int);
|
||||||
@ -1927,6 +1934,8 @@ u_int grid_reflow(struct grid *, struct grid *, u_int);
|
|||||||
void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
||||||
void grid_view_set_cell(struct grid *, u_int, u_int,
|
void grid_view_set_cell(struct grid *, u_int, u_int,
|
||||||
const struct grid_cell *);
|
const struct grid_cell *);
|
||||||
|
void grid_view_set_cells(struct grid *, u_int, u_int,
|
||||||
|
const struct grid_cell *, const char *, size_t);
|
||||||
void grid_view_clear_history(struct grid *, u_int);
|
void grid_view_clear_history(struct grid *, u_int);
|
||||||
void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int, u_int);
|
void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int, u_int);
|
||||||
void grid_view_scroll_region_up(struct grid *, u_int, u_int);
|
void grid_view_scroll_region_up(struct grid *, u_int, u_int);
|
||||||
@ -1980,11 +1989,15 @@ void screen_write_cursormove(struct screen_write_ctx *, u_int, u_int);
|
|||||||
void screen_write_reverseindex(struct screen_write_ctx *);
|
void screen_write_reverseindex(struct screen_write_ctx *);
|
||||||
void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
|
void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
|
||||||
void screen_write_linefeed(struct screen_write_ctx *, int);
|
void screen_write_linefeed(struct screen_write_ctx *, int);
|
||||||
|
void screen_write_scrollup(struct screen_write_ctx *, u_int);
|
||||||
void screen_write_carriagereturn(struct screen_write_ctx *);
|
void screen_write_carriagereturn(struct screen_write_ctx *);
|
||||||
void screen_write_clearendofscreen(struct screen_write_ctx *, u_int);
|
void screen_write_clearendofscreen(struct screen_write_ctx *, u_int);
|
||||||
void screen_write_clearstartofscreen(struct screen_write_ctx *, u_int);
|
void screen_write_clearstartofscreen(struct screen_write_ctx *, u_int);
|
||||||
void screen_write_clearscreen(struct screen_write_ctx *, u_int);
|
void screen_write_clearscreen(struct screen_write_ctx *, u_int);
|
||||||
void screen_write_clearhistory(struct screen_write_ctx *);
|
void screen_write_clearhistory(struct screen_write_ctx *);
|
||||||
|
void screen_write_collect_end(struct screen_write_ctx *);
|
||||||
|
void screen_write_collect_add(struct screen_write_ctx *,
|
||||||
|
const struct grid_cell *);
|
||||||
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
|
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
|
||||||
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
|
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
|
||||||
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
|
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
|
||||||
|
@ -98,6 +98,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
|||||||
[TTYC_ICH1] = { TTYCODE_STRING, "ich1" },
|
[TTYC_ICH1] = { TTYCODE_STRING, "ich1" },
|
||||||
[TTYC_IL] = { TTYCODE_STRING, "il" },
|
[TTYC_IL] = { TTYCODE_STRING, "il" },
|
||||||
[TTYC_IL1] = { TTYCODE_STRING, "il1" },
|
[TTYC_IL1] = { TTYCODE_STRING, "il1" },
|
||||||
|
[TTYC_INDN] = { TTYCODE_STRING, "indn" },
|
||||||
[TTYC_INVIS] = { TTYCODE_STRING, "invis" },
|
[TTYC_INVIS] = { TTYCODE_STRING, "invis" },
|
||||||
[TTYC_IS1] = { TTYCODE_STRING, "is1" },
|
[TTYC_IS1] = { TTYCODE_STRING, "is1" },
|
||||||
[TTYC_IS2] = { TTYCODE_STRING, "is2" },
|
[TTYC_IS2] = { TTYCODE_STRING, "is2" },
|
||||||
|
48
tty.c
48
tty.c
@ -954,14 +954,15 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
|
|
||||||
tty_default_attributes(tty, wp, ctx->bg);
|
tty_default_attributes(tty, wp, ctx->bg);
|
||||||
|
|
||||||
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
|
|
||||||
|
|
||||||
if (ctx->xoff == 0 &&
|
if (ctx->xoff == 0 &&
|
||||||
tty_term_has(tty->term, TTYC_EL1) &&
|
tty_term_has(tty->term, TTYC_EL1) &&
|
||||||
!tty_fake_bce(tty, ctx->wp, ctx->bg))
|
!tty_fake_bce(tty, ctx->wp, ctx->bg)) {
|
||||||
|
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||||
tty_putcode(tty, TTYC_EL1);
|
tty_putcode(tty, TTYC_EL1);
|
||||||
else
|
} else {
|
||||||
|
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
|
||||||
tty_repeat_space(tty, ctx->ocx + 1);
|
tty_repeat_space(tty, ctx->ocx + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1020,6 +1021,32 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
tty_putc(tty, '\n');
|
tty_putc(tty, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ctx->wp;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if ((!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) ||
|
||||||
|
tty_fake_bce(tty, wp, ctx->bg) ||
|
||||||
|
!tty_term_has(tty->term, TTYC_CSR)) {
|
||||||
|
tty_redraw_region(tty, ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_attributes(tty, &grid_default_cell, wp);
|
||||||
|
|
||||||
|
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||||
|
tty_margin_pane(tty, ctx);
|
||||||
|
|
||||||
|
if (ctx->num == 1 || !tty_term_has(tty->term, TTYC_INDN)) {
|
||||||
|
tty_cursor(tty, tty->rright, ctx->yoff + tty->rlower);
|
||||||
|
for (i = 0; i < ctx->num; i++)
|
||||||
|
tty_putc(tty, '\n');
|
||||||
|
} else
|
||||||
|
tty_putcode1(tty, TTYC_INDN, ctx->num);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
@ -1156,8 +1183,6 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
void
|
void
|
||||||
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = ctx->wp;
|
|
||||||
|
|
||||||
if (ctx->xoff + ctx->ocx > tty->sx - 1 && ctx->ocy == ctx->orlower) {
|
if (ctx->xoff + ctx->ocx > tty->sx - 1 && ctx->ocy == ctx->orlower) {
|
||||||
if (tty_pane_full_width(tty, ctx))
|
if (tty_pane_full_width(tty, ctx))
|
||||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||||
@ -1167,7 +1192,16 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
|||||||
|
|
||||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||||
|
|
||||||
tty_cell(tty, ctx->cell, wp);
|
tty_cell(tty, ctx->cell, ctx->wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
|
{
|
||||||
|
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||||
|
|
||||||
|
tty_attributes(tty, ctx->cell, ctx->wp);
|
||||||
|
tty_putn(tty, ctx->ptr, ctx->num, ctx->num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -29,7 +29,7 @@ static void window_copy_command(struct window_pane *, struct client *,
|
|||||||
struct session *, struct args *, struct mouse_event *);
|
struct session *, struct args *, struct mouse_event *);
|
||||||
static struct screen *window_copy_init(struct window_pane *);
|
static struct screen *window_copy_init(struct window_pane *);
|
||||||
static void window_copy_free(struct window_pane *);
|
static void window_copy_free(struct window_pane *);
|
||||||
static void window_copy_pagedown(struct window_pane *, int);
|
static int window_copy_pagedown(struct window_pane *, int);
|
||||||
static void window_copy_next_paragraph(struct window_pane *);
|
static void window_copy_next_paragraph(struct window_pane *);
|
||||||
static void window_copy_previous_paragraph(struct window_pane *);
|
static void window_copy_previous_paragraph(struct window_pane *);
|
||||||
static void window_copy_resize(struct window_pane *, u_int, u_int);
|
static void window_copy_resize(struct window_pane *, u_int, u_int);
|
||||||
@ -380,7 +380,7 @@ window_copy_pageup(struct window_pane *wp, int half_page)
|
|||||||
window_copy_redraw_screen(wp);
|
window_copy_redraw_screen(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
window_copy_pagedown(struct window_pane *wp, int half_page)
|
window_copy_pagedown(struct window_pane *wp, int half_page)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = wp->modedata;
|
struct window_copy_mode_data *data = wp->modedata;
|
||||||
@ -420,13 +420,11 @@ window_copy_pagedown(struct window_pane *wp, int half_page)
|
|||||||
window_copy_cursor_end_of_line(wp);
|
window_copy_cursor_end_of_line(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->scroll_exit && data->oy == 0) {
|
if (data->scroll_exit && data->oy == 0)
|
||||||
window_pane_reset_mode(wp);
|
return (1);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window_copy_update_selection(wp, 1);
|
window_copy_update_selection(wp, 1);
|
||||||
window_copy_redraw_screen(wp);
|
window_copy_redraw_screen(wp);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -621,8 +619,12 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s,
|
|||||||
if (strcmp(command, "end-of-line") == 0)
|
if (strcmp(command, "end-of-line") == 0)
|
||||||
window_copy_cursor_end_of_line(wp);
|
window_copy_cursor_end_of_line(wp);
|
||||||
if (strcmp(command, "halfpage-down") == 0) {
|
if (strcmp(command, "halfpage-down") == 0) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--) {
|
||||||
window_copy_pagedown(wp, 1);
|
if (window_copy_pagedown(wp, 1)) {
|
||||||
|
cancel = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (strcmp(command, "halfpage-up") == 0) {
|
if (strcmp(command, "halfpage-up") == 0) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
@ -715,8 +717,12 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s,
|
|||||||
window_copy_other_end(wp);
|
window_copy_other_end(wp);
|
||||||
}
|
}
|
||||||
if (strcmp(command, "page-down") == 0) {
|
if (strcmp(command, "page-down") == 0) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--) {
|
||||||
window_copy_pagedown(wp, 0);
|
if (window_copy_pagedown(wp, 0)) {
|
||||||
|
cancel = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (strcmp(command, "page-up") == 0) {
|
if (strcmp(command, "page-up") == 0) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
|
Loading…
Reference in New Issue
Block a user