mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-07-06 00:06:08 -04:00
grid: move 'cursor' state from terminal to grid
This way, the 'normal' and 'alt' grids have their own cursor state, and we don't need to switch between them.
This commit is contained in:
parent
c96a0b3b3c
commit
89559d5466
6 changed files with 136 additions and 129 deletions
128
csi.c
128
csi.c
|
|
@ -382,7 +382,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
/* VPA - vertical line position absolute */
|
/* VPA - vertical line position absolute */
|
||||||
int rel_row = vt_param_get(term, 0, 1) - 1;
|
int rel_row = vt_param_get(term, 0, 1) - 1;
|
||||||
int row = term_row_rel_to_abs(term, rel_row);
|
int row = term_row_rel_to_abs(term, rel_row);
|
||||||
term_cursor_to(term, row, term->cursor.point.col);
|
term_cursor_to(term, row, term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,13 +411,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 'E':
|
case 'E':
|
||||||
/* CNL - Cursor Next Line */
|
/* CNL - Cursor Next Line */
|
||||||
term_cursor_down(term, vt_param_get(term, 0, 1));
|
term_cursor_down(term, vt_param_get(term, 0, 1));
|
||||||
term_cursor_left(term, term->cursor.point.col);
|
term_cursor_left(term, term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F':
|
case 'F':
|
||||||
/* CPL - Cursor Previous Line */
|
/* CPL - Cursor Previous Line */
|
||||||
term_cursor_up(term, vt_param_get(term, 0, 1));
|
term_cursor_up(term, vt_param_get(term, 0, 1));
|
||||||
term_cursor_left(term, term->cursor.point.col);
|
term_cursor_left(term, term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g': {
|
case 'g': {
|
||||||
|
|
@ -426,9 +426,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 0:
|
case 0:
|
||||||
/* Clear tab stop at *current* column */
|
/* Clear tab stop at *current* column */
|
||||||
tll_foreach(term->tab_stops, it) {
|
tll_foreach(term->tab_stops, it) {
|
||||||
if (it->item == term->cursor.point.col)
|
if (it->item == term->grid->cursor.point.col)
|
||||||
tll_remove(term->tab_stops, it);
|
tll_remove(term->tab_stops, it);
|
||||||
else if (it->item > term->cursor.point.col)
|
else if (it->item > term->grid->cursor.point.col)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,7 +450,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 'G': {
|
case 'G': {
|
||||||
/* Cursor horizontal absolute */
|
/* Cursor horizontal absolute */
|
||||||
int col = min(vt_param_get(term, 0, 1), term->cols) - 1;
|
int col = min(vt_param_get(term, 0, 1), term->cols) - 1;
|
||||||
term_cursor_to(term, term->cursor.point.row, col);
|
term_cursor_to(term, term->grid->cursor.point.row, col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,15 +473,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
/* From cursor to end of screen */
|
/* From cursor to end of screen */
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&term->cursor.point,
|
&term->grid->cursor.point,
|
||||||
&(struct coord){term->cols - 1, term->rows - 1});
|
&(struct coord){term->cols - 1, term->rows - 1});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* From start of screen to cursor */
|
/* From start of screen to cursor */
|
||||||
term_erase(term, &(struct coord){0, 0}, &term->cursor.point);
|
term_erase(term, &(struct coord){0, 0}, &term->grid->cursor.point);
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -490,7 +490,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
term,
|
term,
|
||||||
&(struct coord){0, 0},
|
&(struct coord){0, 0},
|
||||||
&(struct coord){term->cols - 1, term->rows - 1});
|
&(struct coord){term->cols - 1, term->rows - 1});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: {
|
case 3: {
|
||||||
|
|
@ -531,25 +531,25 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
/* From cursor to end of line */
|
/* From cursor to end of line */
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&term->cursor.point,
|
&term->grid->cursor.point,
|
||||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* From start of line to cursor */
|
/* From start of line to cursor */
|
||||||
term_erase(
|
term_erase(
|
||||||
term, &(struct coord){0, term->cursor.point.row}, &term->cursor.point);
|
term, &(struct coord){0, term->grid->cursor.point.row}, &term->grid->cursor.point);
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
/* Entire line */
|
/* Entire line */
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&(struct coord){0, term->cursor.point.row},
|
&(struct coord){0, term->grid->cursor.point.row},
|
||||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -561,36 +561,36 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L': {
|
case 'L': {
|
||||||
if (term->cursor.point.row < term->scroll_region.start ||
|
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||||
term->cursor.point.row >= term->scroll_region.end)
|
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int count = min(
|
int count = min(
|
||||||
vt_param_get(term, 0, 1),
|
vt_param_get(term, 0, 1),
|
||||||
term->scroll_region.end - term->cursor.point.row);
|
term->scroll_region.end - term->grid->cursor.point.row);
|
||||||
|
|
||||||
term_scroll_reverse_partial(
|
term_scroll_reverse_partial(
|
||||||
term,
|
term,
|
||||||
(struct scroll_region){
|
(struct scroll_region){
|
||||||
.start = term->cursor.point.row,
|
.start = term->grid->cursor.point.row,
|
||||||
.end = term->scroll_region.end},
|
.end = term->scroll_region.end},
|
||||||
count);
|
count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'M': {
|
case 'M': {
|
||||||
if (term->cursor.point.row < term->scroll_region.start ||
|
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||||
term->cursor.point.row >= term->scroll_region.end)
|
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int count = min(
|
int count = min(
|
||||||
vt_param_get(term, 0, 1),
|
vt_param_get(term, 0, 1),
|
||||||
term->scroll_region.end - term->cursor.point.row);
|
term->scroll_region.end - term->grid->cursor.point.row);
|
||||||
|
|
||||||
term_scroll_partial(
|
term_scroll_partial(
|
||||||
term,
|
term,
|
||||||
(struct scroll_region){
|
(struct scroll_region){
|
||||||
.start = term->cursor.point.row,
|
.start = term->grid->cursor.point.row,
|
||||||
.end = term->scroll_region.end},
|
.end = term->scroll_region.end},
|
||||||
count);
|
count);
|
||||||
break;
|
break;
|
||||||
|
|
@ -601,26 +601,26 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
|
|
||||||
/* Number of characters to delete */
|
/* Number of characters to delete */
|
||||||
int count = min(
|
int count = min(
|
||||||
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
|
vt_param_get(term, 0, 1), term->cols - term->grid->cursor.point.col);
|
||||||
|
|
||||||
/* Number of characters left after deletion (on current line) */
|
/* Number of characters left after deletion (on current line) */
|
||||||
int remaining = term->cols - (term->cursor.point.col + count);
|
int remaining = term->cols - (term->grid->cursor.point.col + count);
|
||||||
|
|
||||||
/* 'Delete' characters by moving the remaining ones */
|
/* 'Delete' characters by moving the remaining ones */
|
||||||
memmove(&term->grid->cur_row->cells[term->cursor.point.col],
|
memmove(&term->grid->cur_row->cells[term->grid->cursor.point.col],
|
||||||
&term->grid->cur_row->cells[term->cursor.point.col + count],
|
&term->grid->cur_row->cells[term->grid->cursor.point.col + count],
|
||||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||||
|
|
||||||
for (size_t c = 0; c < remaining; c++)
|
for (size_t c = 0; c < remaining; c++)
|
||||||
term->grid->cur_row->cells[term->cursor.point.col + c].attrs.clean = 0;
|
term->grid->cur_row->cells[term->grid->cursor.point.col + c].attrs.clean = 0;
|
||||||
term->grid->cur_row->dirty = true;
|
term->grid->cur_row->dirty = true;
|
||||||
|
|
||||||
/* Erase the remainder of the line */
|
/* Erase the remainder of the line */
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&(struct coord){term->cursor.point.col + remaining, term->cursor.point.row},
|
&(struct coord){term->grid->cursor.point.col + remaining, term->grid->cursor.point.row},
|
||||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,25 +629,25 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
|
|
||||||
/* Number of characters to insert */
|
/* Number of characters to insert */
|
||||||
int count = min(
|
int count = min(
|
||||||
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
|
vt_param_get(term, 0, 1), term->cols - term->grid->cursor.point.col);
|
||||||
|
|
||||||
/* Characters to move */
|
/* Characters to move */
|
||||||
int remaining = term->cols - (term->cursor.point.col + count);
|
int remaining = term->cols - (term->grid->cursor.point.col + count);
|
||||||
|
|
||||||
/* Push existing characters */
|
/* Push existing characters */
|
||||||
memmove(&term->grid->cur_row->cells[term->cursor.point.col + count],
|
memmove(&term->grid->cur_row->cells[term->grid->cursor.point.col + count],
|
||||||
&term->grid->cur_row->cells[term->cursor.point.col],
|
&term->grid->cur_row->cells[term->grid->cursor.point.col],
|
||||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||||
for (size_t c = 0; c < remaining; c++)
|
for (size_t c = 0; c < remaining; c++)
|
||||||
term->grid->cur_row->cells[term->cursor.point.col + count + c].attrs.clean = 0;
|
term->grid->cur_row->cells[term->grid->cursor.point.col + count + c].attrs.clean = 0;
|
||||||
term->grid->cur_row->dirty = true;
|
term->grid->cur_row->dirty = true;
|
||||||
|
|
||||||
/* Erase (insert space characters) */
|
/* Erase (insert space characters) */
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&term->cursor.point,
|
&term->grid->cursor.point,
|
||||||
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
|
&(struct coord){term->grid->cursor.point.col + count - 1, term->grid->cursor.point.row});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -662,13 +662,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 'X': {
|
case 'X': {
|
||||||
/* Erase chars */
|
/* Erase chars */
|
||||||
int count = min(
|
int count = min(
|
||||||
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
|
vt_param_get(term, 0, 1), term->cols - term->grid->cursor.point.col);
|
||||||
|
|
||||||
term_erase(
|
term_erase(
|
||||||
term,
|
term,
|
||||||
&term->cursor.point,
|
&term->grid->cursor.point,
|
||||||
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
|
&(struct coord){term->grid->cursor.point.col + count - 1, term->grid->cursor.point.row});
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -677,13 +677,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
for (int i = 0; i < vt_param_get(term, 0, 1); i++) {
|
for (int i = 0; i < vt_param_get(term, 0, 1); i++) {
|
||||||
int new_col = term->cols - 1;
|
int new_col = term->cols - 1;
|
||||||
tll_foreach(term->tab_stops, it) {
|
tll_foreach(term->tab_stops, it) {
|
||||||
if (it->item > term->cursor.point.col) {
|
if (it->item > term->grid->cursor.point.col) {
|
||||||
new_col = it->item;
|
new_col = it->item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(new_col >= term->cursor.point.col);
|
assert(new_col >= term->grid->cursor.point.col);
|
||||||
term_cursor_right(term, new_col - term->cursor.point.col);
|
term_cursor_right(term, new_col - term->grid->cursor.point.col);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -693,13 +693,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
for (int i = 0; i < vt_param_get(term, 0, 1); i++) {
|
for (int i = 0; i < vt_param_get(term, 0, 1); i++) {
|
||||||
int new_col = 0;
|
int new_col = 0;
|
||||||
tll_rforeach(term->tab_stops, it) {
|
tll_rforeach(term->tab_stops, it) {
|
||||||
if (it->item < term->cursor.point.col) {
|
if (it->item < term->grid->cursor.point.col) {
|
||||||
new_col = it->item;
|
new_col = it->item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(term->cursor.point.col >= new_col);
|
assert(term->grid->cursor.point.col >= new_col);
|
||||||
term_cursor_left(term, term->cursor.point.col - new_col);
|
term_cursor_left(term, term->grid->cursor.point.col - new_col);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -757,11 +757,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
term->saved_cursor = term->cursor;
|
term->grid->saved_cursor = term->grid->cursor;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
term_restore_cursor(term, &term->saved_cursor);
|
term_restore_cursor(term, &term->grid->saved_cursor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't': {
|
case 't': {
|
||||||
|
|
@ -861,15 +861,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
/* u7 - cursor position query */
|
/* u7 - cursor position query */
|
||||||
|
|
||||||
int row = term->origin == ORIGIN_ABSOLUTE
|
int row = term->origin == ORIGIN_ABSOLUTE
|
||||||
? term->cursor.point.row
|
? term->grid->cursor.point.row
|
||||||
: term->cursor.point.row - term->scroll_region.start;
|
: term->grid->cursor.point.row - term->scroll_region.start;
|
||||||
|
|
||||||
/* TODO: we use 0-based position, while the xterm
|
/* TODO: we use 0-based position, while the xterm
|
||||||
* terminfo says the receiver of the reply should
|
* terminfo says the receiver of the reply should
|
||||||
* decrement, hence we must add 1 */
|
* decrement, hence we must add 1 */
|
||||||
char reply[64];
|
char reply[64];
|
||||||
snprintf(reply, sizeof(reply), "\x1b[%d;%dR",
|
snprintf(reply, sizeof(reply), "\x1b[%d;%dR",
|
||||||
row + 1, term->cursor.point.col + 1);
|
row + 1, term->grid->cursor.point.col + 1);
|
||||||
term_to_slave(term, reply, strlen(reply));
|
term_to_slave(term, reply, strlen(reply));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1014,9 +1014,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
|
|
||||||
term->grid = &term->alt;
|
term->grid = &term->alt;
|
||||||
term->alt_saved_cursor = term->cursor;
|
|
||||||
|
|
||||||
term_cursor_to(term, term->cursor.point.row, term->cursor.point.col);
|
term_cursor_to(
|
||||||
|
term,
|
||||||
|
min(term->grid->cursor.point.row, term->rows - 1),
|
||||||
|
min(term->grid->cursor.point.col, term->cols - 1));
|
||||||
|
|
||||||
tll_free(term->alt.damage);
|
tll_free(term->alt.damage);
|
||||||
tll_free(term->alt.scroll_damage);
|
tll_free(term->alt.scroll_damage);
|
||||||
|
|
@ -1137,7 +1139,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
|
|
||||||
term->grid = &term->normal;
|
term->grid = &term->normal;
|
||||||
term_restore_cursor(term, &term->alt_saved_cursor);
|
|
||||||
|
term_cursor_to(
|
||||||
|
term,
|
||||||
|
min(term->grid->cursor.point.row, term->rows - 1),
|
||||||
|
min(term->grid->cursor.point.col, term->cols - 1));
|
||||||
|
|
||||||
tll_free(term->alt.damage);
|
tll_free(term->alt.damage);
|
||||||
tll_free(term->alt.scroll_damage);
|
tll_free(term->alt.scroll_damage);
|
||||||
|
|
|
||||||
22
render.c
22
render.c
|
|
@ -1373,7 +1373,7 @@ grid_render(struct terminal *term)
|
||||||
*/
|
*/
|
||||||
bool cursor_is_visible = false;
|
bool cursor_is_visible = false;
|
||||||
int view_end = (term->grid->view + term->rows - 1) & (term->grid->num_rows - 1);
|
int view_end = (term->grid->view + term->rows - 1) & (term->grid->num_rows - 1);
|
||||||
int cursor_row = (term->grid->offset + term->cursor.point.row) & (term->grid->num_rows - 1);
|
int cursor_row = (term->grid->offset + term->grid->cursor.point.row) & (term->grid->num_rows - 1);
|
||||||
if (view_end >= term->grid->view) {
|
if (view_end >= term->grid->view) {
|
||||||
/* Not wrapped */
|
/* Not wrapped */
|
||||||
if (cursor_row >= term->grid->view && cursor_row <= view_end)
|
if (cursor_row >= term->grid->view && cursor_row <= view_end)
|
||||||
|
|
@ -1401,21 +1401,21 @@ grid_render(struct terminal *term)
|
||||||
int view_aligned_row
|
int view_aligned_row
|
||||||
= (cursor_row - term->grid->view + term->grid->num_rows) & (term->grid->num_rows - 1);
|
= (cursor_row - term->grid->view + term->grid->num_rows) & (term->grid->num_rows - 1);
|
||||||
|
|
||||||
term->render.last_cursor.actual = term->cursor.point;
|
term->render.last_cursor.actual = term->grid->cursor.point;
|
||||||
term->render.last_cursor.in_view = (struct coord) {
|
term->render.last_cursor.in_view = (struct coord) {
|
||||||
term->cursor.point.col, view_aligned_row};
|
term->grid->cursor.point.col, view_aligned_row};
|
||||||
|
|
||||||
struct row *row = grid_row_in_view(term->grid, view_aligned_row);
|
struct row *row = grid_row_in_view(term->grid, view_aligned_row);
|
||||||
struct cell *cell = &row->cells[term->cursor.point.col];
|
struct cell *cell = &row->cells[term->grid->cursor.point.col];
|
||||||
|
|
||||||
cell->attrs.clean = 0;
|
cell->attrs.clean = 0;
|
||||||
term->render.last_cursor.cell = cell;
|
term->render.last_cursor.cell = cell;
|
||||||
int cols_updated = render_cell(
|
int cols_updated = render_cell(
|
||||||
term, buf->pix, cell, term->cursor.point.col, view_aligned_row, true);
|
term, buf->pix, cell, term->grid->cursor.point.col, view_aligned_row, true);
|
||||||
|
|
||||||
wl_surface_damage_buffer(
|
wl_surface_damage_buffer(
|
||||||
term->window->surface,
|
term->window->surface,
|
||||||
term->margins.left + term->cursor.point.col * term->cell_width,
|
term->margins.left + term->grid->cursor.point.col * term->cell_width,
|
||||||
term->margins.top + view_aligned_row * term->cell_height,
|
term->margins.top + view_aligned_row * term->cell_height,
|
||||||
cols_updated * term->cell_width, term->cell_height);
|
cols_updated * term->cell_width, term->cell_height);
|
||||||
}
|
}
|
||||||
|
|
@ -1804,7 +1804,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
term_cursor_to(
|
term_cursor_to(
|
||||||
term,
|
term,
|
||||||
cursor_row,
|
cursor_row,
|
||||||
min(term->cursor.point.col, term->cols - 1));
|
min(term->grid->cursor.point.col, term->cols - 1));
|
||||||
|
|
||||||
/* If in alt screen, update the saved 'normal' cursor too */
|
/* If in alt screen, update the saved 'normal' cursor too */
|
||||||
if (term->grid == &term->alt) {
|
if (term->grid == &term->alt) {
|
||||||
|
|
@ -1813,10 +1813,10 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
while (cursor_row < 0)
|
while (cursor_row < 0)
|
||||||
cursor_row += term->grid->num_rows;
|
cursor_row += term->grid->num_rows;
|
||||||
|
|
||||||
term->alt_saved_cursor.lcf = false;
|
term->normal.cursor.lcf = false;
|
||||||
term->alt_saved_cursor.point.row = cursor_row;
|
term->normal.cursor.point.row = cursor_row;
|
||||||
term->alt_saved_cursor.point.col = min(
|
term->normal.cursor.point.col = min(
|
||||||
term->alt_saved_cursor.point.col, term->cols - 1);
|
term->normal.cursor.point.col, term->cols - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
term->render.last_cursor.cell = NULL;
|
term->render.last_cursor.cell = NULL;
|
||||||
|
|
|
||||||
6
sixel.c
6
sixel.c
|
|
@ -125,7 +125,7 @@ sixel_delete_in_range(struct terminal *term, int _start, int _end)
|
||||||
void
|
void
|
||||||
sixel_delete_at_cursor(struct terminal *term)
|
sixel_delete_at_cursor(struct terminal *term)
|
||||||
{
|
{
|
||||||
sixel_delete_at_row(term, term->cursor.point.row);
|
sixel_delete_at_row(term, term->grid->cursor.point.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -142,8 +142,8 @@ sixel_unhook(struct terminal *term)
|
||||||
.height = term->sixel.image.height,
|
.height = term->sixel.image.height,
|
||||||
.rows = (term->sixel.image.height + term->cell_height - 1) / term->cell_height,
|
.rows = (term->sixel.image.height + term->cell_height - 1) / term->cell_height,
|
||||||
.pos = (struct coord){
|
.pos = (struct coord){
|
||||||
term->cursor.point.col,
|
term->grid->cursor.point.col,
|
||||||
(term->grid->offset + term->cursor.point.row) & (term->grid->num_rows - 1)},
|
(term->grid->offset + term->grid->cursor.point.row) & (term->grid->num_rows - 1)},
|
||||||
};
|
};
|
||||||
|
|
||||||
LOG_DBG("generating %dx%d pixman image", image.width, image.height);
|
LOG_DBG("generating %dx%d pixman image", image.width, image.height);
|
||||||
|
|
|
||||||
87
terminal.c
87
terminal.c
|
|
@ -354,7 +354,7 @@ term_arm_blink_timer(struct terminal *term)
|
||||||
static void
|
static void
|
||||||
cursor_refresh(struct terminal *term)
|
cursor_refresh(struct terminal *term)
|
||||||
{
|
{
|
||||||
term->grid->cur_row->cells[term->cursor.point.col].attrs.clean = 0;
|
term->grid->cur_row->cells[term->grid->cursor.point.col].attrs.clean = 0;
|
||||||
term->grid->cur_row->dirty = true;
|
term->grid->cur_row->dirty = true;
|
||||||
render_refresh(term);
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
@ -1163,7 +1163,6 @@ term_reset(struct terminal *term, bool hard)
|
||||||
|
|
||||||
if (term->grid == &term->alt) {
|
if (term->grid == &term->alt) {
|
||||||
term->grid = &term->normal;
|
term->grid = &term->normal;
|
||||||
term_restore_cursor(term, &term->alt_saved_cursor);
|
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1188,10 +1187,12 @@ term_reset(struct terminal *term, bool hard)
|
||||||
for (size_t i = 0; i < 256; i++)
|
for (size_t i = 0; i < 256; i++)
|
||||||
term->colors.table[i] = term->colors.default_table[i];
|
term->colors.table[i] = term->colors.default_table[i];
|
||||||
term->origin = ORIGIN_ABSOLUTE;
|
term->origin = ORIGIN_ABSOLUTE;
|
||||||
term->cursor.lcf = false;
|
term->normal.cursor.lcf = false;
|
||||||
term->cursor = (struct cursor){.point = {0, 0}};
|
term->alt.cursor.lcf = false;
|
||||||
term->saved_cursor = (struct cursor){.point = {0, 0}};
|
term->normal.cursor = (struct cursor){.point = {0, 0}};
|
||||||
term->alt_saved_cursor = (struct cursor){.point = {0, 0}};
|
term->normal.saved_cursor = (struct cursor){.point = {0, 0}};
|
||||||
|
term->alt.cursor = (struct cursor){.point = {0, 0}};
|
||||||
|
term->alt.saved_cursor = (struct cursor){.point = {0, 0}};
|
||||||
term->cursor_style = term->default_cursor_style;
|
term->cursor_style = term->default_cursor_style;
|
||||||
term_cursor_blink_disable(term);
|
term_cursor_blink_disable(term);
|
||||||
term->cursor_color.text = term->default_cursor_color.text;
|
term->cursor_color.text = term->default_cursor_color.text;
|
||||||
|
|
@ -1431,10 +1432,10 @@ term_cursor_to(struct terminal *term, int row, int col)
|
||||||
assert(row < term->rows);
|
assert(row < term->rows);
|
||||||
assert(col < term->cols);
|
assert(col < term->cols);
|
||||||
|
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
|
|
||||||
term->cursor.point.col = col;
|
term->grid->cursor.point.col = col;
|
||||||
term->cursor.point.row = row;
|
term->grid->cursor.point.row = row;
|
||||||
|
|
||||||
term->grid->cur_row = grid_row(term->grid, row);
|
term->grid->cur_row = grid_row(term->grid, row);
|
||||||
}
|
}
|
||||||
|
|
@ -1448,39 +1449,39 @@ term_cursor_home(struct terminal *term)
|
||||||
void
|
void
|
||||||
term_cursor_left(struct terminal *term, int count)
|
term_cursor_left(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int move_amount = min(term->cursor.point.col, count);
|
int move_amount = min(term->grid->cursor.point.col, count);
|
||||||
term->cursor.point.col -= move_amount;
|
term->grid->cursor.point.col -= move_amount;
|
||||||
assert(term->cursor.point.col >= 0);
|
assert(term->grid->cursor.point.col >= 0);
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_right(struct terminal *term, int count)
|
term_cursor_right(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int move_amount = min(term->cols - term->cursor.point.col - 1, count);
|
int move_amount = min(term->cols - term->grid->cursor.point.col - 1, count);
|
||||||
term->cursor.point.col += move_amount;
|
term->grid->cursor.point.col += move_amount;
|
||||||
assert(term->cursor.point.col < term->cols);
|
assert(term->grid->cursor.point.col < term->cols);
|
||||||
term->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_up(struct terminal *term, int count)
|
term_cursor_up(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int top = term->origin == ORIGIN_ABSOLUTE ? 0 : term->scroll_region.start;
|
int top = term->origin == ORIGIN_ABSOLUTE ? 0 : term->scroll_region.start;
|
||||||
assert(term->cursor.point.row >= top);
|
assert(term->grid->cursor.point.row >= top);
|
||||||
|
|
||||||
int move_amount = min(term->cursor.point.row - top, count);
|
int move_amount = min(term->grid->cursor.point.row - top, count);
|
||||||
term_cursor_to(term, term->cursor.point.row - move_amount, term->cursor.point.col);
|
term_cursor_to(term, term->grid->cursor.point.row - move_amount, term->grid->cursor.point.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_down(struct terminal *term, int count)
|
term_cursor_down(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int bottom = term->origin == ORIGIN_ABSOLUTE ? term->rows : term->scroll_region.end;
|
int bottom = term->origin == ORIGIN_ABSOLUTE ? term->rows : term->scroll_region.end;
|
||||||
assert(bottom >= term->cursor.point.row);
|
assert(bottom >= term->grid->cursor.point.row);
|
||||||
|
|
||||||
int move_amount = min(bottom - term->cursor.point.row - 1, count);
|
int move_amount = min(bottom - term->grid->cursor.point.row - 1, count);
|
||||||
term_cursor_to(term, term->cursor.point.row + move_amount, term->cursor.point.col);
|
term_cursor_to(term, term->grid->cursor.point.row + move_amount, term->grid->cursor.point.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -1569,7 +1570,7 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
||||||
|
|
||||||
sixel_delete_in_range(term, max(region.end - rows, region.start), region.end - 1);
|
sixel_delete_in_range(term, max(region.end - rows, region.start), region.end - 1);
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||||
term->grid->cur_row = grid_row(term->grid, term->cursor.point.row);
|
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1622,7 +1623,7 @@ term_scroll_reverse_partial(struct terminal *term,
|
||||||
|
|
||||||
sixel_delete_in_range(term, region.start, min(region.start + rows, region.end) - 1);
|
sixel_delete_in_range(term, region.start, min(region.start + rows, region.end) - 1);
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||||
term->grid->cur_row = grid_row(term->grid, term->cursor.point.row);
|
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1634,14 +1635,14 @@ term_scroll_reverse(struct terminal *term, int rows)
|
||||||
void
|
void
|
||||||
term_formfeed(struct terminal *term)
|
term_formfeed(struct terminal *term)
|
||||||
{
|
{
|
||||||
term_cursor_left(term, term->cursor.point.col);
|
term_cursor_left(term, term->grid->cursor.point.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_linefeed(struct terminal *term)
|
term_linefeed(struct terminal *term)
|
||||||
{
|
{
|
||||||
term->grid->cur_row->linebreak = true;
|
term->grid->cur_row->linebreak = true;
|
||||||
if (term->cursor.point.row == term->scroll_region.end - 1)
|
if (term->grid->cursor.point.row == term->scroll_region.end - 1)
|
||||||
term_scroll(term, 1);
|
term_scroll(term, 1);
|
||||||
else
|
else
|
||||||
term_cursor_down(term, 1);
|
term_cursor_down(term, 1);
|
||||||
|
|
@ -1650,7 +1651,7 @@ term_linefeed(struct terminal *term)
|
||||||
void
|
void
|
||||||
term_reverse_index(struct terminal *term)
|
term_reverse_index(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (term->cursor.point.row == term->scroll_region.start)
|
if (term->grid->cursor.point.row == term->scroll_region.start)
|
||||||
term_scroll_reverse(term, 1);
|
term_scroll_reverse(term, 1);
|
||||||
else
|
else
|
||||||
term_cursor_up(term, 1);
|
term_cursor_up(term, 1);
|
||||||
|
|
@ -1672,7 +1673,7 @@ term_restore_cursor(struct terminal *term, const struct cursor *cursor)
|
||||||
int row = min(cursor->point.row, term->rows - 1);
|
int row = min(cursor->point.row, term->rows - 1);
|
||||||
int col = min(cursor->point.col, term->cols - 1);
|
int col = min(cursor->point.col, term->cols - 1);
|
||||||
term_cursor_to(term, row, col);
|
term_cursor_to(term, row, col);
|
||||||
term->cursor.lcf = cursor->lcf;
|
term->grid->cursor.lcf = cursor->lcf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2095,7 +2096,7 @@ term_disable_app_sync_updates(struct terminal *term)
|
||||||
static inline void
|
static inline void
|
||||||
print_linewrap(struct terminal *term)
|
print_linewrap(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (likely(!term->cursor.lcf)) {
|
if (likely(!term->grid->cursor.lcf)) {
|
||||||
/* Not and end of line */
|
/* Not and end of line */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2105,11 +2106,11 @@ print_linewrap(struct terminal *term)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (term->cursor.point.row == term->scroll_region.end - 1) {
|
if (term->grid->cursor.point.row == term->scroll_region.end - 1) {
|
||||||
term_scroll(term, 1);
|
term_scroll(term, 1);
|
||||||
term_cursor_to(term, term->cursor.point.row, 0);
|
term_cursor_to(term, term->grid->cursor.point.row, 0);
|
||||||
} else
|
} else
|
||||||
term_cursor_to(term, min(term->cursor.point.row + 1, term->rows - 1), 0);
|
term_cursor_to(term, min(term->grid->cursor.point.row + 1, term->rows - 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
@ -2119,15 +2120,15 @@ print_insert(struct terminal *term, int width)
|
||||||
|
|
||||||
if (unlikely(term->insert_mode)) {
|
if (unlikely(term->insert_mode)) {
|
||||||
struct row *row = term->grid->cur_row;
|
struct row *row = term->grid->cur_row;
|
||||||
const size_t move_count = max(0, term->cols - term->cursor.point.col - width);
|
const size_t move_count = max(0, term->cols - term->grid->cursor.point.col - width);
|
||||||
|
|
||||||
memmove(
|
memmove(
|
||||||
&row->cells[term->cursor.point.col + width],
|
&row->cells[term->grid->cursor.point.col + width],
|
||||||
&row->cells[term->cursor.point.col],
|
&row->cells[term->grid->cursor.point.col],
|
||||||
move_count * sizeof(struct cell));
|
move_count * sizeof(struct cell));
|
||||||
|
|
||||||
/* Mark moved cells as dirty */
|
/* Mark moved cells as dirty */
|
||||||
for (size_t i = term->cursor.point.col + width; i < term->cols; i++)
|
for (size_t i = term->grid->cursor.point.col + width; i < term->cols; i++)
|
||||||
row->cells[i].attrs.clean = 0;
|
row->cells[i].attrs.clean = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2145,7 +2146,7 @@ term_print(struct terminal *term, wchar_t wc, int width)
|
||||||
|
|
||||||
/* *Must* get current cell *after* linewrap+insert */
|
/* *Must* get current cell *after* linewrap+insert */
|
||||||
struct row *row = term->grid->cur_row;
|
struct row *row = term->grid->cur_row;
|
||||||
struct cell *cell = &row->cells[term->cursor.point.col];
|
struct cell *cell = &row->cells[term->grid->cursor.point.col];
|
||||||
|
|
||||||
cell->wc = term->vt.last_printed = wc;
|
cell->wc = term->vt.last_printed = wc;
|
||||||
cell->attrs = term->vt.attrs;
|
cell->attrs = term->vt.attrs;
|
||||||
|
|
@ -2154,20 +2155,20 @@ term_print(struct terminal *term, wchar_t wc, int width)
|
||||||
cell->attrs.clean = 0;
|
cell->attrs.clean = 0;
|
||||||
|
|
||||||
/* Advance cursor the 'additional' columns while dirty:ing the cells */
|
/* Advance cursor the 'additional' columns while dirty:ing the cells */
|
||||||
for (int i = 1; i < width && term->cursor.point.col < term->cols - 1; i++) {
|
for (int i = 1; i < width && term->grid->cursor.point.col < term->cols - 1; i++) {
|
||||||
term_cursor_right(term, 1);
|
term_cursor_right(term, 1);
|
||||||
|
|
||||||
assert(term->cursor.point.col < term->cols);
|
assert(term->grid->cursor.point.col < term->cols);
|
||||||
struct cell *cell = &row->cells[term->cursor.point.col];
|
struct cell *cell = &row->cells[term->grid->cursor.point.col];
|
||||||
cell->wc = 0;
|
cell->wc = 0;
|
||||||
cell->attrs.clean = 0;
|
cell->attrs.clean = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
if (term->cursor.point.col < term->cols - 1)
|
if (term->grid->cursor.point.col < term->cols - 1)
|
||||||
term_cursor_right(term, 1);
|
term_cursor_right(term, 1);
|
||||||
else
|
else
|
||||||
term->cursor.lcf = true;
|
term->grid->cursor.lcf = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum term_surface
|
enum term_surface
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ struct grid {
|
||||||
int offset;
|
int offset;
|
||||||
int view;
|
int view;
|
||||||
|
|
||||||
|
struct cursor cursor;
|
||||||
|
struct cursor saved_cursor;
|
||||||
|
|
||||||
struct row **rows;
|
struct row **rows;
|
||||||
struct row *cur_row;
|
struct row *cur_row;
|
||||||
|
|
||||||
|
|
@ -278,9 +281,6 @@ struct terminal {
|
||||||
} colors;
|
} colors;
|
||||||
|
|
||||||
enum cursor_origin origin;
|
enum cursor_origin origin;
|
||||||
struct cursor cursor;
|
|
||||||
struct cursor saved_cursor;
|
|
||||||
struct cursor alt_saved_cursor;
|
|
||||||
enum cursor_style default_cursor_style;
|
enum cursor_style default_cursor_style;
|
||||||
enum cursor_style cursor_style;
|
enum cursor_style cursor_style;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
16
vt.c
16
vt.c
|
|
@ -146,13 +146,13 @@ action_execute(struct terminal *term, uint8_t c)
|
||||||
/* HT - horizontal tab */
|
/* HT - horizontal tab */
|
||||||
int new_col = term->cols - 1;
|
int new_col = term->cols - 1;
|
||||||
tll_foreach(term->tab_stops, it) {
|
tll_foreach(term->tab_stops, it) {
|
||||||
if (it->item > term->cursor.point.col) {
|
if (it->item > term->grid->cursor.point.col) {
|
||||||
new_col = it->item;
|
new_col = it->item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(new_col >= term->cursor.point.col);
|
assert(new_col >= term->grid->cursor.point.col);
|
||||||
term_cursor_right(term, new_col - term->cursor.point.col);
|
term_cursor_right(term, new_col - term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,13 +341,13 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 0:
|
case 0:
|
||||||
switch (final) {
|
switch (final) {
|
||||||
case '7':
|
case '7':
|
||||||
term->saved_cursor = term->cursor;
|
term->grid->saved_cursor = term->grid->cursor;
|
||||||
term->vt.saved_attrs = term->vt.attrs;
|
term->vt.saved_attrs = term->vt.attrs;
|
||||||
term->saved_charsets = term->charsets;
|
term->saved_charsets = term->charsets;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '8':
|
case '8':
|
||||||
term_restore_cursor(term, &term->saved_cursor);
|
term_restore_cursor(term, &term->grid->saved_cursor);
|
||||||
term->vt.attrs = term->vt.saved_attrs;
|
term->vt.attrs = term->vt.saved_attrs;
|
||||||
term->charsets = term->saved_charsets;
|
term->charsets = term->saved_charsets;
|
||||||
break;
|
break;
|
||||||
|
|
@ -367,13 +367,13 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
tll_foreach(term->tab_stops, it) {
|
tll_foreach(term->tab_stops, it) {
|
||||||
if (it->item >= term->cursor.point.col) {
|
if (it->item >= term->grid->cursor.point.col) {
|
||||||
tll_insert_before(term->tab_stops, it, term->cursor.point.col);
|
tll_insert_before(term->tab_stops, it, term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_push_back(term->tab_stops, term->cursor.point.col);
|
tll_push_back(term->tab_stops, term->grid->cursor.point.col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue