From 0f48b4f8f70b10c48f934d4354ed15dd0ed5cb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 29 Jun 2019 21:23:36 +0200 Subject: [PATCH] terminal: prepare for floating grids --- csi.c | 14 ++++++------ main.c | 62 ++++++++++++++++++++++++++++-------------------------- terminal.c | 44 +++++++++++++++++++------------------- terminal.h | 10 ++++++--- vt.c | 2 +- 5 files changed, 69 insertions(+), 63 deletions(-) diff --git a/csi.c b/csi.c index d1b72489..83f089ee 100644 --- a/csi.c +++ b/csi.c @@ -466,9 +466,9 @@ csi_dispatch(struct terminal *term, uint8_t final) /* Move remaining (up til the right margin) characters */ int remaining = max_end - end; - memmove(&term->grid.cells[start], - &term->grid.cells[end], - remaining * sizeof(term->grid.cells[0])); + memmove(&term->grid->cells[start], + &term->grid->cells[end], + remaining * sizeof(term->grid->cells[0])); term_damage_update(term, term->cursor.linear, remaining); break; } @@ -581,8 +581,8 @@ csi_dispatch(struct terminal *term, uint8_t final) break; case 1049: - if (term->grid.cells != term->grid.alt_grid) { - term->grid.cells = term->grid.alt_grid; + if (term->grid != &term->alt) { + term->grid = &term->alt; term->saved_cursor = term->cursor; term_damage_all(term); } @@ -634,8 +634,8 @@ csi_dispatch(struct terminal *term, uint8_t final) break; case 1049: - if (term->grid.cells == term->grid.alt_grid) { - term->grid.cells = term->grid.normal_grid; + if (term->grid == &term->alt) { + term->grid = &term->normal; term->cursor = term->saved_cursor; diff --git a/main.c b/main.c index 93740fc9..f4f9eaa7 100644 --- a/main.c +++ b/main.c @@ -95,7 +95,7 @@ grid_render_update(struct context *c, struct buffer *buf, const struct damage *d { //LOG_DBG("UPDATE: %d (%dx%d)", linear_cursor, row, col); - const struct cell *cell = &c->term.grid.cells[linear_cursor]; + const struct cell *cell = &c->term.grid->cells[linear_cursor]; bool has_cursor = c->term.cursor.linear == linear_cursor; int x = col * c->term.cell_width; @@ -337,8 +337,8 @@ grid_render_scroll_reverse(struct context *c, struct buffer *buf, static void grid_render(struct context *c) { - if (tll_length(c->term.grid.damage) == 0 && - tll_length(c->term.grid.scroll_damage) == 0) + if (tll_length(c->term.grid->damage) == 0 && + tll_length(c->term.grid->scroll_damage) == 0) { return; } @@ -350,7 +350,7 @@ grid_render(struct context *c) cairo_set_operator(buf->cairo, CAIRO_OPERATOR_SOURCE); - tll_foreach(c->term.grid.scroll_damage, it) { + tll_foreach(c->term.grid->scroll_damage, it) { switch (it->item.type) { case DAMAGE_SCROLL: grid_render_scroll(c, buf, &it->item); @@ -366,10 +366,10 @@ grid_render(struct context *c) break; } - tll_remove(c->term.grid.scroll_damage, it); + tll_remove(c->term.grid->scroll_damage, it); } - tll_foreach(c->term.grid.damage, it) { + tll_foreach(c->term.grid->damage, it) { switch (it->item.type) { case DAMAGE_ERASE: grid_render_erase(c, buf, &it->item); break; case DAMAGE_UPDATE: grid_render_update(c, buf, &it->item); break; @@ -380,7 +380,7 @@ grid_render(struct context *c) break; } - tll_remove(c->term.grid.damage, it); + tll_remove(c->term.grid->damage, it); } //cairo_surface_flush(buf->cairo_surface); @@ -409,42 +409,41 @@ resize(struct context *c, int width, int height) if (width == c->width && height == c->height) return; - bool alt_screen_active - = c->term.grid.cells != NULL && c->term.grid.cells == c->term.grid.alt_grid; - c->width = width; c->height = height; const size_t old_rows = c->term.rows; - const size_t old_cols = c->term.cols; - const size_t old_cells_len = old_rows * old_cols; + const size_t normal_old_size = c->term.normal.size; + const size_t alt_old_size = c->term.alt.size; c->term.cell_width = (int)ceil(c->fextents.max_x_advance); c->term.cell_height = (int)ceil(c->fextents.height); c->term.cols = c->width / c->term.cell_width; c->term.rows = c->height / c->term.cell_height; - c->term.grid.normal_grid = realloc( - c->term.grid.normal_grid, - c->term.cols * c->term.rows * sizeof(c->term.grid.cells[0])); - c->term.grid.alt_grid = realloc( - c->term.grid.alt_grid, - c->term.cols * c->term.rows * sizeof(c->term.grid.cells[0])); + c->term.normal.size = c->term.cols * c->term.rows; + c->term.alt.size = c->term.cols * c->term.rows; - size_t new_cells_len = c->term.cols * c->term.rows; - for (size_t i = old_cells_len; i < new_cells_len; i++) { - c->term.grid.normal_grid[i] = (struct cell){ - .attrs = {.foreground = default_foreground, - .background = default_background}, - }; - c->term.grid.alt_grid[i] = (struct cell){ + c->term.normal.cells = realloc( + c->term.normal.cells, + c->term.cols * c->term.rows * sizeof(c->term.normal.cells[0])); + c->term.alt.cells = realloc( + c->term.alt.cells, + c->term.cols * c->term.rows * sizeof(c->term.alt.cells[0])); + + for (size_t i = normal_old_size; i < c->term.normal.size; i++) { + c->term.normal.cells[i] = (struct cell){ .attrs = {.foreground = default_foreground, .background = default_background}, }; } - c->term.grid.cells = alt_screen_active - ? c->term.grid.alt_grid : c->term.grid.normal_grid; + for (size_t i = alt_old_size; i < c->term.alt.size; i++) { + c->term.alt.cells[i] = (struct cell){ + .attrs = {.foreground = default_foreground, + .background = default_background}, + }; + } LOG_DBG("resize: %dx%d, grid: cols=%d, rows=%d", c->width, c->height, c->term.cols, c->term.rows); @@ -743,7 +742,6 @@ main(int argc, const char *const *argv) .vt = { .state = 1, /* STATE_GROUND */ }, - .grid = {.damage = tll_init()}, .kbd = { .repeat = { .pipe_read_fd = repeat_pipe_fds[0], @@ -753,6 +751,10 @@ main(int argc, const char *const *argv) }, .foreground = default_foreground, .background = default_background, + + .normal = {.damage = tll_init(), .scroll_damage = tll_init()}, + .alt = {.damage = tll_init(), .scroll_damage = tll_init()}, + .grid = &c.term.normal, }, }; @@ -945,8 +947,8 @@ out: if (c.wl.display != NULL) wl_display_disconnect(c.wl.display); - free(c.term.grid.normal_grid); - free(c.term.grid.alt_grid); + free(c.term.normal.cells); + free(c.term.alt.cells); for (size_t i = 0; i < sizeof(c.fonts) / sizeof(c.fonts[0]); i++) { if (c.fonts[i] != NULL) diff --git a/terminal.c b/terminal.c index dcff32e3..482452c5 100644 --- a/terminal.c +++ b/terminal.c @@ -13,10 +13,10 @@ static bool damage_merge_range(struct terminal *term, const struct damage *dmg) { - if (tll_length(term->grid.damage) == 0) + if (tll_length(term->grid->damage) == 0) return false; - struct damage *old = &tll_back(term->grid.damage); + struct damage *old = &tll_back(term->grid->damage); if (old->type != dmg->type) return false; @@ -64,7 +64,7 @@ term_damage_update_or_erase(struct terminal *term, enum damage_type damage_type, if (damage_merge_range(term, &dmg)) return; - tll_push_back(term->grid.damage, dmg); + tll_push_back(term->grid->damage, dmg); } void @@ -82,8 +82,8 @@ term_damage_erase(struct terminal *term, int start, int length) void term_damage_all(struct terminal *term) { - tll_free(term->grid.damage); - tll_free(term->grid.scroll_damage); + tll_free(term->grid->damage); + tll_free(term->grid->scroll_damage); term_damage_update(term, 0, term->rows * term->cols); } @@ -97,7 +97,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type, const int scroll_start = region.start * term->cols; const int scroll_end = region.end * term->cols; - tll_foreach(term->grid.damage, it) { + tll_foreach(term->grid->damage, it) { int start = it->item.range.start; int length = it->item.range.length; int end = start + length; @@ -109,7 +109,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type, .range = {.start = start, .length = scroll_start - start}, }; - tll_push_back(term->grid.damage, outside); + tll_push_back(term->grid->damage, outside); start = scroll_start; length = end - start; @@ -122,7 +122,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type, .range = {.start = scroll_end, .length = length - scroll_end}, }; - tll_push_back(term->grid.damage, outside); + tll_push_back(term->grid->damage, outside); end = scroll_end; length = end - start; } @@ -138,7 +138,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type, assert(new_length < length); if (new_length <= 0) - tll_remove(term->grid.damage, it); + tll_remove(term->grid->damage, it); else { it->item.range.start = scroll_start; it->item.range.length = new_length; @@ -148,7 +148,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type, if (start + length > scroll_end) { /* Scrolled down outside scroll region */ if (start >= scroll_end) - tll_remove(term->grid.damage, it); + tll_remove(term->grid->damage, it); else { it->item.range.start = start; it->item.range.length = scroll_end - start; @@ -164,8 +164,8 @@ term_damage_scroll(struct terminal *term, enum damage_type damage_type, { damage_adjust_after_scroll(term, damage_type, region, lines); - if (tll_length(term->grid.scroll_damage) > 0) { - struct damage *dmg = &tll_back(term->grid.scroll_damage); + if (tll_length(term->grid->scroll_damage) > 0) { + struct damage *dmg = &tll_back(term->grid->scroll_damage); if (dmg->type == damage_type && dmg->scroll.region.start == region.start && @@ -179,14 +179,14 @@ term_damage_scroll(struct terminal *term, enum damage_type damage_type, .type = damage_type, .scroll = {.region = region, .lines = lines}, }; - tll_push_back(term->grid.scroll_damage, dmg); + tll_push_back(term->grid->scroll_damage, dmg); } void term_erase(struct terminal *term, int start, int end) { assert(end >= start); - memset(&term->grid.cells[start], 0, (end - start) * sizeof(term->grid.cells[0])); + memset(&term->grid->cells[start], 0, (end - start) * sizeof(term->grid->cells[0])); term_damage_erase(term, start, end - start); } @@ -260,13 +260,13 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows LOG_DBG("moving %d lines from row %d to row %d", cell_count / term->cols, cell_src / term->cols, cell_dst / term->cols); - const size_t bytes = cell_count * sizeof(term->grid.cells[0]); + const size_t bytes = cell_count * sizeof(term->grid->cells[0]); memmove( - &term->grid.cells[cell_dst], &term->grid.cells[cell_src], + &term->grid->cells[cell_dst], &term->grid->cells[cell_src], bytes); - memset(&term->grid.cells[(region.end - rows) * term->cols], 0, - rows * term->cols * sizeof(term->grid.cells[0])); + memset(&term->grid->cells[(region.end - rows) * term->cols], 0, + rows * term->cols * sizeof(term->grid->cells[0])); term_damage_scroll(term, DAMAGE_SCROLL, region, rows); } @@ -293,13 +293,13 @@ term_scroll_reverse_partial(struct terminal *term, LOG_DBG("moving %d lines from row %d to row %d", cell_count / term->cols, cell_src / term->cols, cell_dst / term->cols); - const size_t bytes = cell_count * sizeof(term->grid.cells[0]); + const size_t bytes = cell_count * sizeof(term->grid->cells[0]); memmove( - &term->grid.cells[cell_dst], &term->grid.cells[cell_src], + &term->grid->cells[cell_dst], &term->grid->cells[cell_src], bytes); - memset(&term->grid.cells[cell_src], 0, - rows * term->cols * sizeof(term->grid.cells[0])); + memset(&term->grid->cells[cell_src], 0, + rows * term->cols * sizeof(term->grid->cells[0])); term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows); } diff --git a/terminal.h b/terminal.h index 5fb30e77..cceaa6b6 100644 --- a/terminal.h +++ b/terminal.h @@ -62,9 +62,10 @@ struct damage { }; struct grid { + size_t size; + size_t offset; + struct cell *cells; - struct cell *normal_grid; - struct cell *alt_grid; tll(struct damage) damage; tll(struct damage) scroll_damage; @@ -134,7 +135,6 @@ struct terminal { bool bracketed_paste; struct vt vt; - struct grid grid; struct kbd kbd; int cols; @@ -151,6 +151,10 @@ struct terminal { struct cursor cursor; struct cursor saved_cursor; struct cursor alt_saved_cursor; + + struct grid normal; + struct grid alt; + struct grid *grid; }; void term_damage_all(struct terminal *term); diff --git a/vt.c b/vt.c index c6d05d46..cb0b8a90 100644 --- a/vt.c +++ b/vt.c @@ -678,7 +678,7 @@ action(struct terminal *term, enum action action, uint8_t c) term_cursor_to(term, term->cursor.row + 1, 0); } - struct cell *cell = &term->grid.cells[term->cursor.linear]; + struct cell *cell = &term->grid->cells[term->cursor.linear]; term_damage_update(term, term->cursor.linear, 1); if (term->vt.utf8.idx > 0) {