mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-03 07:15:29 -04:00
terminal: prepare for floating grids
This commit is contained in:
parent
8cff861f38
commit
0f48b4f8f7
5 changed files with 69 additions and 63 deletions
14
csi.c
14
csi.c
|
|
@ -466,9 +466,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
|
|
||||||
/* Move remaining (up til the right margin) characters */
|
/* Move remaining (up til the right margin) characters */
|
||||||
int remaining = max_end - end;
|
int remaining = max_end - end;
|
||||||
memmove(&term->grid.cells[start],
|
memmove(&term->grid->cells[start],
|
||||||
&term->grid.cells[end],
|
&term->grid->cells[end],
|
||||||
remaining * sizeof(term->grid.cells[0]));
|
remaining * sizeof(term->grid->cells[0]));
|
||||||
term_damage_update(term, term->cursor.linear, remaining);
|
term_damage_update(term, term->cursor.linear, remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -581,8 +581,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1049:
|
case 1049:
|
||||||
if (term->grid.cells != term->grid.alt_grid) {
|
if (term->grid != &term->alt) {
|
||||||
term->grid.cells = term->grid.alt_grid;
|
term->grid = &term->alt;
|
||||||
term->saved_cursor = term->cursor;
|
term->saved_cursor = term->cursor;
|
||||||
term_damage_all(term);
|
term_damage_all(term);
|
||||||
}
|
}
|
||||||
|
|
@ -634,8 +634,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1049:
|
case 1049:
|
||||||
if (term->grid.cells == term->grid.alt_grid) {
|
if (term->grid == &term->alt) {
|
||||||
term->grid.cells = term->grid.normal_grid;
|
term->grid = &term->normal;
|
||||||
|
|
||||||
term->cursor = term->saved_cursor;
|
term->cursor = term->saved_cursor;
|
||||||
|
|
||||||
|
|
|
||||||
62
main.c
62
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);
|
//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;
|
bool has_cursor = c->term.cursor.linear == linear_cursor;
|
||||||
|
|
||||||
int x = col * c->term.cell_width;
|
int x = col * c->term.cell_width;
|
||||||
|
|
@ -337,8 +337,8 @@ grid_render_scroll_reverse(struct context *c, struct buffer *buf,
|
||||||
static void
|
static void
|
||||||
grid_render(struct context *c)
|
grid_render(struct context *c)
|
||||||
{
|
{
|
||||||
if (tll_length(c->term.grid.damage) == 0 &&
|
if (tll_length(c->term.grid->damage) == 0 &&
|
||||||
tll_length(c->term.grid.scroll_damage) == 0)
|
tll_length(c->term.grid->scroll_damage) == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +350,7 @@ grid_render(struct context *c)
|
||||||
|
|
||||||
cairo_set_operator(buf->cairo, CAIRO_OPERATOR_SOURCE);
|
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) {
|
switch (it->item.type) {
|
||||||
case DAMAGE_SCROLL:
|
case DAMAGE_SCROLL:
|
||||||
grid_render_scroll(c, buf, &it->item);
|
grid_render_scroll(c, buf, &it->item);
|
||||||
|
|
@ -366,10 +366,10 @@ grid_render(struct context *c)
|
||||||
break;
|
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) {
|
switch (it->item.type) {
|
||||||
case DAMAGE_ERASE: grid_render_erase(c, buf, &it->item); break;
|
case DAMAGE_ERASE: grid_render_erase(c, buf, &it->item); break;
|
||||||
case DAMAGE_UPDATE: grid_render_update(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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_remove(c->term.grid.damage, it);
|
tll_remove(c->term.grid->damage, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cairo_surface_flush(buf->cairo_surface);
|
//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)
|
if (width == c->width && height == c->height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool alt_screen_active
|
|
||||||
= c->term.grid.cells != NULL && c->term.grid.cells == c->term.grid.alt_grid;
|
|
||||||
|
|
||||||
c->width = width;
|
c->width = width;
|
||||||
c->height = height;
|
c->height = height;
|
||||||
|
|
||||||
const size_t old_rows = c->term.rows;
|
const size_t old_rows = c->term.rows;
|
||||||
const size_t old_cols = c->term.cols;
|
const size_t normal_old_size = c->term.normal.size;
|
||||||
const size_t old_cells_len = old_rows * old_cols;
|
const size_t alt_old_size = c->term.alt.size;
|
||||||
|
|
||||||
c->term.cell_width = (int)ceil(c->fextents.max_x_advance);
|
c->term.cell_width = (int)ceil(c->fextents.max_x_advance);
|
||||||
c->term.cell_height = (int)ceil(c->fextents.height);
|
c->term.cell_height = (int)ceil(c->fextents.height);
|
||||||
c->term.cols = c->width / c->term.cell_width;
|
c->term.cols = c->width / c->term.cell_width;
|
||||||
c->term.rows = c->height / c->term.cell_height;
|
c->term.rows = c->height / c->term.cell_height;
|
||||||
|
|
||||||
c->term.grid.normal_grid = realloc(
|
c->term.normal.size = c->term.cols * c->term.rows;
|
||||||
c->term.grid.normal_grid,
|
c->term.alt.size = c->term.cols * c->term.rows;
|
||||||
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]));
|
|
||||||
|
|
||||||
size_t new_cells_len = c->term.cols * c->term.rows;
|
c->term.normal.cells = realloc(
|
||||||
for (size_t i = old_cells_len; i < new_cells_len; i++) {
|
c->term.normal.cells,
|
||||||
c->term.grid.normal_grid[i] = (struct cell){
|
c->term.cols * c->term.rows * sizeof(c->term.normal.cells[0]));
|
||||||
.attrs = {.foreground = default_foreground,
|
c->term.alt.cells = realloc(
|
||||||
.background = default_background},
|
c->term.alt.cells,
|
||||||
};
|
c->term.cols * c->term.rows * sizeof(c->term.alt.cells[0]));
|
||||||
c->term.grid.alt_grid[i] = (struct cell){
|
|
||||||
|
for (size_t i = normal_old_size; i < c->term.normal.size; i++) {
|
||||||
|
c->term.normal.cells[i] = (struct cell){
|
||||||
.attrs = {.foreground = default_foreground,
|
.attrs = {.foreground = default_foreground,
|
||||||
.background = default_background},
|
.background = default_background},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
c->term.grid.cells = alt_screen_active
|
for (size_t i = alt_old_size; i < c->term.alt.size; i++) {
|
||||||
? c->term.grid.alt_grid : c->term.grid.normal_grid;
|
c->term.alt.cells[i] = (struct cell){
|
||||||
|
.attrs = {.foreground = default_foreground,
|
||||||
|
.background = default_background},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DBG("resize: %dx%d, grid: cols=%d, rows=%d",
|
LOG_DBG("resize: %dx%d, grid: cols=%d, rows=%d",
|
||||||
c->width, c->height, c->term.cols, c->term.rows);
|
c->width, c->height, c->term.cols, c->term.rows);
|
||||||
|
|
@ -743,7 +742,6 @@ main(int argc, const char *const *argv)
|
||||||
.vt = {
|
.vt = {
|
||||||
.state = 1, /* STATE_GROUND */
|
.state = 1, /* STATE_GROUND */
|
||||||
},
|
},
|
||||||
.grid = {.damage = tll_init()},
|
|
||||||
.kbd = {
|
.kbd = {
|
||||||
.repeat = {
|
.repeat = {
|
||||||
.pipe_read_fd = repeat_pipe_fds[0],
|
.pipe_read_fd = repeat_pipe_fds[0],
|
||||||
|
|
@ -753,6 +751,10 @@ main(int argc, const char *const *argv)
|
||||||
},
|
},
|
||||||
.foreground = default_foreground,
|
.foreground = default_foreground,
|
||||||
.background = default_background,
|
.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)
|
if (c.wl.display != NULL)
|
||||||
wl_display_disconnect(c.wl.display);
|
wl_display_disconnect(c.wl.display);
|
||||||
|
|
||||||
free(c.term.grid.normal_grid);
|
free(c.term.normal.cells);
|
||||||
free(c.term.grid.alt_grid);
|
free(c.term.alt.cells);
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(c.fonts) / sizeof(c.fonts[0]); i++) {
|
for (size_t i = 0; i < sizeof(c.fonts) / sizeof(c.fonts[0]); i++) {
|
||||||
if (c.fonts[i] != NULL)
|
if (c.fonts[i] != NULL)
|
||||||
|
|
|
||||||
44
terminal.c
44
terminal.c
|
|
@ -13,10 +13,10 @@
|
||||||
static bool
|
static bool
|
||||||
damage_merge_range(struct terminal *term, const struct damage *dmg)
|
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;
|
return false;
|
||||||
|
|
||||||
struct damage *old = &tll_back(term->grid.damage);
|
struct damage *old = &tll_back(term->grid->damage);
|
||||||
if (old->type != dmg->type)
|
if (old->type != dmg->type)
|
||||||
return false;
|
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))
|
if (damage_merge_range(term, &dmg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tll_push_back(term->grid.damage, dmg);
|
tll_push_back(term->grid->damage, dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -82,8 +82,8 @@ term_damage_erase(struct terminal *term, int start, int length)
|
||||||
void
|
void
|
||||||
term_damage_all(struct terminal *term)
|
term_damage_all(struct terminal *term)
|
||||||
{
|
{
|
||||||
tll_free(term->grid.damage);
|
tll_free(term->grid->damage);
|
||||||
tll_free(term->grid.scroll_damage);
|
tll_free(term->grid->scroll_damage);
|
||||||
term_damage_update(term, 0, term->rows * term->cols);
|
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_start = region.start * term->cols;
|
||||||
const int scroll_end = region.end * 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 start = it->item.range.start;
|
||||||
int length = it->item.range.length;
|
int length = it->item.range.length;
|
||||||
int end = start + 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},
|
.range = {.start = start, .length = scroll_start - start},
|
||||||
};
|
};
|
||||||
|
|
||||||
tll_push_back(term->grid.damage, outside);
|
tll_push_back(term->grid->damage, outside);
|
||||||
start = scroll_start;
|
start = scroll_start;
|
||||||
length = end - 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},
|
.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;
|
end = scroll_end;
|
||||||
length = end - start;
|
length = end - start;
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +138,7 @@ damage_adjust_after_scroll(struct terminal *term, enum damage_type damage_type,
|
||||||
assert(new_length < length);
|
assert(new_length < length);
|
||||||
|
|
||||||
if (new_length <= 0)
|
if (new_length <= 0)
|
||||||
tll_remove(term->grid.damage, it);
|
tll_remove(term->grid->damage, it);
|
||||||
else {
|
else {
|
||||||
it->item.range.start = scroll_start;
|
it->item.range.start = scroll_start;
|
||||||
it->item.range.length = new_length;
|
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) {
|
if (start + length > scroll_end) {
|
||||||
/* Scrolled down outside scroll region */
|
/* Scrolled down outside scroll region */
|
||||||
if (start >= scroll_end)
|
if (start >= scroll_end)
|
||||||
tll_remove(term->grid.damage, it);
|
tll_remove(term->grid->damage, it);
|
||||||
else {
|
else {
|
||||||
it->item.range.start = start;
|
it->item.range.start = start;
|
||||||
it->item.range.length = scroll_end - 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);
|
damage_adjust_after_scroll(term, damage_type, region, lines);
|
||||||
|
|
||||||
if (tll_length(term->grid.scroll_damage) > 0) {
|
if (tll_length(term->grid->scroll_damage) > 0) {
|
||||||
struct damage *dmg = &tll_back(term->grid.scroll_damage);
|
struct damage *dmg = &tll_back(term->grid->scroll_damage);
|
||||||
|
|
||||||
if (dmg->type == damage_type &&
|
if (dmg->type == damage_type &&
|
||||||
dmg->scroll.region.start == region.start &&
|
dmg->scroll.region.start == region.start &&
|
||||||
|
|
@ -179,14 +179,14 @@ term_damage_scroll(struct terminal *term, enum damage_type damage_type,
|
||||||
.type = damage_type,
|
.type = damage_type,
|
||||||
.scroll = {.region = region, .lines = lines},
|
.scroll = {.region = region, .lines = lines},
|
||||||
};
|
};
|
||||||
tll_push_back(term->grid.scroll_damage, dmg);
|
tll_push_back(term->grid->scroll_damage, dmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_erase(struct terminal *term, int start, int end)
|
term_erase(struct terminal *term, int start, int end)
|
||||||
{
|
{
|
||||||
assert(end >= start);
|
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);
|
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,
|
LOG_DBG("moving %d lines from row %d to row %d", cell_count / term->cols,
|
||||||
cell_src / term->cols, cell_dst / 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(
|
memmove(
|
||||||
&term->grid.cells[cell_dst], &term->grid.cells[cell_src],
|
&term->grid->cells[cell_dst], &term->grid->cells[cell_src],
|
||||||
bytes);
|
bytes);
|
||||||
|
|
||||||
memset(&term->grid.cells[(region.end - rows) * term->cols], 0,
|
memset(&term->grid->cells[(region.end - rows) * term->cols], 0,
|
||||||
rows * term->cols * sizeof(term->grid.cells[0]));
|
rows * term->cols * sizeof(term->grid->cells[0]));
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
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,
|
LOG_DBG("moving %d lines from row %d to row %d", cell_count / term->cols,
|
||||||
cell_src / term->cols, cell_dst / 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(
|
memmove(
|
||||||
&term->grid.cells[cell_dst], &term->grid.cells[cell_src],
|
&term->grid->cells[cell_dst], &term->grid->cells[cell_src],
|
||||||
bytes);
|
bytes);
|
||||||
|
|
||||||
memset(&term->grid.cells[cell_src], 0,
|
memset(&term->grid->cells[cell_src], 0,
|
||||||
rows * term->cols * sizeof(term->grid.cells[0]));
|
rows * term->cols * sizeof(term->grid->cells[0]));
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
terminal.h
10
terminal.h
|
|
@ -62,9 +62,10 @@ struct damage {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grid {
|
struct grid {
|
||||||
|
size_t size;
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
struct cell *cells;
|
struct cell *cells;
|
||||||
struct cell *normal_grid;
|
|
||||||
struct cell *alt_grid;
|
|
||||||
|
|
||||||
tll(struct damage) damage;
|
tll(struct damage) damage;
|
||||||
tll(struct damage) scroll_damage;
|
tll(struct damage) scroll_damage;
|
||||||
|
|
@ -134,7 +135,6 @@ struct terminal {
|
||||||
bool bracketed_paste;
|
bool bracketed_paste;
|
||||||
|
|
||||||
struct vt vt;
|
struct vt vt;
|
||||||
struct grid grid;
|
|
||||||
struct kbd kbd;
|
struct kbd kbd;
|
||||||
|
|
||||||
int cols;
|
int cols;
|
||||||
|
|
@ -151,6 +151,10 @@ struct terminal {
|
||||||
struct cursor cursor;
|
struct cursor cursor;
|
||||||
struct cursor saved_cursor;
|
struct cursor saved_cursor;
|
||||||
struct cursor alt_saved_cursor;
|
struct cursor alt_saved_cursor;
|
||||||
|
|
||||||
|
struct grid normal;
|
||||||
|
struct grid alt;
|
||||||
|
struct grid *grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
void term_damage_all(struct terminal *term);
|
void term_damage_all(struct terminal *term);
|
||||||
|
|
|
||||||
2
vt.c
2
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);
|
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);
|
term_damage_update(term, term->cursor.linear, 1);
|
||||||
|
|
||||||
if (term->vt.utf8.idx > 0) {
|
if (term->vt.utf8.idx > 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue