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:
Daniel Eklöf 2020-04-16 18:51:14 +02:00
parent c96a0b3b3c
commit 89559d5466
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 136 additions and 129 deletions

128
csi.c
View file

@ -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);