mirror of
https://github.com/tmux/tmux.git
synced 2025-12-18 00:02:54 -05:00
Cleanup - screen_redraw_get_visible_ranges returns a value rather than pass addr of arg. Bugfix to redraw code.
This commit is contained in:
parent
5faf41b695
commit
ce03f1abea
147
screen-redraw.c
147
screen-redraw.c
@ -887,28 +887,30 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
|
|||||||
|
|
||||||
/* Construct ranges of line at px,py of width cells of base_wp that are
|
/* Construct ranges of line at px,py of width cells of base_wp that are
|
||||||
unobsructed. */
|
unobsructed. */
|
||||||
void
|
struct visible_ranges *
|
||||||
screen_redraw_get_visible_ranges(u_int px, u_int py, u_int width,
|
screen_redraw_get_visible_ranges(u_int px, u_int py, u_int width,
|
||||||
struct window_pane *base_wp, struct visible_range **vr_p,
|
struct window_pane *base_wp) {
|
||||||
int *vr_count_p) {
|
struct window_pane *wp;
|
||||||
struct window_pane *wp;
|
struct window *w;
|
||||||
struct window *w;
|
static struct visible_ranges ranges = { NULL, 0, 0 };
|
||||||
struct visible_range *vr;
|
static struct visible_range *vr;
|
||||||
int found_self, r, s;
|
int found_self;
|
||||||
int vr_len, vr_count;
|
u_int r, s;
|
||||||
|
|
||||||
/* Caller must call free(vr). */
|
/* For efficiency ranges is static and space reused. */
|
||||||
vr = xcalloc(4, sizeof(struct visible_range *));
|
if (ranges.array == NULL) {
|
||||||
vr_len = 4;
|
ranges.array = xcalloc(4, sizeof(struct visible_range *));
|
||||||
|
ranges.size = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start with the entire width of the range. */
|
||||||
|
vr = ranges.array;
|
||||||
vr[0].px = px;
|
vr[0].px = px;
|
||||||
vr[0].nx = width;
|
vr[0].nx = width;
|
||||||
vr_count = 1;
|
ranges.n = 1;
|
||||||
|
|
||||||
if (base_wp == NULL) {
|
if (base_wp == NULL)
|
||||||
*vr_p = vr;
|
return (&ranges);
|
||||||
*vr_count_p = vr_count;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = base_wp->window;
|
w = base_wp->window;
|
||||||
|
|
||||||
@ -917,50 +919,59 @@ screen_redraw_get_visible_ranges(u_int px, u_int py, u_int width,
|
|||||||
found_self = 1;
|
found_self = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (found_self && wp->layout_cell == NULL &&
|
|
||||||
!(wp->flags & PANE_MINIMISED) &&
|
if (!found_self || wp->layout_cell != NULL ||
|
||||||
(py >= wp->yoff && py <= wp->yoff + wp->sy)) {
|
(wp->flags & PANE_MINIMISED) ||
|
||||||
for (r=0; r<vr_count; r++) {
|
(py < wp->yoff || py > wp->yoff + wp->sy))
|
||||||
/* if the left edge of wp
|
continue;
|
||||||
falls inside this range and right
|
|
||||||
edge greater than this range,
|
for (r=0; r<ranges.n; r++) {
|
||||||
then shrink nx */
|
/* If the left edge of floating wp
|
||||||
if (wp->xoff > vr[r].px &&
|
falls inside this range and right
|
||||||
wp->xoff < vr[r].px + vr[r].nx &&
|
edge covers up to right of range,
|
||||||
wp->xoff + wp->sx > vr[r].px + vr[r].nx) {
|
then shrink left edge of range. */
|
||||||
vr[r].nx = wp->xoff;
|
if (wp->xoff > vr[r].px &&
|
||||||
/* else if the right edge of wp
|
wp->xoff < vr[r].px + vr[r].nx &&
|
||||||
falls inside of this range and left
|
wp->xoff + wp->sx >= vr[r].px + vr[r].nx) {
|
||||||
edge is less than the start of the range,
|
vr[r].nx = wp->xoff;
|
||||||
then move px forward */
|
|
||||||
} else if (wp->xoff + wp->sx > vr[r].px &&
|
|
||||||
wp->xoff + wp->sx < vr[r].px + vr[r].nx &&
|
|
||||||
wp->xoff < vr[r].px) {
|
|
||||||
vr[r].px = vr[r].px + (wp->xoff + wp->sx);
|
|
||||||
vr[r].nx = vr[r].nx - (wp->xoff + wp->sx);
|
|
||||||
/* else if wp fully inside range
|
|
||||||
then split range into 2 ranges */
|
|
||||||
} else if (wp->xoff > vr[r].px &&
|
|
||||||
wp->xoff + wp->sx < vr[r].px + vr[r].nx) {
|
|
||||||
/* make space */
|
|
||||||
if (vr_len == vr_count) {
|
|
||||||
vr = xreallocarray(vr, vr_len +
|
|
||||||
4, sizeof *vr);
|
|
||||||
vr_len += 4;
|
|
||||||
}
|
|
||||||
for (s=vr_count; s>r; s--) {
|
|
||||||
vr[s].px = vr[s-1].px;
|
|
||||||
vr[s].nx = vr[s-1].nx;
|
|
||||||
}
|
|
||||||
vr[r].nx = wp->xoff;
|
|
||||||
vr[r+1].px = wp->xoff + wp->sx;
|
|
||||||
vr_count++;
|
|
||||||
} /* XXX what if it's completely obscured? */
|
|
||||||
}
|
}
|
||||||
|
/* Else if the right edge of floating wp
|
||||||
|
falls inside of this range and left
|
||||||
|
edge covers the left of range,
|
||||||
|
then move px forward to right edge of wp. */
|
||||||
|
else if (wp->xoff + wp->sx > vr[r].px &&
|
||||||
|
wp->xoff + wp->sx < vr[r].px + vr[r].nx &&
|
||||||
|
wp->xoff <= vr[r].px) {
|
||||||
|
vr[r].px = vr[r].px + (wp->xoff + wp->sx);
|
||||||
|
vr[r].nx = vr[r].nx - (wp->xoff + wp->sx);
|
||||||
|
}
|
||||||
|
/* Else if wp fully inside range
|
||||||
|
then split range into 2 ranges. */
|
||||||
|
else if (wp->xoff > vr[r].px &&
|
||||||
|
wp->xoff + wp->sx < vr[r].px + vr[r].nx) {
|
||||||
|
if (ranges.size == ranges.n) {
|
||||||
|
ranges.array = xreallocarray(vr,
|
||||||
|
ranges.size += 4, sizeof *vr);
|
||||||
|
ranges.array = vr;
|
||||||
|
}
|
||||||
|
for (s=ranges.n; s>r; s--) {
|
||||||
|
vr[s].px = vr[s-1].px;
|
||||||
|
vr[s].nx = vr[s-1].nx;
|
||||||
|
}
|
||||||
|
vr[r].nx = wp->xoff;
|
||||||
|
vr[r+1].px = wp->xoff + wp->sx;
|
||||||
|
ranges.n++;
|
||||||
|
}
|
||||||
|
/* If floating wp completely covers this range
|
||||||
|
then delete it (make it 0 length). */
|
||||||
|
else if (wp->xoff <= vr[r].px &&
|
||||||
|
wp->xoff+wp->sx >= vr[r].px+vr[r].nx) {
|
||||||
|
vr[r].nx = 0;
|
||||||
|
}
|
||||||
|
/* Else the range is already obscured, do nothing. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*vr_p = vr;
|
return (&ranges);
|
||||||
*vr_count_p = vr_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -974,9 +985,9 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
struct screen *s = wp->screen;
|
struct screen *s = wp->screen;
|
||||||
struct colour_palette *palette = &wp->palette;
|
struct colour_palette *palette = &wp->palette;
|
||||||
struct grid_cell defaults;
|
struct grid_cell defaults;
|
||||||
|
struct visible_ranges *visible_ranges;
|
||||||
struct visible_range *vr;
|
struct visible_range *vr;
|
||||||
int vr_count, r;
|
u_int i, j, top, x, y, width, r;
|
||||||
u_int i, j, top, x, y, width;
|
|
||||||
|
|
||||||
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
|
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
|
||||||
|
|
||||||
@ -1019,15 +1030,21 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
|||||||
__func__, c->name, wp->id, i, j, x, y, width);
|
__func__, c->name, wp->id, i, j, x, y, width);
|
||||||
|
|
||||||
/* Get visible ranges of line before we draw it. */
|
/* Get visible ranges of line before we draw it. */
|
||||||
screen_redraw_get_visible_ranges(x, y, width, wp,
|
visible_ranges = screen_redraw_get_visible_ranges(x, y, width,
|
||||||
&vr, &vr_count);
|
wp);
|
||||||
|
vr = visible_ranges->array;
|
||||||
|
|
||||||
tty_default_colours(&defaults, wp);
|
tty_default_colours(&defaults, wp);
|
||||||
|
|
||||||
for (r=0; r<vr_count; r++)
|
for (r=0; r<visible_ranges->n; r++) {
|
||||||
tty_draw_line(tty, s, i + vr[r].px, j,
|
if (vr[r].nx == 0)
|
||||||
|
continue;
|
||||||
|
/* i is px of cell, add px of region, sub the
|
||||||
|
pane offset. If you don't sub offset,
|
||||||
|
contents of pane shifted. */
|
||||||
|
tty_draw_line(tty, s, i+vr[r].px-wp->xoff, j,
|
||||||
vr[r].nx, vr[r].px, y, &defaults, palette);
|
vr[r].nx, vr[r].px, y, &defaults, palette);
|
||||||
free(vr);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
|
|||||||
@ -1747,13 +1747,13 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_cline *cl_src, *cl_dst;
|
struct screen_write_cline *cl_src, *cl_dst;
|
||||||
u_int y, r_start, r_end;
|
u_int y, r, r_start, r_end;
|
||||||
u_int ci_start, ci_end, new_end;
|
u_int ci_start, ci_end, new_end;
|
||||||
char *saved;
|
char *saved;
|
||||||
struct screen_write_citem *ci, *new_ci;
|
struct screen_write_citem *ci, *new_ci;
|
||||||
struct window_pane *wp = ctx->wp;
|
struct window_pane *wp = ctx->wp;
|
||||||
|
struct visible_ranges *visible_ranges;
|
||||||
struct visible_range *vr;
|
struct visible_range *vr;
|
||||||
int vr_count, r;
|
|
||||||
|
|
||||||
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,
|
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,
|
||||||
s->rupper, s->rlower);
|
s->rupper, s->rlower);
|
||||||
@ -1766,11 +1766,10 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
for (y = s->rupper; y < s->rlower; y++) {
|
for (y = s->rupper; y < s->rlower; y++) {
|
||||||
cl_src = &s->write_list[y + 1];
|
cl_src = &s->write_list[y + 1];
|
||||||
cl_dst = &s->write_list[y];
|
cl_dst = &s->write_list[y];
|
||||||
vr = NULL;
|
|
||||||
vr_count = 0;
|
|
||||||
|
|
||||||
screen_redraw_get_visible_ranges(0, y, screen_size_x(s), wp,
|
visible_ranges = screen_redraw_get_visible_ranges(0, y,
|
||||||
&vr, &vr_count);
|
screen_size_x(s), wp);
|
||||||
|
vr = visible_ranges->array;
|
||||||
|
|
||||||
TAILQ_INIT(&cl_dst->items);
|
TAILQ_INIT(&cl_dst->items);
|
||||||
|
|
||||||
@ -1779,7 +1778,8 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
|
|
||||||
/* For each visible range, copy corresponding items from cl_src
|
/* For each visible range, copy corresponding items from cl_src
|
||||||
to cl_dst. */
|
to cl_dst. */
|
||||||
for (r = 0; r < vr_count; r++) {
|
for (r = 0; r < visible_ranges->n; r++) {
|
||||||
|
if (vr[r].nx == 0) continue;
|
||||||
r_start = vr[r].px;
|
r_start = vr[r].px;
|
||||||
r_end = vr[r].px + vr[r].nx;
|
r_end = vr[r].px + vr[r].nx;
|
||||||
|
|
||||||
@ -1806,7 +1806,6 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
entry);
|
entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(vr);
|
|
||||||
}
|
}
|
||||||
s->write_list[s->rlower].data = saved;
|
s->write_list[s->rlower].data = saved;
|
||||||
|
|
||||||
@ -1821,12 +1820,12 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct screen_write_citem *ci, *tmp;
|
struct screen_write_citem *ci, *tmp;
|
||||||
struct screen_write_cline *cl;
|
struct screen_write_cline *cl;
|
||||||
u_int y, cx, cy, last, items = 0;
|
u_int y, cx, cy, last, items = 0, r;
|
||||||
u_int r_start, r_end, ci_start, ci_end;
|
u_int r_start, r_end, ci_start, ci_end;
|
||||||
u_int wr_start, wr_end, wr_length;
|
u_int wr_start, wr_end, wr_length;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
struct visible_range *vr = NULL;
|
struct visible_ranges *visible_ranges;
|
||||||
int vr_count = 0;
|
struct visible_range *vr;
|
||||||
struct window_pane *wp = ctx->wp;
|
struct window_pane *wp = ctx->wp;
|
||||||
|
|
||||||
if (ctx->scrolled != 0) {
|
if (ctx->scrolled != 0) {
|
||||||
@ -1854,8 +1853,9 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
for (y = 0; y < screen_size_y(s); y++) {
|
for (y = 0; y < screen_size_y(s); y++) {
|
||||||
cl = &ctx->s->write_list[y];
|
cl = &ctx->s->write_list[y];
|
||||||
|
|
||||||
screen_redraw_get_visible_ranges(0, y, screen_size_x(s), wp,
|
visible_ranges = screen_redraw_get_visible_ranges(0, y,
|
||||||
&vr, &vr_count);
|
screen_size_x(s), wp);
|
||||||
|
vr = visible_ranges->array;
|
||||||
|
|
||||||
last = UINT_MAX;
|
last = UINT_MAX;
|
||||||
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||||
@ -1863,7 +1863,8 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
fatalx("collect list not in order: %u <= %u",
|
fatalx("collect list not in order: %u <= %u",
|
||||||
ci->x, last);
|
ci->x, last);
|
||||||
}
|
}
|
||||||
for (int r = 0; r < vr_count; r++) {
|
for (r = 0; r < visible_ranges->n; r++) {
|
||||||
|
if (vr[r].nx == 0) continue;
|
||||||
r_start = vr[r].px;
|
r_start = vr[r].px;
|
||||||
r_end = vr[r].px + vr[r].nx;
|
r_end = vr[r].px + vr[r].nx;
|
||||||
ci_start = ci->x;
|
ci_start = ci->x;
|
||||||
@ -1900,7 +1901,6 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|||||||
screen_write_free_citem(ci);
|
screen_write_free_citem(ci);
|
||||||
last = ci->x;
|
last = ci->x;
|
||||||
}
|
}
|
||||||
free(vr);
|
|
||||||
}
|
}
|
||||||
s->cx = cx; s->cy = cy;
|
s->cx = cx; s->cy = cy;
|
||||||
|
|
||||||
|
|||||||
13
tmux.h
13
tmux.h
@ -2235,8 +2235,13 @@ struct mode_tree_sort_criteria {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct visible_range {
|
struct visible_range {
|
||||||
u_int px;
|
u_int px; /* Start */
|
||||||
u_int nx;
|
u_int nx; /* Length */
|
||||||
|
};
|
||||||
|
struct visible_ranges {
|
||||||
|
struct visible_range *array;
|
||||||
|
size_t n; /* Elements used */
|
||||||
|
size_t size; /* Array size */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tmux.c */
|
/* tmux.c */
|
||||||
@ -3169,8 +3174,8 @@ void screen_write_alternateoff(struct screen_write_ctx *,
|
|||||||
/* screen-redraw.c */
|
/* screen-redraw.c */
|
||||||
void screen_redraw_screen(struct client *);
|
void screen_redraw_screen(struct client *);
|
||||||
void screen_redraw_pane(struct client *, struct window_pane *, int);
|
void screen_redraw_pane(struct client *, struct window_pane *, int);
|
||||||
void screen_redraw_get_visible_ranges(u_int, u_int, u_int,
|
struct visible_ranges *screen_redraw_get_visible_ranges(u_int, u_int, u_int,
|
||||||
struct window_pane *, struct visible_range **, int *);
|
struct window_pane *);
|
||||||
|
|
||||||
|
|
||||||
/* screen.c */
|
/* screen.c */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user