term: add struct cursor

This commit is contained in:
Daniel Eklöf 2019-11-17 09:44:31 +01:00
parent c1088d77ac
commit d637b8c9ba
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 103 additions and 99 deletions

84
csi.c
View file

@ -331,7 +331,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
case 'd': {
/* VPA - vertical line position absolute */
struct coord new_cursor = term_cursor_rel_to_abs(
term, vt_param_get(term, 0, 1) - 1, term->cursor.col);
term, vt_param_get(term, 0, 1) - 1, term->cursor.point.col);
term_cursor_to(term, new_cursor.row, new_cursor.col);
break;
}
@ -363,9 +363,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.col)
if (it->item == term->cursor.point.col)
tll_remove(term->tab_stops, it);
else if (it->item > term->cursor.col)
else if (it->item > term->cursor.point.col)
break;
}
@ -386,7 +386,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
case 'G': {
/* Cursor horizontal absolute */
struct coord new_cursor = term_cursor_rel_to_abs(
term, term->cursor.row, vt_param_get(term, 0, 1) - 1);
term, term->cursor.point.row, vt_param_get(term, 0, 1) - 1);
term_cursor_to(term, new_cursor.row, new_cursor.col);
break;
}
@ -411,14 +411,14 @@ csi_dispatch(struct terminal *term, uint8_t final)
/* From cursor to end of screen */
term_erase(
term,
&term->cursor,
&term->cursor.point,
&(struct coord){term->cols - 1, term->rows - 1});
term->lcf = false;
break;
case 1:
/* From start of screen to cursor */
term_erase(term, &(struct coord){0, 0}, &term->cursor);
term_erase(term, &(struct coord){0, 0}, &term->cursor.point);
term->lcf = false;
break;
@ -469,15 +469,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
/* From cursor to end of line */
term_erase(
term,
&term->cursor,
&(struct coord){term->cols - 1, term->cursor.row});
&term->cursor.point,
&(struct coord){term->cols - 1, term->cursor.point.row});
term->lcf = false;
break;
case 1:
/* From start of line to cursor */
term_erase(
term, &(struct coord){0, term->cursor.row}, &term->cursor);
term, &(struct coord){0, term->cursor.point.row}, &term->cursor.point);
term->lcf = false;
break;
@ -485,8 +485,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
/* Entire line */
term_erase(
term,
&(struct coord){0, term->cursor.row},
&(struct coord){term->cols - 1, term->cursor.row});
&(struct coord){0, term->cursor.point.row},
&(struct coord){term->cols - 1, term->cursor.point.row});
term->lcf = false;
break;
@ -499,36 +499,36 @@ csi_dispatch(struct terminal *term, uint8_t final)
}
case 'L': {
if (term->cursor.row < term->scroll_region.start ||
term->cursor.row >= term->scroll_region.end)
if (term->cursor.point.row < term->scroll_region.start ||
term->cursor.point.row >= term->scroll_region.end)
break;
int count = min(
vt_param_get(term, 0, 1),
term->scroll_region.end - term->cursor.row);
term->scroll_region.end - term->cursor.point.row);
term_scroll_reverse_partial(
term,
(struct scroll_region){
.start = term->cursor.row,
.start = term->cursor.point.row,
.end = term->scroll_region.end},
count);
break;
}
case 'M': {
if (term->cursor.row < term->scroll_region.start ||
term->cursor.row >= term->scroll_region.end)
if (term->cursor.point.row < term->scroll_region.start ||
term->cursor.point.row >= term->scroll_region.end)
break;
int count = min(
vt_param_get(term, 0, 1),
term->scroll_region.end - term->cursor.row);
term->scroll_region.end - term->cursor.point.row);
term_scroll_partial(
term,
(struct scroll_region){
.start = term->cursor.row,
.start = term->cursor.point.row,
.end = term->scroll_region.end},
count);
break;
@ -539,25 +539,25 @@ 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.col);
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
/* Number of characters left after deletion (on current line) */
int remaining = term->cols - (term->cursor.col + count);
int remaining = term->cols - (term->cursor.point.col + count);
/* 'Delete' characters by moving the remaining ones */
memmove(&term->grid->cur_row->cells[term->cursor.col],
&term->grid->cur_row->cells[term->cursor.col + count],
memmove(&term->grid->cur_row->cells[term->cursor.point.col],
&term->grid->cur_row->cells[term->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.col + c].attrs.clean = 0;
term->grid->cur_row->cells[term->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.col + remaining, term->cursor.row},
&(struct coord){term->cols - 1, term->cursor.row});
&(struct coord){term->cursor.point.col + remaining, term->cursor.point.row},
&(struct coord){term->cols - 1, term->cursor.point.row});
term->lcf = false;
break;
}
@ -567,24 +567,24 @@ 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.col);
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
/* Characters to move */
int remaining = term->cols - (term->cursor.col + count);
int remaining = term->cols - (term->cursor.point.col + count);
/* Push existing characters */
memmove(&term->grid->cur_row->cells[term->cursor.col + count],
&term->grid->cur_row->cells[term->cursor.col],
memmove(&term->grid->cur_row->cells[term->cursor.point.col + count],
&term->grid->cur_row->cells[term->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.col + count + c].attrs.clean = 0;
term->grid->cur_row->cells[term->cursor.point.col + count + c].attrs.clean = 0;
term->grid->cur_row->dirty = true;
/* Erase (insert space characters) */
term_erase(
term,
&term->cursor,
&(struct coord){term->cursor.col + count - 1, term->cursor.row});
&term->cursor.point,
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
term->lcf = false;
break;
}
@ -600,21 +600,21 @@ 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.col);
vt_param_get(term, 0, 1), term->cols - term->cursor.point.col);
term_erase(
term,
&term->cursor,
&(struct coord){term->cursor.col + count - 1, term->cursor.row});
&term->cursor.point,
&(struct coord){term->cursor.point.col + count - 1, term->cursor.point.row});
term->lcf = false;
break;
}
case 'Z': {
/* Back tab */
int col = term->cursor.col;
int col = term->cursor.point.col;
col = (col - 8 + 7) / 8 * 8;
term_cursor_right(term, col - term->cursor.col);
term_cursor_right(term, col - term->cursor.point.col);
break;
}
@ -724,15 +724,15 @@ csi_dispatch(struct terminal *term, uint8_t final)
/* u7 - cursor position query */
int row = term->origin == ORIGIN_ABSOLUTE
? term->cursor.row
: term->cursor.row - term->scroll_region.start;
? term->cursor.point.row
: term->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.col + 1);
row + 1, term->cursor.point.col + 1);
term_to_slave(term, reply, strlen(reply));
break;
}
@ -857,7 +857,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
term->grid = &term->alt;
term->saved_cursor = term->cursor;
term_cursor_to(term, term->cursor.row, term->cursor.col);
term_cursor_to(term, term->cursor.point.row, term->cursor.point.col);
tll_free(term->alt.damage);
tll_free(term->alt.scroll_damage);

View file

@ -527,8 +527,8 @@ grid_render(struct terminal *term)
}
term->render.last_cursor.cell = NULL;
if (term->render.last_cursor.actual.col != term->cursor.col ||
term->render.last_cursor.actual.row != term->cursor.row)
if (term->render.last_cursor.actual.col != term->cursor.point.col ||
term->render.last_cursor.actual.row != term->cursor.point.row)
{
/* Detect cursor movement - we don't dirty cells touched
* by the cursor, since only the final cell matters. */
@ -647,7 +647,7 @@ grid_render(struct terminal *term)
*/
bool cursor_is_visible = false;
int view_end = (term->grid->view + term->rows - 1) & (term->grid->num_rows - 1);
int cursor_row = (term->grid->offset + term->cursor.row) & (term->grid->num_rows - 1);
int cursor_row = (term->grid->offset + term->cursor.point.row) & (term->grid->num_rows - 1);
if (view_end >= term->grid->view) {
/* Not wrapped */
if (cursor_row >= term->grid->view && cursor_row <= view_end)
@ -675,21 +675,21 @@ grid_render(struct terminal *term)
int view_aligned_row
= (cursor_row - term->grid->view + term->grid->num_rows) & (term->grid->num_rows - 1);
term->render.last_cursor.actual = term->cursor;
term->render.last_cursor.actual = term->cursor.point;
term->render.last_cursor.in_view = (struct coord) {
term->cursor.col, view_aligned_row};
term->cursor.point.col, view_aligned_row};
struct row *row = grid_row_in_view(term->grid, view_aligned_row);
struct cell *cell = &row->cells[term->cursor.col];
struct cell *cell = &row->cells[term->cursor.point.col];
cell->attrs.clean = 0;
term->render.last_cursor.cell = cell;
int cols_updated = render_cell(
term, pix, cell, term->cursor.col, view_aligned_row, true);
term, pix, cell, term->cursor.point.col, view_aligned_row, true);
wl_surface_damage_buffer(
term->window->surface,
term->x_margin + term->cursor.col * term->cell_width,
term->x_margin + term->cursor.point.col * term->cell_width,
term->y_margin + view_aligned_row * term->cell_height,
cols_updated * term->cell_width, term->cell_height);
}
@ -949,8 +949,8 @@ render_resize(struct terminal *term, int width, int height)
term_cursor_to(
term,
min(term->cursor.row, term->rows - 1),
min(term->cursor.col, term->cols - 1));
min(term->cursor.point.row, term->rows - 1),
min(term->cursor.point.col, term->cols - 1));
term->render.last_cursor.cell = NULL;

View file

@ -856,9 +856,9 @@ term_reset(struct terminal *term, bool hard)
for (size_t i = 0; i < 256; i++)
term->colors.table[i] = term->colors.default_table[i];
term->lcf = false;
term->cursor = (struct coord){0, 0};
term->saved_cursor = (struct coord){0, 0};
term->alt_saved_cursor = (struct coord){0, 0};
term->cursor = (struct cursor){.point = {0, 0}};
term->saved_cursor = (struct cursor){.point = {0, 0}};
term->alt_saved_cursor = (struct cursor){.point = {0, 0}};
term->cursor_style = term->default_cursor_style;
term->cursor_blinking = false;
term->cursor_color.text = term->default_cursor_color.text;
@ -1026,8 +1026,8 @@ term_cursor_to(struct terminal *term, int row, int col)
term->lcf = false;
term->cursor.col = col;
term->cursor.row = row;
term->cursor.point.col = col;
term->cursor.point.row = row;
term->grid->cur_row = grid_row(term->grid, row);
}
@ -1042,18 +1042,18 @@ term_cursor_home(struct terminal *term)
void
term_cursor_left(struct terminal *term, int count)
{
int move_amount = min(term->cursor.col, count);
term->cursor.col -= move_amount;
assert(term->cursor.col >= 0);
int move_amount = min(term->cursor.point.col, count);
term->cursor.point.col -= move_amount;
assert(term->cursor.point.col >= 0);
term->lcf = false;
}
void
term_cursor_right(struct terminal *term, int count)
{
int move_amount = min(term->cols - term->cursor.col - 1, count);
term->cursor.col += move_amount;
assert(term->cursor.col < term->cols);
int move_amount = min(term->cols - term->cursor.point.col - 1, count);
term->cursor.point.col += move_amount;
assert(term->cursor.point.col < term->cols);
term->lcf = false;
}
@ -1061,20 +1061,20 @@ void
term_cursor_up(struct terminal *term, int count)
{
int top = term->origin == ORIGIN_ABSOLUTE ? 0 : term->scroll_region.start;
assert(term->cursor.row >= top);
assert(term->cursor.point.row >= top);
int move_amount = min(term->cursor.row - top, count);
term_cursor_to(term, term->cursor.row - move_amount, term->cursor.col);
int move_amount = min(term->cursor.point.row - top, count);
term_cursor_to(term, term->cursor.point.row - move_amount, term->cursor.point.col);
}
void
term_cursor_down(struct terminal *term, int count)
{
int bottom = term->origin == ORIGIN_ABSOLUTE ? term->rows : term->scroll_region.end;
assert(bottom >= term->cursor.row);
assert(bottom >= term->cursor.point.row);
int move_amount = min(bottom - term->cursor.row - 1, count);
term_cursor_to(term, term->cursor.row + move_amount, term->cursor.col);
int move_amount = min(bottom - term->cursor.point.row - 1, count);
term_cursor_to(term, term->cursor.point.row + move_amount, term->cursor.point.col);
}
void
@ -1113,7 +1113,7 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
}
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
term->grid->cur_row = grid_row(term->grid, term->cursor.point.row);
}
void
@ -1164,7 +1164,7 @@ term_scroll_reverse_partial(struct terminal *term,
}
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
term->grid->cur_row = grid_row(term->grid, term->cursor.row);
term->grid->cur_row = grid_row(term->grid, term->cursor.point.row);
}
void
@ -1176,7 +1176,7 @@ term_scroll_reverse(struct terminal *term, int rows)
void
term_linefeed(struct terminal *term)
{
if (term->cursor.row == term->scroll_region.end - 1)
if (term->cursor.point.row == term->scroll_region.end - 1)
term_scroll(term, 1);
else
term_cursor_down(term, 1);
@ -1185,7 +1185,7 @@ term_linefeed(struct terminal *term)
void
term_reverse_index(struct terminal *term)
{
if (term->cursor.row == term->scroll_region.start)
if (term->cursor.point.row == term->scroll_region.start)
term_scroll_reverse(term, 1);
else
term_cursor_up(term, 1);
@ -1204,8 +1204,8 @@ term_reset_view(struct terminal *term)
void
term_restore_cursor(struct terminal *term)
{
int row = min(term->saved_cursor.row, term->rows - 1);
int col = min(term->saved_cursor.col, term->cols - 1);
int row = min(term->saved_cursor.point.row, term->rows - 1);
int col = min(term->saved_cursor.point.col, term->cols - 1);
term_cursor_to(term, row, col);
}

View file

@ -61,6 +61,10 @@ struct coord {
int row;
};
struct cursor {
struct coord point;
};
enum damage_type {DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE,
DAMAGE_SCROLL_IN_VIEW, DAMAGE_SCROLL_REVERSE_IN_VIEW};
@ -216,9 +220,9 @@ struct terminal {
} colors;
enum cursor_origin origin;
struct coord cursor;
struct coord saved_cursor;
struct coord alt_saved_cursor;
struct cursor cursor;
struct cursor saved_cursor;
struct cursor alt_saved_cursor;
enum cursor_style default_cursor_style;
enum cursor_style cursor_style;
bool cursor_blinking;

42
vt.c
View file

@ -614,18 +614,18 @@ esc_dispatch(struct terminal *term, uint8_t final)
case 'E':
term_linefeed(term);
term_cursor_left(term, term->cursor.col);
term_cursor_left(term, term->cursor.point.col);
break;
case 'H':
tll_foreach(term->tab_stops, it) {
if (it->item >= term->cursor.col) {
tll_insert_before(term->tab_stops, it, term->cursor.col);
if (it->item >= term->cursor.point.col) {
tll_insert_before(term->tab_stops, it, term->cursor.point.col);
break;
}
}
tll_push_back(term->tab_stops, term->cursor.col);
tll_push_back(term->tab_stops, term->cursor.point.col);
break;
case 'M':
@ -714,18 +714,18 @@ static inline void
pre_print(struct terminal *term)
{
if (unlikely(term->lcf) && term->auto_margin) {
if (term->cursor.row == term->scroll_region.end - 1) {
if (term->cursor.point.row == term->scroll_region.end - 1) {
term_scroll(term, 1);
term_cursor_to(term, term->cursor.row, 0);
term_cursor_to(term, term->cursor.point.row, 0);
} else
term_cursor_to(term, term->cursor.row + 1, 0);
term_cursor_to(term, term->cursor.point.row + 1, 0);
}
}
static inline void
post_print(struct terminal *term)
{
if (term->cursor.col < term->cols - 1)
if (term->cursor.point.col < term->cols - 1)
term_cursor_right(term, 1);
else
term->lcf = true;
@ -736,15 +736,15 @@ print_insert(struct terminal *term, int width)
{
if (unlikely(term->insert_mode)) {
struct row *row = term->grid->cur_row;
const size_t move_count = max(0, term->cols - term->cursor.col - width);
const size_t move_count = max(0, term->cols - term->cursor.point.col - width);
memmove(
&row->cells[term->cursor.col + width],
&row->cells[term->cursor.col],
&row->cells[term->cursor.point.col + width],
&row->cells[term->cursor.point.col],
move_count * sizeof(struct cell));
/* Mark moved cells as dirty */
for (size_t i = term->cursor.col + width; i < term->cols; i++)
for (size_t i = term->cursor.point.col + width; i < term->cols; i++)
row->cells[i].attrs.clean = 0;
}
}
@ -755,7 +755,7 @@ action_print_utf8(struct terminal *term)
pre_print(term);
struct row *row = term->grid->cur_row;
struct cell *cell = &row->cells[term->cursor.col];
struct cell *cell = &row->cells[term->cursor.point.col];
/* Convert to wchar */
mbstate_t ps = {0};
@ -781,11 +781,11 @@ action_print_utf8(struct terminal *term)
/* Advance cursor the 'additional' columns (last step is done
* by post_print()) */
for (int i = 1; i < width && term->cursor.col < term->cols - 1; i++) {
for (int i = 1; i < width && term->cursor.point.col < term->cols - 1; i++) {
term_cursor_right(term, 1);
assert(term->cursor.col < term->cols);
struct cell *cell = &row->cells[term->cursor.col];
assert(term->cursor.point.col < term->cols);
struct cell *cell = &row->cells[term->cursor.point.col];
cell->wc = 0;
cell->attrs.clean = 0;
}
@ -799,7 +799,7 @@ action_print(struct terminal *term, uint8_t c)
pre_print(term);
struct row *row = term->grid->cur_row;
struct cell *cell = &row->cells[term->cursor.col];
struct cell *cell = &row->cells[term->cursor.point.col];
row->dirty = true;
cell->attrs.clean = 0;
@ -850,7 +850,7 @@ action(struct terminal *term, enum action _action, uint8_t c)
case '\r':
/* FF - form feed */
term_cursor_left(term, term->cursor.col);
term_cursor_left(term, term->cursor.point.col);
break;
case '\b':
@ -866,14 +866,14 @@ action(struct terminal *term, enum action _action, uint8_t c)
case '\x09': {
/* HT - horizontal tab */
int new_col = term->cursor.col;
int new_col = term->cursor.point.col;
tll_foreach(term->tab_stops, it) {
if (it->item >= term->cursor.col) {
if (it->item >= term->cursor.point.col) {
new_col = it->item;
break;
}
}
term_cursor_right(term, new_col - term->cursor.col);
term_cursor_right(term, new_col - term->cursor.point.col);
break;
}