summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-display-panes.c8
-rw-r--r--format-draw.c8
-rw-r--r--input.c37
-rw-r--r--menu.c16
-rw-r--r--mode-tree.c2
-rw-r--r--popup.c70
-rw-r--r--screen-redraw.c18
-rw-r--r--screen-write.c167
-rw-r--r--server-client.c19
-rw-r--r--server-fn.c2
-rw-r--r--status.c6
-rw-r--r--tmux.h55
-rw-r--r--tty.c370
-rw-r--r--window-clock.c2
-rw-r--r--window-copy.c24
-rw-r--r--window.c20
16 files changed, 468 insertions, 356 deletions
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 0f12b14b..a13a06ae 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -131,9 +131,7 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
gc.bg = active_colour;
else
gc.bg = colour;
- gc.flags |= GRID_FLAG_NOPALETTE;
-
- tty_attributes(tty, &gc, wp);
+ tty_attributes(tty, &gc, &grid_default_cell, NULL);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
@@ -160,9 +158,7 @@ draw_text:
gc.fg = active_colour;
else
gc.fg = colour;
- gc.flags |= GRID_FLAG_NOPALETTE;
-
- tty_attributes(tty, &gc, wp);
+ tty_attributes(tty, &gc, &grid_default_cell, NULL);
tty_puts(tty, buf);
tty_cursor(tty, 0, 0);
diff --git a/format-draw.c b/format-draw.c
index 4a4fc6bc..3751082e 100644
--- a/format-draw.c
+++ b/format-draw.c
@@ -242,7 +242,7 @@ format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
/* If there is no list left, pass off to the no list function. */
if (width_list == 0) {
- screen_write_start(&ctx, NULL, left);
+ screen_write_start(&ctx, left);
screen_write_fast_copy(&ctx, after, 0, 0, width_after, 1);
screen_write_stop(&ctx);
@@ -334,7 +334,7 @@ format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
/* If there is no list left, pass off to the no list function. */
if (width_list == 0) {
- screen_write_start(&ctx, NULL, centre);
+ screen_write_start(&ctx, centre);
screen_write_fast_copy(&ctx, after, 0, 0, width_after, 1);
screen_write_stop(&ctx);
@@ -431,7 +431,7 @@ format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
/* If there is no list left, pass off to the no list function. */
if (width_list == 0) {
- screen_write_start(&ctx, NULL, right);
+ screen_write_start(&ctx, right);
screen_write_fast_copy(&ctx, after, 0, 0, width_after, 1);
screen_write_stop(&ctx);
@@ -536,7 +536,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
*/
for (i = 0; i < TOTAL; i++) {
screen_init(&s[i], size, 1, 0);
- screen_write_start(&ctx[i], NULL, &s[i]);
+ screen_write_start(&ctx[i], &s[i]);
screen_write_clearendofline(&ctx[i], current_default.bg);
width[i] = 0;
}
diff --git a/input.c b/input.c
index 8485a17a..03b81c69 100644
--- a/input.c
+++ b/input.c
@@ -842,9 +842,9 @@ input_reset(struct input_ctx *ictx, int clear)
if (clear && wp != NULL) {
if (TAILQ_EMPTY(&wp->modes))
- screen_write_start(sctx, wp, &wp->base);
+ screen_write_start_pane(sctx, wp, &wp->base);
else
- screen_write_start(sctx, NULL, &wp->base);
+ screen_write_start(sctx, &wp->base);
screen_write_reset(sctx);
screen_write_stop(sctx);
}
@@ -960,9 +960,9 @@ input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
/* NULL wp if there is a mode set as don't want to update the tty. */
if (TAILQ_EMPTY(&wp->modes))
- screen_write_start(sctx, wp, &wp->base);
+ screen_write_start_pane(sctx, wp, &wp->base);
else
- screen_write_start(sctx, NULL, &wp->base);
+ screen_write_start(sctx, &wp->base);
log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
ictx->state->name, len, (int)len, buf);
@@ -973,15 +973,15 @@ input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
/* Parse given input for screen. */
void
-input_parse_screen(struct input_ctx *ictx, struct screen *s, u_char *buf,
- size_t len)
+input_parse_screen(struct input_ctx *ictx, struct screen *s,
+ screen_write_init_ctx_cb cb, void *arg, u_char *buf, size_t len)
{
struct screen_write_ctx *sctx = &ictx->ctx;
if (len == 0)
return;
- screen_write_start(sctx, NULL, s);
+ screen_write_start_callback(sctx, s, cb, arg);
input_parse(ictx, buf, len);
screen_write_stop(sctx);
}
@@ -1632,7 +1632,6 @@ static void
input_csi_dispatch_rm_private(struct input_ctx *ictx)
{
struct screen_write_ctx *sctx = &ictx->ctx;
- struct window_pane *wp = ictx->wp;
struct grid_cell *gc = &ictx->cell.cell;
u_int i;
@@ -1677,16 +1676,10 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
break;
case 47:
case 1047:
- if (wp != NULL)
- window_pane_alternate_off(wp, gc, 0);
- else
- screen_alternate_off(sctx->s, gc, 0);
+ screen_write_alternateoff(sctx, gc, 0);
break;
case 1049:
- if (wp != NULL)
- window_pane_alternate_off(wp, gc, 1);
- else
- screen_alternate_off(sctx->s, gc, 1);
+ screen_write_alternateoff(sctx, gc, 1);
break;
case 2004:
screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
@@ -1782,16 +1775,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
break;
case 47:
case 1047:
- if (wp != NULL)
- window_pane_alternate_on(wp, gc, 0);
- else
- screen_alternate_on(sctx->s, gc, 0);
+ screen_write_alternateon(sctx, gc, 0);
break;
case 1049:
- if (wp != NULL)
- window_pane_alternate_on(wp, gc, 1);
- else
- screen_alternate_on(sctx->s, gc, 1);
+ screen_write_alternateon(sctx, gc, 1);
break;
case 2004:
screen_write_mode_set(sctx, MODE_BRACKETPASTE);
@@ -2595,7 +2582,7 @@ input_osc_52(struct input_ctx *ictx, const char *p)
return;
}
- screen_write_start(&ctx, wp, NULL);
+ screen_write_start_pane(&ctx, wp, NULL);
screen_write_setselection(&ctx, out, outlen);
screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp);
diff --git a/menu.c b/menu.c
index e78999c6..07fc8fa8 100644
--- a/menu.c
+++ b/menu.c
@@ -130,14 +130,12 @@ menu_free(struct menu *menu)
free(menu);
}
-static int
+static struct screen *
menu_mode_cb(struct client *c, __unused u_int *cx, __unused u_int *cy)
{
struct menu_data *md = c->overlay_data;
- if (~md->flags & MENU_NOMOUSE)
- return (MODE_MOUSE_ALL);
- return (0);
+ return (&md->s);
}
static void
@@ -153,13 +151,15 @@ menu_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
- screen_write_start(&ctx, NULL, s);
+ screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8);
screen_write_menu(&ctx, menu, md->choice, &gc);
screen_write_stop(&ctx);
- for (i = 0; i < screen_size_y(&md->s); i++)
- tty_draw_line(tty, NULL, s, 0, i, menu->width + 4, px, py + i);
+ for (i = 0; i < screen_size_y(&md->s); i++) {
+ tty_draw_line(tty, s, 0, i, menu->width + 4, px, py + i,
+ &grid_default_cell, NULL);
+ }
}
static void
@@ -349,6 +349,8 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
if (fs != NULL)
cmd_find_copy_state(&md->fs, fs);
screen_init(&md->s, menu->width + 4, menu->count + 2, 0);
+ if (~md->flags & MENU_NOMOUSE)
+ md->s.mode |= MODE_MOUSE_ALL;
md->px = px;
md->py = py;
diff --git a/mode-tree.c b/mode-tree.c
index 645e2ae9..8d210d72 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -562,7 +562,7 @@ mode_tree_draw(struct mode_tree_data *mtd)
w = mtd->width;
h = mtd->height;
- screen_write_start(&ctx, NULL, s);
+ screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8);
if (mtd->line_size > 10)
diff --git a/popup.c b/popup.c
index 160b5aa3..9937d586 100644
--- a/popup.c
+++ b/popup.c
@@ -58,6 +58,44 @@ struct popup_data {
};
static void
+popup_redraw_cb(const struct tty_ctx *ttyctx)
+{
+ struct popup_data *pd = ttyctx->arg;
+
+ pd->c->flags |= CLIENT_REDRAWOVERLAY;
+}
+
+static int
+popup_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
+{
+ struct popup_data *pd = ttyctx->arg;
+
+ if (pd->c->flags & CLIENT_REDRAWOVERLAY)
+ return (-1);
+
+ ttyctx->bigger = 0;
+ ttyctx->wox = 0;
+ ttyctx->woy = 0;
+ ttyctx->wsx = c->tty.sx;
+ ttyctx->wsy = c->tty.sy;
+
+ ttyctx->xoff = ttyctx->rxoff = pd->px + 1;
+ ttyctx->yoff = ttyctx->ryoff = pd->py + 1;
+
+ return (1);
+}
+
+static void
+popup_init_ctx_cb(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx)
+{
+ struct popup_data *pd = ctx->arg;
+
+ ttyctx->redraw_cb = popup_redraw_cb;
+ ttyctx->set_client_cb = popup_set_client_cb;
+ ttyctx->arg = pd;
+}
+
+static void
popup_write_screen(struct client *c, struct popup_data *pd)
{
struct cmdq_item *item = pd->item;
@@ -72,7 +110,7 @@ popup_write_screen(struct client *c, struct popup_data *pd)
else
format_defaults(ft, c, NULL, NULL, NULL);
- screen_write_start(&ctx, NULL, &pd->s);
+ screen_write_start(&ctx, &pd->s);
screen_write_clearscreen(&ctx, 8);
y = 0;
@@ -98,7 +136,7 @@ popup_write_screen(struct client *c, struct popup_data *pd)
screen_write_stop(&ctx);
}
-static int
+static struct screen *
popup_mode_cb(struct client *c, u_int *cx, u_int *cy)
{
struct popup_data *pd = c->overlay_data;
@@ -107,7 +145,7 @@ popup_mode_cb(struct client *c, u_int *cx, u_int *cy)
return (0);
*cx = pd->px + 1 + pd->s.cx;
*cy = pd->py + 1 + pd->s.cy;
- return (pd->s.mode);
+ return (&pd->s);
}
static int
@@ -132,7 +170,7 @@ popup_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
u_int i, px = pd->px, py = pd->py;
screen_init(&s, pd->sx, pd->sy, 0);
- screen_write_start(&ctx, NULL, &s);
+ screen_write_start(&ctx, &s);
screen_write_clearscreen(&ctx, 8);
screen_write_box(&ctx, pd->sx, pd->sy);
screen_write_cursormove(&ctx, 1, 1, 0);
@@ -140,8 +178,10 @@ popup_draw_cb(struct client *c, __unused struct screen_redraw_ctx *ctx0)
screen_write_stop(&ctx);
c->overlay_check = NULL;
- for (i = 0; i < pd->sy; i++)
- tty_draw_line(tty, NULL, &s, 0, i, pd->sx, px, py + i);
+ for (i = 0; i < pd->sy; i++){
+ tty_draw_line(tty, &s, 0, i, pd->sx, px, py + i,
+ &grid_default_cell, NULL);
+ }
c->overlay_check = popup_check_cb;
}
@@ -327,15 +367,23 @@ popup_job_update_cb(struct job *job)
{
struct popup_data *pd = job_get_data(job);
struct evbuffer *evb = job_get_event(job)->input;
+ struct client *c = pd->c;
struct screen *s = &pd->s;
void *data = EVBUFFER_DATA(evb);
size_t size = EVBUFFER_LENGTH(evb);
- if (size != 0) {
- input_parse_screen(pd->ictx, s, data, size);
- evbuffer_drain(evb, size);
- pd->c->flags |= CLIENT_REDRAWOVERLAY;
- }
+ if (size == 0)
+ return;
+
+ c->overlay_check = NULL;
+ c->tty.flags &= ~TTY_FREEZE;
+
+ input_parse_screen(pd->ictx, s, popup_init_ctx_cb, pd, data, size);
+
+ c->tty.flags |= TTY_FREEZE;
+ c->overlay_check = popup_check_cb;
+
+ evbuffer_drain(evb, size);
}
static void
diff --git a/screen-redraw.c b/screen-redraw.c
index 19ed6305..0f83479c 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -346,7 +346,7 @@ screen_redraw_make_pane_status(struct client *c, struct window *w,
screen_init(&wp->status_screen, width, 1, 0);
wp->status_screen.mode = 0;
- screen_write_start(&ctx, NULL, &wp->status_screen);
+ screen_write_start(&ctx, &wp->status_screen);
gc.attr |= GRID_ATTR_CHARSET;
for (i = 0; i < width; i++)
@@ -423,7 +423,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
if (ctx->statustop)
yoff += ctx->statuslines;
- tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy);
+ tty_draw_line(tty, s, i, 0, width, x, yoff - ctx->oy,
+ &grid_default_cell, NULL);
}
tty_cursor(tty, 0, 0);
}
@@ -615,7 +616,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
}
}
- tty_attributes(tty, gc, NULL);
+ tty_attributes(tty, gc, &grid_default_cell, NULL);
if (ctx->statustop)
tty_cursor(tty, i, ctx->statuslines + j);
else
@@ -676,8 +677,10 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
y = 0;
else
y = c->tty.sy - ctx->statuslines;
- for (i = 0; i < ctx->statuslines; i++)
- tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i);
+ for (i = 0; i < ctx->statuslines; i++) {
+ tty_draw_line(tty, s, 0, i, UINT_MAX, 0, y + i,
+ &grid_default_cell, NULL);
+ }
}
/* Draw one pane. */
@@ -688,6 +691,7 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct screen *s;
+ struct grid_cell defaults;
u_int i, j, top, x, y, width;
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
@@ -731,6 +735,8 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u",
__func__, c->name, wp->id, i, j, x, y, width);
- tty_draw_line(tty, wp, s, i, j, width, x, y);
+ tty_default_colours(&defaults, wp);
+ tty_draw_line(tty, s, i, j, width, x, y, &defaults,
+ wp->palette);
}
}
diff --git a/screen-write.c b/screen-write.c
index 32424b39..909b8531 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -27,8 +27,8 @@ static void screen_write_collect_clear(struct screen_write_ctx *, u_int,
u_int);
static int screen_write_collect_clear_end(struct screen_write_ctx *, u_int,
u_int, u_int);
-static int screen_write_collect_clear_start(struct screen_write_ctx *, u_int,
- u_int, u_int);
+static int screen_write_collect_clear_start(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_flush(struct screen_write_ctx *, int,
const char *);
@@ -101,6 +101,50 @@ screen_write_set_cursor(struct screen_write_ctx *ctx, int cx, int cy)
evtimer_add(&w->offset_timer, &tv);
}
+/* Do a full redraw. */
+static void
+screen_write_redraw_cb(const struct tty_ctx *ttyctx)
+{
+ struct window_pane *wp = ttyctx->arg;
+
+ wp->flags |= PANE_REDRAW;
+}
+
+/* Update context for client. */
+static int
+screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
+{
+ struct window_pane *wp = ttyctx->arg;
+
+ if (c->session->curw->window != wp->window)
+ return (0);
+ if (wp->layout_cell == NULL)
+ return (0);
+
+ if (wp->flags & (PANE_REDRAW|PANE_DROP))
+ return (-1);
+ if (c->flags & CLIENT_REDRAWPANES) {
+ /*
+ * Redraw is already deferred to redraw another pane - redraw
+ * this one also when that happens.
+ */
+ log_debug("adding %%%u to deferred redraw", wp->id);
+ wp->flags |= PANE_REDRAW;
+ return (-1);
+ }
+
+ ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy,
+ &ttyctx->wsx, &ttyctx->wsy);
+
+ ttyctx->xoff = ttyctx->rxoff = wp->xoff;
+ ttyctx->yoff = ttyctx->ryoff = wp->yoff;
+
+ if (status_at_line(c) == 0)
+ ttyctx->yoff += status_line_size(c);
+
+ return (1);
+}
+
/* Set up context for TTY command. */
static void
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
@@ -110,17 +154,35 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
memset(ttyctx, 0, sizeof *ttyctx);
- ttyctx->wp = ctx->wp;
+ if (ctx->wp != NULL) {
+ tty_default_colours(&ttyctx->defaults, ctx->wp);
+ ttyctx->palette = ctx->wp->palette;
+ } else {
+ memcpy(&ttyctx->defaults, &grid_default_cell,
+ sizeof ttyctx->defaults);
+ ttyctx->palette = NULL;
+ }
+ ttyctx->s = s;
ttyctx->sx = screen_size_x(s);
ttyctx->sy = screen_size_y(s);
ttyctx->ocx = s->cx;
ttyctx->ocy = s->cy;
-
ttyctx->orlower = s->rlower;
ttyctx->orupper = s->rupper;
+ if (ctx->init_ctx_cb != NULL)
+ ctx->init_ctx_cb(ctx, ttyctx);
+ else {
+ ttyctx->redraw_cb = screen_write_redraw_cb;
+ if (ctx->wp == NULL)
+ ttyctx->set_client_cb = NULL;
+ else
+ ttyctx->set_client_cb = screen_write_set_client_cb;
+ ttyctx->arg = ctx->wp;
+ }
+
if (ctx->wp != NULL &&
!ctx->sync &&
(sync || ctx->wp != ctx->wp->window->active)) {
@@ -151,18 +213,13 @@ screen_write_free_list(struct screen *s)
free(s->write_list);
}
-/* Initialize writing with a window. */
-void
-screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
- struct screen *s)
+/* Set up for writing. */
+static void
+screen_write_init(struct screen_write_ctx *ctx, struct screen *s)
{
memset(ctx, 0, sizeof *ctx);
- ctx->wp = wp;
- if (wp != NULL && s == NULL)
- ctx->s = wp->screen;
- else
- ctx->s = s;
+ ctx->s = s;
if (ctx->s->write_list == NULL)
screen_write_make_list(ctx->s);
@@ -170,17 +227,51 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
ctx->scrolled = 0;
ctx->bg = 8;
+}
+
+/* Initialize writing with a pane. */
+void
+screen_write_start_pane(struct screen_write_ctx *ctx, struct window_pane *wp,
+ struct screen *s)
+{
+ if (s == NULL)
+ s = wp->screen;
+ screen_write_init(ctx, s);
+ ctx->wp = wp;
if (log_get_level() != 0) {
- if (wp != NULL) {
- log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
- __func__, screen_size_x(ctx->s),
- screen_size_y(ctx->s), wp->id, wp->xoff, wp->yoff);
- } else {
- log_debug("%s: size %ux%u, no pane",
- __func__, screen_size_x(ctx->s),
- screen_size_y(ctx->s));
- }
+ log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
+ __func__, screen_size_x(ctx->s), screen_size_y(ctx->s),
+ wp->id, wp->xoff, wp->yoff);
+ }
+}
+
+/* Initialize writing with a callback. */
+void
+screen_write_start_callback(struct screen_write_ctx *ctx, struct screen *s,
+ screen_write_init_ctx_cb cb, void *arg)
+{
+ screen_write_init(ctx, s);
+
+ ctx->init_ctx_cb = cb;
+ ctx->arg = arg;
+
+ if (log_get_level() != 0) {
+ log_debug("%s: size %ux%u, with callback", __func__,
+ screen_size_x(ctx->s), screen_size_y(ctx->s));
+ }
+}
+
+
+/* Initialize writing. */
+void
+screen_write_start(struct screen_write_ctx *ctx, struct screen *s)
+{
+ screen_write_init(ctx, s);
+
+ if (log_get_level() != 0) {
+ log_debug("%s: size %ux%u, no pane", __func__,
+ screen_size_x(ctx->s), screen_size_y(ctx->s));
}
}
@@ -1799,3 +1890,35 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
tty_write(tty_cmd_rawstring, &ttyctx);
}
+
+/* Turn alternate screen on. */
+void
+screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
+ int cursor)
+{
+ struct tty_ctx ttyctx;
+ struct window_pane *wp = ctx->wp;
+
+ if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
+ return;
+ screen_alternate_on(ctx->s, gc, cursor);
+
+ screen_write_initctx(ctx, &ttyctx, 1);
+ ttyctx.redraw_cb(&ttyctx);
+}
+
+/* Turn alternate screen off. */
+void
+screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
+ int cursor)
+{
+ struct tty_ctx ttyctx;
+ struct window_pane *wp = ctx->wp;
+
+ if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
+ return;
+ screen_alternate_off(ctx->s, gc, cursor);
+
+ screen_write_initctx(ctx, &ttyctx, 1);
+ ttyctx.redraw_cb(&ttyctx);
+}
diff --git a/server-client.c b/server-client.c
index b21dac1d..a45e9812 100644
--- a/server-client.c
+++ b/server-client.c
@@ -1542,9 +1542,9 @@ server_client_reset_state(struct client *c)
struct tty *tty = &c->tty;
struct window *w = c->session->curw->window;
struct window_pane *wp = w->active, *loop;
- struct screen *s;
+ struct screen *s = NULL;
struct options *oo = c->session->options;
- int mode, cursor, flags;
+ int mode = 0, cursor, flags;
u_int cx = 0, cy = 0, ox, oy, sx, sy;
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
@@ -1556,17 +1556,14 @@ server_client_reset_state(struct client *c)
/* Get mode from overlay if any, else from screen. */
if (c->overlay_draw != NULL) {
- s = NULL;
- if (c->overlay_mode == NULL)
- mode = 0;
- else
- mode = c->overlay_mode(c, &cx, &cy);
- } else {
+ if (c->overlay_mode != NULL)
+ s = c->overlay_mode(c, &cx, &cy);
+ } else
s = wp->screen;
+ if (s != NULL)
mode = s->mode;
- if (c->prompt_string != NULL || c->message_string != NULL)
- mode &= ~MODE_CURSOR;
- }
+ if (c->prompt_string != NULL || c->message_string != NULL)
+ mode &= ~MODE_CURSOR;
log_debug("%s: client %s mode %x", __func__, c->name, mode);
/* Reset region and margin. */
diff --git a/server-fn.c b/server-fn.c
index da1371ae..fde1d8e8 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -318,7 +318,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
if (notify)
notify_pane("pane-died", wp);
- screen_write_start(&ctx, wp, &wp->base);
+ screen_write_start_pane(&ctx, wp, &wp->base);
screen_write_scrollregion(&ctx, 0, screen_size_y(ctx.s) - 1);
screen_write_cursormove(&ctx, 0, screen_size_y(ctx.s) - 1, 0);
screen_write_linefeed(&ctx, 1, 8);
diff --git a/status.c b/status.c
index a4844294..b5442550 100644
--- a/status.c
+++ b/status.c
@@ -372,7 +372,7 @@ status_redraw(struct client *c)
screen_resize(&sl->screen, width, lines, 0);
changed = force = 1;
}
- screen_write_start(&ctx, NULL, &sl->screen);
+ screen_write_start(&ctx, &sl->screen);
/* Write the status lines. */
o = options_get(s->options, "status-format");
@@ -509,7 +509,7 @@ status_message_redraw(struct client *c)
style_apply(&gc, s->options, "message-style", ft);
format_free(ft);
- screen_write_start(&ctx, NULL, sl->active);
+ screen_write_start(&ctx, sl->active);
screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines - 1);
screen_write_cursormove(&ctx, 0, lines - 1, 0);
for (offset = 0; offset < c->tty.sx; offset++)
@@ -664,7 +664,7 @@ status_prompt_redraw(struct client *c)
if (start > c->tty.sx)
start = c->tty.sx;
- screen_write_start(&ctx, NULL, sl->active);
+ screen_write_start(&ctx, sl->active);
screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines - 1);
screen_write_cursormove(&ctx, 0, lines - 1, 0);
for (offset = 0; offset < c->tty.sx; offset++)
diff --git a/tmux.h b/tmux.h
index e9a5db8a..53417cd7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -55,7 +55,11 @@ struct mouse_event;
struct options;
struct options_array_item;
struct options_entry;
+struct screen_write_collect_item;
+struct screen_write_collect_line;
+struct screen_write_ctx;
struct session;
+struct tty_ctx;
struct tmuxpeer;
struct tmuxproc;
struct winlink;
@@ -786,13 +790,16 @@ struct screen {
};
/* Screen write context. */
-struct screen_write_collect_item;
-struct screen_write_collect_line;
+typedef void (*screen_write_init_ctx_cb)(struct screen_write_ctx *,
+ struct tty_ctx *);
struct screen_write_ctx {
struct window_pane *wp;
struct screen *s;
int sync;
+ screen_write_init_ctx_cb init_ctx_cb;
+ void *arg;
+
struct screen_write_collect_item *item;
u_int scrolled;
u_int bg;
@@ -1252,8 +1259,6 @@ struct tty {
struct termios tio;
struct grid_cell cell;
-
- int last_wp;
struct grid_cell last_cell;
#define TTY_NOCURSOR 0x1
@@ -1285,8 +1290,14 @@ struct tty {
};
/* TTY command context. */
+typedef void (*tty_ctx_redraw_cb)(const struct tty_ctx *);
+typedef int (*tty_ctx_set_client_cb)(struct tty_ctx *, struct client *);
struct tty_ctx {
- struct window_pane *wp;
+ struct screen *s;
+
+ tty_ctx_redraw_cb redraw_cb;
+ tty_ctx_set_client_cb set_client_cb;
+ void *arg;
const struct grid_cell *cell;
int wrapped;
@@ -1308,12 +1319,18 @@ struct tty_ctx {
/* Target region (usually pane) offset and size. */
u_int xoff;
u_int yoff;
+ u_int rxoff;
+ u_int ryoff;
u_int sx;
u_int sy;
/* The background colour used for clearing (erasing). */
u_int bg;
+ /* The default colours and palette. */
+ struct grid_cell defaults;
+ int *palette;
+
/* Containing region (usually window) offset and size. */
int bigger;
u_int wox;
@@ -1492,7 +1509,7 @@ RB_HEAD(client_files, client_file);
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
typedef void (*prompt_free_cb)(void *);
typedef int (*overlay_check_cb)(struct client *, u_int, u_int);
-typedef int (*overlay_mode_cb)(struct client *, u_int *, u_int *);
+typedef struct screen *(*overlay_mode_cb)(struct client *, u_int *, u_int *);
typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *);
typedef int (*overlay_key_cb)(struct client *, struct key_event *);
typedef void (*overlay_free_cb)(struct client *);
@@ -1969,7 +1986,7 @@ void tty_update_window_offset(struct window *);
void tty_update_client_offset(struct client *);
void tty_raw(struct tty *, const char *);
void tty_attributes(struct tty *, const struct grid_cell *,
- struct window_pane *);
+ const struct grid_cell *, int *);
void tty_reset(struct tty *);
void tty_region_off(struct tty *);
void tty_margin_off(struct tty *);
@@ -1992,8 +2009,8 @@ void tty_send_requests(struct tty *);
void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
-void tty_draw_line(struct tty *, struct window_pane *, struct screen *,
- u_int, u_int, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ u_int, u_int, const struct grid_cell *, int *);
void tty_sync_start(struct tty *);
void tty_sync_end(struct tty *);
int tty_open(struct tty *, char **);
@@ -2024,6 +2041,7 @@ void tty_cmd_reverseindex(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_syncstart(struct tty *, const struct tty_ctx *);
+void tty_default_colours(struct grid_cell *, struct window_pane *);
/* tty-term.c */
extern struct tty_terms tty_terms;
@@ -2342,8 +2360,8 @@ void input_reset(struct input_ctx *, int);
struct evbuffer *input_pending(struct input_ctx *);
void input_parse_pane(struct window_pane *);
void input_parse_buffer(struct window_pane *, u_char *, size_t);
-void input_parse_screen(struct input_ctx *, struct screen *, u_char *,
- size_t);
+void input_parse_screen(struct input_ctx *, struct screen *,
+ screen_write_init_ctx_cb, void *, u_char *, size_t);
/* input-key.c */
int input_key_pane(struct window_pane *, key_code, struct mouse_event *);
@@ -2426,8 +2444,11 @@ char *grid_view_string_cells(struct grid *, u_int, u_int, u_int);
/* screen-write.c */
void screen_write_make_list(struct screen *);
void screen_write_free_list(struct screen *);
-void screen_write_start(struct screen_write_ctx *, struct window_pane *,
- struct screen *);
+void screen_write_start_pane(struct screen_write_ctx *,
+ struct window_pane *, struct screen *);
+void screen_write_start(struct screen_write_ctx *, struct screen *);
+void screen_write_start_callback(struct screen_write_ctx *, struct screen *,
+ screen_write_init_ctx_cb, void *);
void screen_write_stop(struct screen_write_ctx *);
void screen_write_reset(struct screen_write_ctx *);
size_t printflike(1, 2) screen_write_strlen(const char *, ...);
@@ -2481,6 +2502,10 @@ void screen_write_collect_add(struct screen_write_ctx *,
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_rawstring(struct screen_write_ctx *, u_char *, u_int);
+void screen_write_alternateon(struct screen_write_ctx *,
+ struct grid_cell *, int);
+void screen_write_alternateoff(struct screen_write_ctx *,
+ struct grid_cell *, int);
/* screen-redraw.c */
void screen_redraw_screen(struct client *);
@@ -2569,10 +2594,6 @@ struct window_pane *window_pane_find_by_id_str(const char *);
struct window_pane *window_pane_find_by_id(u_int);
int window_pane_destroy_ready(struct window_pane *);
void window_pane_resize(struct window_pane *, u_int, u_int);
-void window_pane_alternate_on(struct window_pane *,
- struct grid_cell *, int);
-void window_pane_alternate_off(struct window_pane *,
- struct grid_cell *, int);
void window_pane_set_palette(struct window_pane *, u_int, int);
void window_pane_unset_palette(struct window_pane *, u_int);
void window_pane_reset_palette(struct window_pane *);
diff --git a/tty.c b/tty.c
index aaf4d639..388f6f5f 100644
--- a/tty.c
+++ b/tty.c
@@ -34,7 +34,7 @@
static int tty_log_fd = -1;
-static int tty_client_ready(struct client *, struct window_pane *);
+static int tty_client_ready(struct client *);
static void tty_set_italics(struct tty *);
static int tty_try_colour(struct tty *, int, const char *);
@@ -45,12 +45,9 @@ static void tty_cursor_pane_unless_wrap(struct tty *,
const struct tty_ctx *, u_int, u_int);
static void tty_invalidate(struct tty *);
static void tty_colours(struct tty *, const struct grid_cell *);
-static void tty_check_fg(struct tty *, struct window_pane *,
- struct grid_cell *);
-static void tty_check_bg(struct tty *, struct window_pane *,
- struct grid_cell *);
-static void tty_check_us(struct tty *, struct window_pane *,
- struct grid_cell *);
+static void tty_check_fg(struct tty *, int *, struct grid_cell *);
+static void tty_check_bg(struct tty *, int *, struct grid_cell *);
+static void tty_check_us(struct tty *, int *, struct grid_cell *);
static void tty_colours_fg(struct tty *, const struct grid_cell *);
static void tty_colours_bg(struct tty *, const struct grid_cell *);
static void tty_colours_us(struct tty *, const struct grid_cell *);
@@ -61,17 +58,17 @@ static void tty_region(struct tty *, u_int, u_int);
static void tty_margin_pane(struct tty *, const struct tty_ctx *);
static void tty_margin(struct tty *, u_int, u_int);
static int tty_large_region(struct tty *, const struct tty_ctx *);
-static int tty_fake_bce(const struct tty *, struct window_pane *, u_int);
+static int tty_fake_bce(const struct tty *, const struct grid_cell *,
+ u_int);
static void tty_redraw_region(struct tty *, const struct tty_ctx *);
static void tty_emulate_repeat(struct tty *, enum tty_code_code,
enum tty_code_code, u_int);
static void tty_repeat_space(struct tty *, u_int);
static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
static void tty_cell(struct tty *, const struct grid_cell *,
- struct window_pane *);
-static void tty_default_colours(struct grid_cell *, struct window_pane *);
-static void tty_default_attributes(struct tty *, struct window_pane *,
- u_int);
+ const struct grid_cell *, int *);
+static void tty_default_attributes(struct tty *, const struct grid_cell *,
+ int *, u_int);
#define tty_use_margin(tty) \
(tty->term->flags & TERM_DECSLRM)
@@ -888,6 +885,27 @@ tty_update_client_offset(struct client *c)
c->flags |= (CLIENT_REDRAWWINDOW|CLIENT_REDRAWSTATUS);
}
+/* Get a palette entry. */
+static int
+tty_get_palette(int *palette, int c)
+{
+ int new;
+
+ if (palette == NULL)
+ return (-1);
+
+ new = -1;
+ if (c < 8)
+ new = palette[c];
+ else if (c >= 90 && c <= 97)
+ new = palette[8 + c - 90];
+ else if (c & COLOUR_FLAG_256)
+ new = palette[c & ~COLOUR_FLAG_256];
+ if (new == 0)
+ return (-1);
+ return (new);
+}
+
/*
* Is the region large enough to be worth redrawing once later rather than
* probably several times now? Currently yes if it is more than 50% of the
@@ -904,18 +922,11 @@ tty_large_region(__unused struct tty *tty, const struct tty_ctx *ctx)
* emulated.