From 43264dfbf410489b36343a29cc83798a54df67f8 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Nov 2017 22:00:42 +0000 Subject: [PATCH] Make the mode draw function use the parent screen directly rather than its own to avoid copying twice. --- mode-tree.c | 28 ++++++++++--------------- screen-write.c | 2 +- tmux.h | 15 ++++++++------ window-buffer.c | 23 +++++++-------------- window-client.c | 30 ++++++++++----------------- window-tree.c | 55 +++++++++++++++++++++++-------------------------- 6 files changed, 65 insertions(+), 88 deletions(-) diff --git a/mode-tree.c b/mode-tree.c index 32ae4a33..4307dbf0 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -39,10 +39,9 @@ struct mode_tree_data { u_int sort_size; u_int sort_type; - void (*buildcb)(void *, u_int, uint64_t *, - const char *); - struct screen *(*drawcb)(void *, void *, u_int, u_int); - int (*searchcb)(void*, void *, const char *); + mode_tree_build_cb buildcb; + mode_tree_draw_cb drawcb; + mode_tree_search_cb searchcb; struct mode_tree_list children; struct mode_tree_list saved; @@ -265,8 +264,8 @@ mode_tree_count_tagged(struct mode_tree_data *mtd) } void -mode_tree_each_tagged(struct mode_tree_data *mtd, void (*cb)(void *, void *, - struct client *, key_code), struct client *c, key_code key, int current) +mode_tree_each_tagged(struct mode_tree_data *mtd, mode_tree_each_cb cb, + struct client *c, key_code key, int current) { struct mode_tree_item *mti; u_int i; @@ -288,10 +287,9 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, void (*cb)(void *, void *, struct mode_tree_data * mode_tree_start(struct window_pane *wp, struct args *args, - void (*buildcb)(void *, u_int, uint64_t *, const char *), - struct screen *(*drawcb)(void *, void *, u_int, u_int), - int (*searchcb)(void *, void *, const char *), void *modedata, - const char **sort_list, u_int sort_size, struct screen **s) + mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, + mode_tree_search_cb searchcb, void *modedata, const char **sort_list, + u_int sort_size, struct screen **s) { struct mode_tree_data *mtd; const char *sort; @@ -463,7 +461,7 @@ void mode_tree_draw(struct mode_tree_data *mtd) { struct window_pane *wp = mtd->wp; - struct screen *s = &mtd->screen, *box = NULL; + struct screen *s = &mtd->screen; struct mode_tree_line *line; struct mode_tree_item *mti; struct options *oo = wp->window->options; @@ -591,13 +589,9 @@ mode_tree_draw(struct mode_tree_data *mtd) box_x = w - 4; box_y = sy - h - 2; - if (box_x != 0 && box_y != 0) - box = mtd->drawcb(mtd->modedata, mti->itemdata, box_x, box_y); - if (box != NULL) { + if (box_x != 0 && box_y != 0) { screen_write_cursormove(&ctx, 2, h + 1); - screen_write_fast_copy(&ctx, box, 0, 0, box_x, box_y); - - screen_free(box); + mtd->drawcb(mtd->modedata, mti->itemdata, &ctx, box_x, box_y); } screen_write_stop(&ctx); diff --git a/screen-write.c b/screen-write.c index 37a51fcb..44c28982 100644 --- a/screen-write.c +++ b/screen-write.c @@ -457,7 +457,7 @@ screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom) screen_write_cursormove(ctx, cx, cy + i); screen_write_putc(ctx, &gc, 'x'); } - screen_write_cursormove(ctx, cx, cy + ny); + screen_write_cursormove(ctx, cx, cy + ny - 1); screen_write_putc(ctx, &gc, bottom ? 'v' : 'x'); screen_write_cursormove(ctx, cx, cy); diff --git a/tmux.h b/tmux.h index 62e88248..dcd4c676 100644 --- a/tmux.h +++ b/tmux.h @@ -2225,17 +2225,20 @@ u_int layout_set_next(struct window *); u_int layout_set_previous(struct window *); /* mode-tree.c */ +typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *); +typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *, + u_int, u_int); +typedef int (*mode_tree_search_cb)(void *, void *, const char *); +typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code); u_int mode_tree_count_tagged(struct mode_tree_data *); void *mode_tree_get_current(struct mode_tree_data *); -void mode_tree_each_tagged(struct mode_tree_data *, void (*)(void *, void *, - struct client *, key_code), struct client *, key_code, int); +void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb, + struct client *, key_code, int); void mode_tree_up(struct mode_tree_data *, int); void mode_tree_down(struct mode_tree_data *, int); struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *, - void (*)(void *, u_int, uint64_t *, const char *), - struct screen *(*)(void *, void *, u_int, u_int), - int (*)(void *, void *, const char *), void *, const char **, - u_int, struct screen **); + mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb, + void *, const char **, u_int, struct screen **); void mode_tree_build(struct mode_tree_data *); void mode_tree_free(struct mode_tree_data *); void mode_tree_resize(struct mode_tree_data *, u_int, u_int); diff --git a/window-buffer.c b/window-buffer.c index 5f58a858..14b15762 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -196,26 +196,20 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag, } -static struct screen * -window_buffer_draw(__unused void *modedata, void *itemdata, u_int sx, u_int sy) +static void +window_buffer_draw(__unused void *modedata, void *itemdata, + struct screen_write_ctx *ctx, u_int sx, u_int sy) { struct window_buffer_itemdata *item = itemdata; struct paste_buffer *pb; - static struct screen s; - struct screen_write_ctx ctx; char line[1024]; const char *pdata, *end, *cp; size_t psize, at; - u_int i; + u_int i, cx = ctx->s->cx, cy = ctx->s->cy; pb = paste_get_name(item->name); if (pb == NULL) - return (NULL); - - screen_init(&s, sx, sy, 0); - - screen_write_start(&ctx, NULL, &s); - screen_write_clearscreen(&ctx, 8); + return; pdata = end = paste_buffer_data(pb, &psize); for (i = 0; i < sy; i++) { @@ -232,17 +226,14 @@ window_buffer_draw(__unused void *modedata, void *itemdata, u_int sx, u_int sy) line[at] = '\0'; if (*line != '\0') { - screen_write_cursormove(&ctx, 0, i); - screen_write_puts(&ctx, &grid_default_cell, "%s", line); + screen_write_cursormove(ctx, cx, cy + i); + screen_write_puts(ctx, &grid_default_cell, "%s", line); } if (end == pdata + psize) break; end++; } - - screen_write_stop(&ctx); - return (&s); } static int diff --git a/window-client.c b/window-client.c index fc5b55e7..5f1b58ba 100644 --- a/window-client.c +++ b/window-client.c @@ -210,37 +210,29 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag, } } -static struct screen * -window_client_draw(__unused void *modedata, void *itemdata, u_int sx, u_int sy) +static void +window_client_draw(__unused void *modedata, void *itemdata, + struct screen_write_ctx *ctx, u_int sx, u_int sy) { struct window_client_itemdata *item = itemdata; struct client *c = item->c; struct window_pane *wp; - static struct screen s; - struct screen_write_ctx ctx; + u_int cx = ctx->s->cx, cy = ctx->s->cy; if (c->session == NULL || (c->flags & (CLIENT_DEAD|CLIENT_DETACHING))) - return (NULL); + return; wp = c->session->curw->window->active; - screen_init(&s, sx, sy, 0); + screen_write_preview(ctx, &wp->base, sx, sy - 3); - screen_write_start(&ctx, NULL, &s); - screen_write_clearscreen(&ctx, 8); + screen_write_cursormove(ctx, cx, cy + sy - 2); + screen_write_hline(ctx, sx, 0, 0); - screen_write_preview(&ctx, &wp->base, sx, sy - 3); - - screen_write_cursormove(&ctx, 0, sy - 2); - screen_write_hline(&ctx, sx, 0, 0); - - screen_write_cursormove(&ctx, 0, sy - 1); + screen_write_cursormove(ctx, cx, cy + sy - 1); if (c->old_status != NULL) - screen_write_fast_copy(&ctx, c->old_status, 0, 0, sx, 1); + screen_write_fast_copy(ctx, c->old_status, 0, 0, sx, 1); else - screen_write_fast_copy(&ctx, &c->status, 0, 0, sx, 1); - - screen_write_stop(&ctx); - return (&s); + screen_write_fast_copy(ctx, &c->status, 0, 0, sx, 1); } static struct screen * diff --git a/window-tree.c b/window-tree.c index c83db557..8e676c72 100644 --- a/window-tree.c +++ b/window-tree.c @@ -482,6 +482,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, struct options *oo = s->options; struct winlink *wl; struct window *w; + u_int cx = ctx->s->cx, cy = ctx->s->cy; u_int loop, total, visible, each, width, offset; u_int current, start, end, remaining, i; struct grid_cell gc; @@ -544,15 +545,15 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, return; if (left) { - screen_write_cursormove(ctx, 2, 0); + screen_write_cursormove(ctx, cx + 2, cy); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, 0, sy / 2); + screen_write_cursormove(ctx, cx, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, "<"); } if (right) { - screen_write_cursormove(ctx, sx - 3, 0); + screen_write_cursormove(ctx, cx + sx - 3, cy); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, sx - 1, sy / 2); + screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, ">"); } @@ -580,17 +581,18 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, else width = each - 1; - screen_write_cursormove(ctx, offset, 0); + screen_write_cursormove(ctx, cx + offset, cy); screen_write_preview(ctx, &w->active->base, width, sy); xasprintf(&label, " %u:%s ", wl->idx, w->name); if (strlen(label) > width) xasprintf(&label, " %u ", wl->idx); - window_tree_draw_label(ctx, offset, 0, width, sy, &gc, label); + window_tree_draw_label(ctx, cx + offset, cy, width, sy, &gc, + label); free(label); if (loop != end - 1) { - screen_write_cursormove(ctx, offset + width, 0); + screen_write_cursormove(ctx, cx + offset + width, cy); screen_write_vline(ctx, sy, 0, 0); } loop++; @@ -605,6 +607,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, { struct options *oo = s->options; struct window_pane *wp; + u_int cx = ctx->s->cx, cy = ctx->s->cy; u_int loop, total, visible, each, width, offset; u_int current, start, end, remaining, i; struct grid_cell gc; @@ -667,15 +670,15 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, return; if (left) { - screen_write_cursormove(ctx, 2, 0); + screen_write_cursormove(ctx, cx + 2, cy); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, 0, sy / 2); + screen_write_cursormove(ctx, cx, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, "<"); } if (right) { - screen_write_cursormove(ctx, sx - 3, 0); + screen_write_cursormove(ctx, cx + sx - 3, cy); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, sx - 1, sy / 2); + screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); screen_write_puts(ctx, &grid_default_cell, ">"); } @@ -702,17 +705,18 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, else width = each - 1; - screen_write_cursormove(ctx, offset, 0); + screen_write_cursormove(ctx, cx + offset, cy); screen_write_preview(ctx, &wp->base, width, sy); if (window_pane_index(wp, &pane_idx) != 0) pane_idx = loop; xasprintf(&label, " %u ", pane_idx); - window_tree_draw_label(ctx, offset, 0, each, sy, &gc, label); + window_tree_draw_label(ctx, cx + offset, cy, each, sy, &gc, + label); free(label); if (loop != end - 1) { - screen_write_cursormove(ctx, offset + width, 0); + screen_write_cursormove(ctx, cx + offset + width, cy); screen_write_vline(ctx, sy, 0, 0); } loop++; @@ -721,39 +725,32 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, } } -static struct screen * -window_tree_draw(void *modedata, void *itemdata, u_int sx, u_int sy) +static void +window_tree_draw(void *modedata, void *itemdata, struct screen_write_ctx *ctx, + u_int sx, u_int sy) { struct window_tree_itemdata *item = itemdata; struct session *sp; struct winlink *wlp; struct window_pane *wp; - static struct screen s; - struct screen_write_ctx ctx; window_tree_pull_item(item, &sp, &wlp, &wp); if (wp == NULL) - return (NULL); - - screen_init(&s, sx, sy, 0); - screen_write_start(&ctx, NULL, &s); + return; switch (item->type) { case WINDOW_TREE_NONE: - return (0); + break; case WINDOW_TREE_SESSION: - window_tree_draw_session(modedata, sp, &ctx, sx, sy); + window_tree_draw_session(modedata, sp, ctx, sx, sy); break; case WINDOW_TREE_WINDOW: - window_tree_draw_window(modedata, sp, wlp->window, &ctx, sx, sy); + window_tree_draw_window(modedata, sp, wlp->window, ctx, sx, sy); break; case WINDOW_TREE_PANE: - screen_write_preview(&ctx, &wp->base, sx, sy); + screen_write_preview(ctx, &wp->base, sx, sy); break; } - - screen_write_stop(&ctx); - return (&s); } static int