From fd87bca102321e5804fef74dac8a6d267ae46732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 13 Feb 2021 12:31:55 +0100 Subject: [PATCH] =?UTF-8?q?grid:=20enable=20rows=20to=20have=20=E2=80=98ex?= =?UTF-8?q?tra=E2=80=99=20data=20associated=20with=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds an ‘extra’ member to the row struct. It is a pointer to a struct containing extra data to be associated with this row. Initially, this struct contains a list of URL ranges. These define (OSC-8) URLs on this row. The ‘extra’ data is allocated on-demand. I.e. the pointer is NULL by default; it is *not* allocated by grid_row_alloc(). --- grid.c | 9 +++++++++ terminal.c | 28 ++++++++++++++++++++++++---- terminal.h | 11 +++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/grid.c b/grid.c index 6d6b6b3c..2f0033ec 100644 --- a/grid.c +++ b/grid.c @@ -33,6 +33,7 @@ grid_row_alloc(int cols, bool initialize) struct row *row = xmalloc(sizeof(*row)); row->dirty = false; row->linebreak = false; + row->extra = NULL; if (initialize) { row->cells = xcalloc(cols, sizeof(row->cells[0])); @@ -50,6 +51,14 @@ grid_row_free(struct row *row) if (row == NULL) return; + if (row->extra != NULL) { + tll_foreach(row->extra->uri_ranges, it) { + free(it->item.uri); + tll_remove(row->extra->uri_ranges, it); + } + } + + free(row->extra); free(row->cells); free(row); } diff --git a/terminal.c b/terminal.c index 0051ca6d..17b985a8 100644 --- a/terminal.c +++ b/terminal.c @@ -2154,8 +2154,18 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows grid_swap_row(term->grid, i - rows, i); /* Erase scrolled in lines */ - for (int r = region.end - rows; r < region.end; r++) - erase_line(term, grid_row_and_alloc(term->grid, r)); + for (int r = region.end - rows; r < region.end; r++) { + struct row *row = grid_row_and_alloc(term->grid, r); + if (unlikely(row->extra != NULL)) { + tll_foreach(row->extra->uri_ranges, it) { + free(it->item.uri); + tll_remove(row->extra->uri_ranges, it); + } + free(row->extra); + row->extra = NULL; + } + erase_line(term, row); + } term_damage_scroll(term, DAMAGE_SCROLL, region, rows); term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row); @@ -2222,8 +2232,18 @@ term_scroll_reverse_partial(struct terminal *term, grid_swap_row(term->grid, i, i - rows); /* Erase scrolled in lines */ - for (int r = region.start; r < region.start + rows; r++) - erase_line(term, grid_row_and_alloc(term->grid, r)); + for (int r = region.start; r < region.start + rows; r++) { + struct row *row = grid_row_and_alloc(term->grid, r); + if (unlikely(row->extra != NULL)) { + tll_foreach(row->extra->uri_ranges, it) { + free(it->item.uri); + tll_remove(row->extra->uri_ranges, it); + } + free(row->extra); + row->extra = NULL; + } + erase_line(term, row); + } term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows); term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row); diff --git a/terminal.h b/terminal.h index 39d02859..7df92efc 100644 --- a/terminal.h +++ b/terminal.h @@ -86,10 +86,21 @@ struct composed { uint8_t count; }; +struct row_uri_range { + int start; + int end; + char *uri; +}; + +struct row_data { + tll(struct row_uri_range) uri_ranges; +}; + struct row { struct cell *cells; bool dirty; bool linebreak; + struct row_data *extra; }; struct sixel {