mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-05-05 06:47:25 -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 */
|
||||
int rel_row = vt_param_get(term, 0, 1) - 1;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -411,13 +411,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 'E':
|
||||
/* CNL - Cursor Next Line */
|
||||
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;
|
||||
|
||||
case 'F':
|
||||
/* CPL - Cursor Previous Line */
|
||||
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;
|
||||
|
||||
case 'g': {
|
||||
|
|
@ -426,9 +426,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 0:
|
||||
/* Clear tab stop at *current* column */
|
||||
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);
|
||||
else if (it->item > term->cursor.point.col)
|
||||
else if (it->item > term->grid->cursor.point.col)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +450,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 'G': {
|
||||
/* Cursor horizontal absolute */
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -473,15 +473,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
/* From cursor to end of screen */
|
||||
term_erase(
|
||||
term,
|
||||
&term->cursor.point,
|
||||
&term->grid->cursor.point,
|
||||
&(struct coord){term->cols - 1, term->rows - 1});
|
||||
term->cursor.lcf = false;
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* From start of screen to cursor */
|
||||
term_erase(term, &(struct coord){0, 0}, &term->cursor.point);
|
||||
term->cursor.lcf = false;
|
||||
term_erase(term, &(struct coord){0, 0}, &term->grid->cursor.point);
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
|
@ -490,7 +490,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
term,
|
||||
&(struct coord){0, 0},
|
||||
&(struct coord){term->cols - 1, term->rows - 1});
|
||||
term->cursor.lcf = false;
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
case 3: {
|
||||
|
|
@ -531,25 +531,25 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
/* From cursor to end of line */
|
||||
term_erase(
|
||||
term,
|
||||
&term->cursor.point,
|
||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
||||
term->cursor.lcf = false;
|
||||
&term->grid->cursor.point,
|
||||
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* From start of line to cursor */
|
||||
term_erase(
|
||||
term, &(struct coord){0, term->cursor.point.row}, &term->cursor.point);
|
||||
term->cursor.lcf = false;
|
||||
term, &(struct coord){0, term->grid->cursor.point.row}, &term->grid->cursor.point);
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Entire line */
|
||||
term_erase(
|
||||
term,
|
||||
&(struct coord){0, term->cursor.point.row},
|
||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
||||
term->cursor.lcf = false;
|
||||
&(struct coord){0, term->grid->cursor.point.row},
|
||||
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -561,36 +561,36 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
}
|
||||
|
||||
case 'L': {
|
||||
if (term->cursor.point.row < term->scroll_region.start ||
|
||||
term->cursor.point.row >= term->scroll_region.end)
|
||||
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||
break;
|
||||
|
||||
int count = min(
|
||||
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,
|
||||
(struct scroll_region){
|
||||
.start = term->cursor.point.row,
|
||||
.start = term->grid->cursor.point.row,
|
||||
.end = term->scroll_region.end},
|
||||
count);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'M': {
|
||||
if (term->cursor.point.row < term->scroll_region.start ||
|
||||
term->cursor.point.row >= term->scroll_region.end)
|
||||
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||
break;
|
||||
|
||||
int count = min(
|
||||
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,
|
||||
(struct scroll_region){
|
||||
.start = term->cursor.point.row,
|
||||
.start = term->grid->cursor.point.row,
|
||||
.end = term->scroll_region.end},
|
||||
count);
|
||||
break;
|
||||
|
|
@ -601,26 +601,26 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
/* Number of characters to delete */
|
||||
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) */
|
||||
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 */
|
||||
memmove(&term->grid->cur_row->cells[term->cursor.point.col],
|
||||
&term->grid->cur_row->cells[term->cursor.point.col + count],
|
||||
memmove(&term->grid->cur_row->cells[term->grid->cursor.point.col],
|
||||
&term->grid->cur_row->cells[term->grid->cursor.point.col + count],
|
||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||
|
||||
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;
|
||||
|
||||
/* Erase the remainder of the line */
|
||||
term_erase(
|
||||
term,
|
||||
&(struct coord){term->cursor.point.col + remaining, term->cursor.point.row},
|
||||
&(struct coord){term->cols - 1, term->cursor.point.row});
|
||||
term->cursor.lcf = false;
|
||||
&(struct coord){term->grid->cursor.point.col + remaining, term->grid->cursor.point.row},
|
||||
&(struct coord){term->cols - 1, term->grid->cursor.point.row});
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -629,25 +629,25 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
/* Number of characters to insert */
|
||||
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 */
|
||||
int remaining = term->cols - (term->cursor.point.col + count);
|
||||
int remaining = term->cols - (term->grid->cursor.point.col + count);
|
||||
|
||||
/* Push existing characters */
|
||||
memmove(&term->grid->cur_row->cells[term->cursor.point.col + count],
|
||||
&term->grid->cur_row->cells[term->cursor.point.col],
|
||||
memmove(&term->grid->cur_row->cells[term->grid->cursor.point.col + count],
|
||||
&term->grid->cur_row->cells[term->grid->cursor.point.col],
|
||||
remaining * sizeof(term->grid->cur_row->cells[0]));
|
||||
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;
|
||||
|
||||
/* Erase (insert space characters) */
|
||||
term_erase(
|
||||
term,
|
||||
&term->cursor.point,
|
||||
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
|
||||
term->cursor.lcf = false;
|
||||
&term->grid->cursor.point,
|
||||
&(struct coord){term->grid->cursor.point.col + count - 1, term->grid->cursor.point.row});
|
||||
term->grid->cursor.lcf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -662,13 +662,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 'X': {
|
||||
/* Erase chars */
|
||||
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,
|
||||
&term->cursor.point,
|
||||
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
|
||||
term->cursor.lcf = false;
|
||||
&term->grid->cursor.point,
|
||||
&(struct coord){term->grid->cursor.point.col + count - 1, term->grid->cursor.point.row});
|
||||
term->grid->cursor.lcf = false;
|
||||
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++) {
|
||||
int new_col = term->cols - 1;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(new_col >= term->cursor.point.col);
|
||||
term_cursor_right(term, new_col - term->cursor.point.col);
|
||||
assert(new_col >= term->grid->cursor.point.col);
|
||||
term_cursor_right(term, new_col - term->grid->cursor.point.col);
|
||||
}
|
||||
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++) {
|
||||
int new_col = 0;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(term->cursor.point.col >= new_col);
|
||||
term_cursor_left(term, term->cursor.point.col - new_col);
|
||||
assert(term->grid->cursor.point.col >= new_col);
|
||||
term_cursor_left(term, term->grid->cursor.point.col - new_col);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -757,11 +757,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
}
|
||||
|
||||
case 's':
|
||||
term->saved_cursor = term->cursor;
|
||||
term->grid->saved_cursor = term->grid->cursor;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
term_restore_cursor(term, &term->saved_cursor);
|
||||
term_restore_cursor(term, &term->grid->saved_cursor);
|
||||
break;
|
||||
|
||||
case 't': {
|
||||
|
|
@ -861,15 +861,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
/* u7 - cursor position query */
|
||||
|
||||
int row = term->origin == ORIGIN_ABSOLUTE
|
||||
? term->cursor.point.row
|
||||
: term->cursor.point.row - term->scroll_region.start;
|
||||
? term->grid->cursor.point.row
|
||||
: term->grid->cursor.point.row - term->scroll_region.start;
|
||||
|
||||
/* TODO: we use 0-based position, while the xterm
|
||||
* terminfo says the receiver of the reply should
|
||||
* decrement, hence we must add 1 */
|
||||
char reply[64];
|
||||
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));
|
||||
break;
|
||||
}
|
||||
|
|
@ -1014,9 +1014,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
selection_cancel(term);
|
||||
|
||||
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.scroll_damage);
|
||||
|
|
@ -1137,7 +1139,11 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
selection_cancel(term);
|
||||
|
||||
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.scroll_damage);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue