From a25c14d472b2b365ba9cb22c7f49594af5766096 Mon Sep 17 00:00:00 2001 From: Michael Grant Date: Wed, 21 Jan 2026 19:34:19 +0000 Subject: [PATCH] Change overlay_ranges into visible_ranges. --- menu.c | 10 +++---- popup.c | 41 ++++++++++++++++++----------- screen-redraw.c | 57 ++++++++++++++++++++-------------------- server-client.c | 46 ++++++++++++++++---------------- tmux.h | 33 +++++++++++------------ tty-draw.c | 3 ++- tty.c | 70 ++++++++++++++++++++++--------------------------- 7 files changed, 130 insertions(+), 130 deletions(-) diff --git a/menu.c b/menu.c index cd361e00..901e0197 100644 --- a/menu.c +++ b/menu.c @@ -181,17 +181,15 @@ menu_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy) } /* Return parts of the input range which are not obstructed by the menu. */ -struct visible_ranges * +void menu_check_cb(__unused struct client *c, void *data, u_int px, u_int py, - u_int nx) + u_int nx, struct visible_ranges *r) { struct menu_data *md = data; struct menu *menu = md->menu; - struct visible_ranges *r; - r = server_client_overlay_range(md->px, md->py, menu->width + 4, - menu->count + 2, px, py, nx); - return (r); + server_client_overlay_range(md->px, md->py, menu->width + 4, + menu->count + 2, px, py, nx, r); } void diff --git a/popup.c b/popup.c index 6d0e1ffd..5422809c 100644 --- a/popup.c +++ b/popup.c @@ -164,19 +164,27 @@ popup_mode_cb(__unused struct client *c, void *data, u_int *cx, u_int *cy) } /* Return parts of the input range which are not obstructed by the popup. */ -static struct visible_ranges * -popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx) +static void +popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx, + struct visible_ranges *r) { - struct popup_data *pd = data; - struct visible_ranges *or[2], *r; - u_int i, j, k = 0; + struct popup_data *pd = data; + static struct visible_ranges or[2] = { { NULL, 0, 0 }, { NULL, 0, 0 } }; + u_int i, j, k = 0; if (pd->md != NULL) { /* Check each returned range for the menu against the popup. */ - r = menu_check_cb(c, pd->md, px, py, nx); + menu_check_cb(c, pd->md, px, py, nx, r); for (i = 0; i < r->used; i++) { - or[i] = server_client_overlay_range(pd->px, pd->py, pd->sx, - pd->sy, r->px[i], py, r->nx[i]); + server_client_overlay_range(pd->px, pd->py, pd->sx, + pd->sy, r->ranges[i].px, py, r->ranges[i].nx, &or[i]); + } + + /* Caller must free when no longer used. */ + if (r->size == 0) { + r->ranges = xcalloc(2, sizeof(struct visible_range)); + r->size = 2; + r->used = 0; } /* @@ -185,20 +193,21 @@ popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx) */ for (i = 0; i < r->used; i++) { /* Each or[i] only has up to 2 ranges. */ - for (j = 0; j < or[i]->used; j++) { - if (or[i]->nx[j] > 0) { - r->px[k] = or[i]->px[j]; - r->nx[k] = or[i]->nx[j]; + for (j = 0; j < or[i].used; j++) { + if (or[i].ranges[j].nx > 0) { + r->ranges[k].px = or[i].ranges[j].px; + r->ranges[k].nx = or[i].ranges[j].nx; k++; } } } - - return (r); + return; } - return (server_client_overlay_range(pd->px, pd->py, pd->sx, pd->sy, px, py, - nx)); + server_client_overlay_range(pd->px, pd->py, pd->sx, pd->sy, + px, py, nx, r); + + return; } static void diff --git a/screen-redraw.c b/screen-redraw.c index da3f40b5..15ca76b7 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -808,22 +808,23 @@ screen_redraw_draw_border_arrows(struct screen_redraw_ctx *ctx, u_int i, static void screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) { - struct client *c = ctx->c; - struct session *s = c->session; - struct window *w = s->curw->window; - struct options *oo = w->options; - struct tty *tty = &c->tty; - struct format_tree *ft; - struct window_pane *wp, *active = server_client_get_pane(c); - struct grid_cell gc; - const struct grid_cell *tmp; - struct visible_ranges *r; - u_int cell_type, x = ctx->ox + i, y = ctx->oy + j; - int isolates; + struct client *c = ctx->c; + struct session *s = c->session; + struct window *w = s->curw->window; + struct options *oo = w->options; + struct tty *tty = &c->tty; + struct format_tree *ft; + struct window_pane *wp, *active = server_client_get_pane(c); + struct grid_cell gc; + const struct grid_cell *tmp; + static struct visible_ranges r = { NULL, 0, 0 }; + u_int cell_type; + u_int x = ctx->ox + i, y = ctx->oy + j; + int isolates; if (c->overlay_check != NULL) { - r = c->overlay_check(c, c->overlay_data, x, y, 1); - if (r->nx[0] + r->nx[1] == 0) + c->overlay_check(c, c->overlay_data, x, y, 1, &r); + if (r.ranges[0].nx + r.ranges[1].nx == 0) return; } @@ -937,14 +938,14 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx) static void screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) { - struct client *c = ctx->c; - struct window *w = c->session->curw->window; - struct tty *tty = &c->tty; - struct screen *s = wp->screen; - struct colour_palette *palette = &wp->palette; - struct grid_cell defaults; - struct visible_ranges *vr; - u_int i, j, top, x, y, px, width, r; + struct client *c = ctx->c; + struct window *w = c->session->curw->window; + struct tty *tty = &c->tty; + struct screen *s = wp->screen; + struct colour_palette *palette = &wp->palette; + struct grid_cell defaults; + static struct visible_ranges vr; + u_int i, j, top, x, y, px, width, r; if (wp->base.mode & MODE_SYNC) screen_write_stop_sync(wp); @@ -989,21 +990,21 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) __func__, c->name, wp->id, i, j, x, y, width); /* xxxx Breaking up the tty_draw_line like this isn't fully working. */ - vr = tty_check_overlay_range(tty, x, y, width); + tty_check_overlay_range(tty, x, y, width, &vr); tty_default_colours(&defaults, wp); - for (r=0; r < vr->used; r++) { - if (vr->nx[r] == 0) + for (r=0; r < vr.used; r++) { + if (vr.ranges[r].nx == 0) continue; /* Convert window coordinates to tty coordinates. */ - px = vr->px[r]; + px = vr.ranges[r].px; /* i is px of cell, add px of region, sub the * pane offset. If you don't sub offset, * contents of pane shifted. note: i apparently unnec. */ - tty_draw_line(tty, s, /* i + */ vr->px[r] - wp->xoff, j, - vr->nx[r], px, y, &defaults, palette); + tty_draw_line(tty, s, /* i + */ vr.ranges[r].px - wp->xoff, j, + vr.ranges[r].nx, px, y, &defaults, palette); } } diff --git a/server-client.c b/server-client.c index a222ac6f..c4952a92 100644 --- a/server-client.c +++ b/server-client.c @@ -165,37 +165,36 @@ server_client_clear_overlay(struct client *c) * Given overlay position and dimensions, return parts of the input range which * are visible. */ -struct visible_ranges * +void server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px, - u_int py, u_int nx) + u_int py, u_int nx, struct visible_ranges *r) { u_int ox, onx; - static struct visible_ranges r = {NULL, NULL, 0, 0}; - /* For efficiency vr is static and space reused. */ - if (r.size == 0) { - r.px = xcalloc(2, sizeof(u_int)); - r.nx = xcalloc(2, sizeof(u_int)); - r.size = 2; + /* Caller must free when no longer used. */ + if (r->size == 0) { + r->ranges = xcalloc(2, sizeof(struct visible_range)); + r->size = 2; + r->used = 0; } /* Trivial case of no overlap in the y direction. */ if (py < y || py > y + sy - 1) { - r.px[0] = px; - r.nx[0] = nx; - r.used = 1; - return (&r); + r->ranges[0].px = px; + r->ranges[0].nx = nx; + r->used = 1; + return; } /* Visible bit to the left of the popup. */ if (px < x) { - r.px[0] = px; - r.nx[0] = x - px; - if (r.nx[0] > nx) - r.nx[0] = nx; + r->ranges[0].px = px; + r->ranges[0].nx = x - px; + if (r->ranges[0].nx > nx) + r->ranges[0].nx = nx; } else { - r.px[0] = 0; - r.nx[0] = 0; + r->ranges[0].px = 0; + r->ranges[0].nx = 0; } /* Visible bit to the right of the popup. */ @@ -204,14 +203,13 @@ server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px, ox = px; onx = px + nx; if (onx > ox) { - r.px[1] = ox; - r.nx[1] = onx - ox; + r->ranges[1].px = ox; + r->ranges[1].nx = onx - ox; } else { - r.px[1] = 0; - r.nx[1] = 0; + r->ranges[1].px = 0; + r->ranges[1].nx = 0; } - r.used = 2; - return (&r); + r->used = 2; } /* Check if this client is inside this server. */ diff --git a/tmux.h b/tmux.h index 424b6093..4544411c 100644 --- a/tmux.h +++ b/tmux.h @@ -1915,26 +1915,24 @@ struct client_window { }; RB_HEAD(client_windows, client_window); -/* Visible areas not obstructed by overlays. */ -#define OVERLAY_MAX_RANGES 3 -struct overlay_ranges { - u_int px[OVERLAY_MAX_RANGES]; - u_int nx[OVERLAY_MAX_RANGES]; +/* Visible range array element. */ +struct visible_range { + u_int px; /* Start */ + u_int nx; /* Length */ }; -/* Visible range array element. */ +/* Visible areas not obstructed. */ struct visible_ranges { - u_int *px; /* Start */ - u_int *nx; /* Length */ - size_t used; - size_t size; + struct visible_range *ranges; /* dynamically allocated array */ + size_t used; /* number of entries in ranges */ + size_t size; /* allocated capacity of ranges */ }; /* Client connection. */ typedef int (*prompt_input_cb)(struct client *, void *, const char *, int); typedef void (*prompt_free_cb)(void *); -typedef struct visible_ranges *(*overlay_check_cb)(struct client*, void *, - u_int, u_int, u_int); +typedef void (*overlay_check_cb)(struct client*, void *, u_int, u_int, u_int, + struct visible_ranges *); typedef struct screen *(*overlay_mode_cb)(struct client *, void *, u_int *, u_int *); typedef void (*overlay_draw_cb)(struct client *, void *, @@ -2561,8 +2559,8 @@ void tty_default_attributes(struct tty *, const struct grid_cell *, void tty_update_mode(struct tty *, int, struct screen *); const struct grid_cell *tty_check_codeset(struct tty *, const struct grid_cell *); -struct visible_ranges *tty_check_overlay_range(struct tty *, u_int, u_int, - u_int); +void tty_check_overlay_range(struct tty *, u_int, u_int, u_int, + struct visible_ranges *); /* tty-draw.c */ void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int, @@ -2922,8 +2920,8 @@ void server_client_set_overlay(struct client *, u_int, overlay_check_cb, overlay_mode_cb, overlay_draw_cb, overlay_key_cb, overlay_free_cb, overlay_resize_cb, void *); void server_client_clear_overlay(struct client *); -struct visible_ranges *server_client_overlay_range(u_int, u_int, u_int, u_int, u_int, u_int, - u_int); +void server_client_overlay_range(u_int, u_int, u_int, u_int, u_int, u_int, + u_int, struct visible_ranges *); void server_client_set_key_table(struct client *, const char *); const char *server_client_get_key_table(struct client *); int server_client_check_nested(struct client *); @@ -3625,7 +3623,8 @@ int menu_display(struct menu *, int, int, struct cmdq_item *, const char *, const char *, struct cmd_find_state *, menu_choice_cb, void *); struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *); -struct visible_ranges *menu_check_cb(struct client *, void *, u_int, u_int, u_int); +void menu_check_cb(struct client *, void *, u_int, u_int, u_int, + struct visible_ranges *); void menu_draw_cb(struct client *, void *, struct screen_redraw_ctx *); void menu_free_cb(struct client *, void *); diff --git a/tty-draw.c b/tty-draw.c index 3d77d4a1..d23bf39e 100644 --- a/tty-draw.c +++ b/tty-draw.c @@ -113,7 +113,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, struct colour_palette *palette) { struct grid *gd = s->grid; - struct grid_cell gc, *gcp, ngc, last; + const struct grid_cell *gcp; + struct grid_cell gc, ngc, last; struct grid_line *gl; u_int i, j, last_i, cx, ex, width; u_int cellsize, bg; diff --git a/tty.c b/tty.c index 2b5e91c5..081b56de 100644 --- a/tty.c +++ b/tty.c @@ -66,7 +66,8 @@ static void tty_emulate_repeat(struct tty *, enum tty_code_code, enum tty_code_code, u_int); static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int); static int tty_check_overlay(struct tty *, u_int, u_int); -struct visible_ranges *tty_check_overlay_range(struct tty *, u_int, u_int, u_int); +void tty_check_overlay_range(struct tty *, u_int, u_int, u_int, + struct visible_ranges *); #ifdef ENABLE_SIXEL static void tty_write_one(void (*)(struct tty *, const struct tty_ctx *), @@ -1160,8 +1161,6 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, u_int px, u_int nx, u_int bg) { struct client *c = tty->client; - struct visible_ranges *r; - u_int i; log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); @@ -1199,15 +1198,6 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, */ tty_cursor(tty, px, py); tty_repeat_space(tty, nx); - /* - r = tty_check_overlay_range(tty, px, py, nx); - for (i = 0; i < r->used; i++) { - if (r->nx[i] == 0) - continue; - tty_cursor(tty, r->px[i], py); - tty_repeat_space(tty, r->nx[i]); - } - */ } /* Clear a line, adjusting to visible part of pane. */ @@ -1442,41 +1432,45 @@ tty_cell_width(const struct grid_cell *gcp, u_int atcol) static int tty_check_overlay(struct tty *tty, u_int px, u_int py) { - struct visible_ranges *r; + static struct visible_ranges r = { NULL, 0, 0 }; /* * A unit width range will always return nx[2] == 0 from a check, even * with multiple overlays, so it's sufficient to check just the first * two entries. */ - r = tty_check_overlay_range(tty, px, py, 1); - if (r->nx[0] + r->nx[1] == 0) + if (r.size == 0) { + r.ranges = xcalloc(2, sizeof(struct visible_range)); + r.size = 2; + } + + tty_check_overlay_range(tty, px, py, 1, &r); + if (r.ranges[0].nx + r.ranges[1].nx == 0) return (0); return (1); } /* Return parts of the input range which are visible. */ -struct visible_ranges * -tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx) +void +tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx, + struct visible_ranges *r) { - static struct visible_ranges r = {NULL, NULL, 0, 0}; struct client *c = tty->client; - /* For efficiency vr is static and space reused. */ - if (r.size == 0) { - r.px = xcalloc(1, sizeof(u_int)); - r.nx = xcalloc(1, sizeof(u_int)); - r.size = 1; + if (r->size == 0) { + r->ranges = xcalloc(2, sizeof(struct visible_range)); + r->size = 2; } if (c->overlay_check == NULL) { - r.px[0] = px; - r.nx[0] = nx; - r.used = 1; - return (&r); + r->ranges[0].px = px; + r->ranges[0].nx = nx; + r->used = 1; + return; } - return (c->overlay_check(c, c->overlay_data, px, py, nx)); + c->overlay_check(c, c->overlay_data, px, py, nx, r); + return; } #ifdef ENABLE_SIXEL @@ -2004,7 +1998,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) { const struct grid_cell *gcp = ctx->cell; struct screen *s = ctx->s; - struct visible_ranges *r; + static struct visible_ranges r = { NULL, 0, 0 }; u_int px, py, i, vis = 0; px = ctx->xoff + ctx->ocx - ctx->wox; @@ -2021,9 +2015,9 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) /* Handle partially obstructed wide characters. */ if (gcp->data.width > 1) { - r = tty_check_overlay_range(tty, px, py, gcp->data.width); - for (i = 0; i < r->used; i++) - vis += r->nx[i]; + tty_check_overlay_range(tty, px, py, gcp->data.width, &r); + for (i = 0; i < r.used; i++) + vis += r.ranges[i].nx; if (vis < gcp->data.width) { tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width, px, py, &ctx->defaults, ctx->palette); @@ -2049,7 +2043,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) { - struct visible_ranges *r; + struct visible_ranges r = { NULL, 0, 0 }; u_int i, px, py, cx; char *cp = ctx->ptr; @@ -2080,14 +2074,14 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) px = ctx->xoff + ctx->ocx - ctx->wox; py = ctx->yoff + ctx->ocy - ctx->woy; - r = tty_check_overlay_range(tty, px, py, ctx->num); - for (i = 0; i < r->used; i++) { - if (r->nx[i] == 0) + tty_check_overlay_range(tty, px, py, ctx->num, &r); + for (i = 0; i < r.used; i++) { + if (r.ranges[i].nx == 0) continue; /* Convert back to pane position for printing. */ - cx = r->px[i] - ctx->xoff + ctx->wox; + cx = r.ranges[i].px - ctx->xoff + ctx->wox; tty_cursor_pane_unless_wrap(tty, ctx, cx, ctx->ocy); - tty_putn(tty, cp + r->px[i] - px, r->nx[i], r->nx[i]); + tty_putn(tty, cp + r.ranges[i].px - px, r.ranges[i].nx, r.ranges[i].nx); } }