mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-17 05:33:52 -04:00
terminal: move cursor from grid to terminal
This commit is contained in:
parent
8723098cda
commit
a8f4cb55af
5 changed files with 61 additions and 66 deletions
56
csi.c
56
csi.c
|
|
@ -297,7 +297,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
if (row > term->rows)
|
if (row > term->rows)
|
||||||
row = term->rows;
|
row = term->rows;
|
||||||
|
|
||||||
term_cursor_to(term, row - 1, term->grid.cursor.col);
|
term_cursor_to(term, row - 1, term->cursor.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -328,7 +328,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
if (col > term->cols)
|
if (col > term->cols)
|
||||||
col = term->cols;
|
col = term->cols;
|
||||||
|
|
||||||
term_cursor_to(term, term->grid.cursor.row, col);
|
term_cursor_to(term, term->cursor.row, col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,14 +355,14 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 0:
|
case 0:
|
||||||
/* From cursor to end of screen */
|
/* From cursor to end of screen */
|
||||||
start = term->grid.linear_cursor;
|
start = term->cursor.linear;
|
||||||
end = term->cols * term->rows;
|
end = term->cols * term->rows;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* From start of screen to cursor */
|
/* From start of screen to cursor */
|
||||||
start = 0;
|
start = 0;
|
||||||
end = term->grid.linear_cursor;
|
end = term->cursor.linear;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -389,20 +389,20 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 0:
|
case 0:
|
||||||
/* From cursor to end of line */
|
/* From cursor to end of line */
|
||||||
start = term->grid.linear_cursor;
|
start = term->cursor.linear;
|
||||||
end = term_cursor_linear(term, term->grid.cursor.row, term->cols);
|
end = term_cursor_linear(term, term->cursor.row, term->cols);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* From start of line to cursor */
|
/* From start of line to cursor */
|
||||||
start = term_cursor_linear(term, term->grid.cursor.row, 0);
|
start = term_cursor_linear(term, term->cursor.row, 0);
|
||||||
end = term->grid.linear_cursor;
|
end = term->cursor.linear;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
/* Entire line */
|
/* Entire line */
|
||||||
start = term_cursor_linear(term, term->grid.cursor.row, 0);
|
start = term_cursor_linear(term, term->cursor.row, 0);
|
||||||
end = term_cursor_linear(term, term->grid.cursor.row, term->cols);
|
end = term_cursor_linear(term, term->cursor.row, term->cols);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -415,36 +415,36 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L': {
|
case 'L': {
|
||||||
if (term->grid.cursor.row < term->scroll_region.start ||
|
if (term->cursor.row < term->scroll_region.start ||
|
||||||
term->grid.cursor.row >= term->scroll_region.end)
|
term->cursor.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int count = min(
|
int count = min(
|
||||||
param_get(term, 0, 1),
|
param_get(term, 0, 1),
|
||||||
term->scroll_region.end - term->grid.cursor.row);
|
term->scroll_region.end - term->cursor.row);
|
||||||
|
|
||||||
term_scroll_reverse_partial(
|
term_scroll_reverse_partial(
|
||||||
term,
|
term,
|
||||||
(struct scroll_region){
|
(struct scroll_region){
|
||||||
.start = term->grid.cursor.row,
|
.start = term->cursor.row,
|
||||||
.end = term->scroll_region.end},
|
.end = term->scroll_region.end},
|
||||||
count);
|
count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'M': {
|
case 'M': {
|
||||||
if (term->grid.cursor.row < term->scroll_region.start ||
|
if (term->cursor.row < term->scroll_region.start ||
|
||||||
term->grid.cursor.row >= term->scroll_region.end)
|
term->cursor.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int count = min(
|
int count = min(
|
||||||
param_get(term, 0, 1),
|
param_get(term, 0, 1),
|
||||||
term->scroll_region.end - term->grid.cursor.row);
|
term->scroll_region.end - term->cursor.row);
|
||||||
|
|
||||||
term_scroll_partial(
|
term_scroll_partial(
|
||||||
term,
|
term,
|
||||||
(struct scroll_region){
|
(struct scroll_region){
|
||||||
.start = term->grid.cursor.row,
|
.start = term->cursor.row,
|
||||||
.end = term->scroll_region.end},
|
.end = term->scroll_region.end},
|
||||||
count);
|
count);
|
||||||
break;
|
break;
|
||||||
|
|
@ -456,9 +456,9 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
|
|
||||||
/* Only delete up to the right margin */
|
/* Only delete up to the right margin */
|
||||||
const int max_end = term_cursor_linear(
|
const int max_end = term_cursor_linear(
|
||||||
term, term->grid.cursor.row, term->cols);
|
term, term->cursor.row, term->cols);
|
||||||
|
|
||||||
int start = term->grid.linear_cursor;
|
int start = term->cursor.linear;
|
||||||
int end = min(start + count, max_end);
|
int end = min(start + count, max_end);
|
||||||
|
|
||||||
/* Erase the requested number of characters */
|
/* Erase the requested number of characters */
|
||||||
|
|
@ -469,7 +469,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
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->grid.linear_cursor, remaining);
|
term_damage_update(term, term->cursor.linear, remaining);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,8 +508,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
* 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",
|
||||||
term->grid.cursor.row + 1,
|
term->cursor.row + 1,
|
||||||
term->grid.cursor.col + 1);
|
term->cursor.col + 1);
|
||||||
write(term->ptmx, reply, strlen(reply));
|
write(term->ptmx, reply, strlen(reply));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -583,10 +583,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
case 1049:
|
case 1049:
|
||||||
if (term->grid.cells != term->grid.alt_grid) {
|
if (term->grid.cells != term->grid.alt_grid) {
|
||||||
term->grid.cells = term->grid.alt_grid;
|
term->grid.cells = term->grid.alt_grid;
|
||||||
|
term->saved_cursor = term->cursor;
|
||||||
term->grid.alt_saved_cursor.row = term->grid.cursor.row;
|
|
||||||
term->grid.alt_saved_cursor.col = term->grid.cursor.col;
|
|
||||||
|
|
||||||
term_damage_all(term);
|
term_damage_all(term);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -640,10 +637,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
if (term->grid.cells == term->grid.alt_grid) {
|
if (term->grid.cells == term->grid.alt_grid) {
|
||||||
term->grid.cells = term->grid.normal_grid;
|
term->grid.cells = term->grid.normal_grid;
|
||||||
|
|
||||||
term->grid.cursor.row = term->grid.alt_saved_cursor.row;
|
term->cursor = term->saved_cursor;
|
||||||
term->grid.cursor.col = term->grid.alt_saved_cursor.col;
|
|
||||||
term->grid.linear_cursor = term_cursor_linear(
|
|
||||||
term, term->grid.cursor.row, term->grid.cursor.col);
|
|
||||||
|
|
||||||
/* Should these be restored from saved values? */
|
/* Should these be restored from saved values? */
|
||||||
term->scroll_region.start = 0;
|
term->scroll_region.start = 0;
|
||||||
|
|
|
||||||
8
main.c
8
main.c
|
|
@ -96,7 +96,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.grid.linear_cursor == 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;
|
||||||
int y = row * c->term.cell_height;
|
int y = row * c->term.cell_height;
|
||||||
|
|
@ -240,14 +240,14 @@ grid_render_erase(struct context *c, struct buffer *buf, const struct damage *dm
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redraw cursor, if it's inside the erased range */
|
/* Redraw cursor, if it's inside the erased range */
|
||||||
if (c->term.grid.linear_cursor >= dmg->range.start &&
|
if (c->term.cursor.linear >= dmg->range.start &&
|
||||||
c->term.grid.linear_cursor < dmg->range.start + dmg->range.length)
|
c->term.cursor.linear < dmg->range.start + dmg->range.length)
|
||||||
{
|
{
|
||||||
grid_render_update(
|
grid_render_update(
|
||||||
c, buf,
|
c, buf,
|
||||||
&(struct damage){
|
&(struct damage){
|
||||||
.type = DAMAGE_UPDATE,
|
.type = DAMAGE_UPDATE,
|
||||||
.range = {.start = c->term.grid.linear_cursor, .length = 1}});
|
.range = {.start = c->term.cursor.linear, .length = 1}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
terminal.c
24
terminal.c
|
|
@ -208,41 +208,41 @@ term_cursor_to(struct terminal *term, int row, int col)
|
||||||
assert(new_linear >= 0);
|
assert(new_linear >= 0);
|
||||||
assert(new_linear < term->rows * term->cols);
|
assert(new_linear < term->rows * term->cols);
|
||||||
|
|
||||||
term_damage_update(term, term->grid.linear_cursor, 1);
|
term_damage_update(term, term->cursor.linear, 1);
|
||||||
term_damage_update(term, new_linear, 1);
|
term_damage_update(term, new_linear, 1);
|
||||||
term->grid.print_needs_wrap = false;
|
term->grid.print_needs_wrap = false;
|
||||||
|
|
||||||
term->grid.linear_cursor = new_linear;
|
term->cursor.linear = new_linear;
|
||||||
term->grid.cursor.col = col;
|
term->cursor.col = col;
|
||||||
term->grid.cursor.row = row;
|
term->cursor.row = row;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_left(struct terminal *term, int count)
|
term_cursor_left(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int move_amount = min(term->grid.cursor.col, count);
|
int move_amount = min(term->cursor.col, count);
|
||||||
term_cursor_to(term, term->grid.cursor.row, term->grid.cursor.col - move_amount);
|
term_cursor_to(term, term->cursor.row, term->cursor.col - move_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
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->grid.cursor.col - 1, count);
|
int move_amount = min(term->cols - term->cursor.col - 1, count);
|
||||||
term_cursor_to(term, term->grid.cursor.row, term->grid.cursor.col + move_amount);
|
term_cursor_to(term, term->cursor.row, term->cursor.col + move_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_up(struct terminal *term, int count)
|
term_cursor_up(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int move_amount = min(term->grid.cursor.row, count);
|
int move_amount = min(term->cursor.row, count);
|
||||||
term_cursor_to(term, term->grid.cursor.row - move_amount, term->grid.cursor.col);
|
term_cursor_to(term, term->cursor.row - move_amount, term->cursor.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_cursor_down(struct terminal *term, int count)
|
term_cursor_down(struct terminal *term, int count)
|
||||||
{
|
{
|
||||||
int move_amount = min(term->rows - term->grid.cursor.row - 1, count);
|
int move_amount = min(term->rows - term->cursor.row - 1, count);
|
||||||
term_cursor_to(term, term->grid.cursor.row + move_amount, term->grid.cursor.col);
|
term_cursor_to(term, term->cursor.row + move_amount, term->cursor.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
19
terminal.h
19
terminal.h
|
|
@ -37,6 +37,12 @@ struct scroll_region {
|
||||||
int end;
|
int end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cursor {
|
||||||
|
int row;
|
||||||
|
int col;
|
||||||
|
int linear;
|
||||||
|
};
|
||||||
|
|
||||||
enum damage_type {DAMAGE_UPDATE, DAMAGE_ERASE, DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE};
|
enum damage_type {DAMAGE_UPDATE, DAMAGE_ERASE, DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE};
|
||||||
struct damage {
|
struct damage {
|
||||||
enum damage_type type;
|
enum damage_type type;
|
||||||
|
|
@ -56,20 +62,11 @@ struct damage {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grid {
|
struct grid {
|
||||||
int linear_cursor;
|
|
||||||
struct {
|
|
||||||
int row;
|
|
||||||
int col;
|
|
||||||
} cursor;
|
|
||||||
bool print_needs_wrap;
|
bool print_needs_wrap;
|
||||||
|
|
||||||
struct cell *cells;
|
struct cell *cells;
|
||||||
struct cell *normal_grid;
|
struct cell *normal_grid;
|
||||||
struct cell *alt_grid;
|
struct cell *alt_grid;
|
||||||
struct {
|
|
||||||
int row;
|
|
||||||
int col;
|
|
||||||
} alt_saved_cursor;
|
|
||||||
|
|
||||||
tll(struct damage) damage;
|
tll(struct damage) damage;
|
||||||
tll(struct damage) scroll_damage;
|
tll(struct damage) scroll_damage;
|
||||||
|
|
@ -151,6 +148,10 @@ struct terminal {
|
||||||
|
|
||||||
struct rgba foreground;
|
struct rgba foreground;
|
||||||
struct rgba background;
|
struct rgba background;
|
||||||
|
|
||||||
|
struct cursor cursor;
|
||||||
|
struct cursor saved_cursor;
|
||||||
|
struct cursor alt_saved_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
void term_damage_all(struct terminal *term);
|
void term_damage_all(struct terminal *term);
|
||||||
|
|
|
||||||
20
vt.c
20
vt.c
|
|
@ -626,7 +626,7 @@ action(struct terminal *term, enum action action, uint8_t c)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
/* LF - line feed */
|
/* LF - line feed */
|
||||||
if (term->grid.cursor.row == term->scroll_region.end - 1) {
|
if (term->cursor.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);
|
||||||
|
|
@ -634,7 +634,7 @@ action(struct terminal *term, enum action action, uint8_t c)
|
||||||
|
|
||||||
case '\r':
|
case '\r':
|
||||||
/* FF - form feed */
|
/* FF - form feed */
|
||||||
term_cursor_left(term, term->grid.cursor.col);
|
term_cursor_left(term, term->cursor.col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\b':
|
case '\b':
|
||||||
|
|
@ -649,9 +649,9 @@ action(struct terminal *term, enum action action, uint8_t c)
|
||||||
|
|
||||||
case '\x09': {
|
case '\x09': {
|
||||||
/* HT - horizontal tab */
|
/* HT - horizontal tab */
|
||||||
int col = term->grid.cursor.col;
|
int col = term->cursor.col;
|
||||||
col = (col + 8) / 8 * 8;
|
col = (col + 8) / 8 * 8;
|
||||||
term_cursor_right(term, col - term->grid.cursor.col);
|
term_cursor_right(term, col - term->cursor.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -671,15 +671,15 @@ action(struct terminal *term, enum action action, uint8_t c)
|
||||||
|
|
||||||
case ACTION_PRINT: {
|
case ACTION_PRINT: {
|
||||||
if (term->grid.print_needs_wrap) {
|
if (term->grid.print_needs_wrap) {
|
||||||
if (term->grid.cursor.row == term->scroll_region.end - 1) {
|
if (term->cursor.row == term->scroll_region.end - 1) {
|
||||||
term_scroll(term, 1);
|
term_scroll(term, 1);
|
||||||
term_cursor_to(term, term->grid.cursor.row, 0);
|
term_cursor_to(term, term->cursor.row, 0);
|
||||||
} else
|
} else
|
||||||
term_cursor_to(term, term->grid.cursor.row + 1, 0);
|
term_cursor_to(term, term->cursor.row + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cell *cell = &term->grid.cells[term->grid.linear_cursor];
|
struct cell *cell = &term->grid.cells[term->cursor.linear];
|
||||||
term_damage_update(term, term->grid.linear_cursor, 1);
|
term_damage_update(term, term->cursor.linear, 1);
|
||||||
|
|
||||||
if (term->vt.utf8.idx > 0) {
|
if (term->vt.utf8.idx > 0) {
|
||||||
//LOG_DBG("print: UTF8: %.*s", (int)term->vt.utf8.idx, term->vt.utf8.data);
|
//LOG_DBG("print: UTF8: %.*s", (int)term->vt.utf8.idx, term->vt.utf8.data);
|
||||||
|
|
@ -694,7 +694,7 @@ action(struct terminal *term, enum action action, uint8_t c)
|
||||||
|
|
||||||
cell->attrs = term->vt.attrs;
|
cell->attrs = term->vt.attrs;
|
||||||
|
|
||||||
if (term->grid.cursor.col < term->cols - 1)
|
if (term->cursor.col < term->cols - 1)
|
||||||
term_cursor_right(term, 1);
|
term_cursor_right(term, 1);
|
||||||
else
|
else
|
||||||
term->grid.print_needs_wrap = true;
|
term->grid.print_needs_wrap = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue