From 3ae49a8fdb7d21c065fcf2b1f7459a32f963c087 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 5 Oct 2014 14:53:18 +0200 Subject: [PATCH] terminal/screen: save state in separate object Terminal state can be saved/restored by applications. To simplify our internal handling, put all affected state into a separate object. Especially with alternate screen buffers, this will simplify our code significantly. --- src/libsystemd-terminal/term-internal.h | 41 ++-- src/libsystemd-terminal/term-screen.c | 326 +++++++++++++++----------------- 2 files changed, 175 insertions(+), 192 deletions(-) diff --git a/src/libsystemd-terminal/term-internal.h b/src/libsystemd-terminal/term-internal.h index a023498b53..c78b9aa70a 100644 --- a/src/libsystemd-terminal/term-internal.h +++ b/src/libsystemd-terminal/term-internal.h @@ -37,6 +37,7 @@ typedef struct term_page term_page; typedef struct term_history term_history; typedef uint32_t term_charset[96]; +typedef struct term_state term_state; /* * Miscellaneous @@ -586,11 +587,9 @@ enum { TERM_FLAG_HIDE_CURSOR = (1U << 1), /* hide cursor caret (default: off) */ TERM_FLAG_INHIBIT_TPARM = (1U << 2), /* do not send TPARM unrequested (default: off) */ TERM_FLAG_NEWLINE_MODE = (1U << 3), /* perform carriage-return on line-feeds (default: off) */ - TERM_FLAG_ORIGIN_MODE = (1U << 4), /* in origin mode, the cursor is bound by the margins (default: off) */ - TERM_FLAG_PENDING_WRAP = (1U << 5), /* wrap-around is pending */ - TERM_FLAG_AUTO_WRAP = (1U << 6), /* auto-wrap mode causes line-wraps at line-ends (default: off) */ - TERM_FLAG_KEYPAD_MODE = (1U << 7), /* application-keypad mode (default: off) */ - TERM_FLAG_CURSOR_KEYS = (1U << 8), /* enable application cursor-keys (default: off) */ + TERM_FLAG_PENDING_WRAP = (1U << 4), /* wrap-around is pending */ + TERM_FLAG_KEYPAD_MODE = (1U << 5), /* application-keypad mode (default: off) */ + TERM_FLAG_CURSOR_KEYS = (1U << 6), /* enable application cursor-keys (default: off) */ }; enum { @@ -600,6 +599,19 @@ enum { TERM_CONFORMANCE_LEVEL_CNT, }; +struct term_state { + unsigned int cursor_x; + unsigned int cursor_y; + term_attr attr; + term_charset **gl; + term_charset **gr; + term_charset **glt; + term_charset **grt; + + bool auto_wrap : 1; + bool origin_mode : 1; +}; + struct term_screen { unsigned long ref; term_age_t age; @@ -623,15 +635,8 @@ struct term_screen { unsigned int flags; unsigned int conformance_level; - unsigned int cursor_x; - unsigned int cursor_y; - term_attr attr; term_attr default_attr; - term_charset **gl; - term_charset **gr; - term_charset **glt; - term_charset **grt; term_charset *g0; term_charset *g1; term_charset *g2; @@ -639,14 +644,6 @@ struct term_screen { char *answerback; - struct { - unsigned int cursor_x; - unsigned int cursor_y; - term_attr attr; - term_charset **gl; - term_charset **gr; - term_charset **glt; - term_charset **grt; - unsigned int flags; - } saved; + term_state state; + term_state saved; }; diff --git a/src/libsystemd-terminal/term-screen.c b/src/libsystemd-terminal/term-screen.c index 9026c25efe..c8a81658cb 100644 --- a/src/libsystemd-terminal/term-screen.c +++ b/src/libsystemd-terminal/term-screen.c @@ -70,18 +70,13 @@ int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *writ screen->cmd_fn_data = cmd_fn_data; screen->flags = TERM_FLAG_7BIT_MODE; screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT400; - screen->gl = &screen->g0; - screen->gr = &screen->g1; screen->g0 = &term_unicode_lower; screen->g1 = &term_unicode_upper; screen->g2 = &term_unicode_lower; screen->g3 = &term_unicode_upper; - - screen->saved.cursor_x = 0; - screen->saved.cursor_y = 0; - screen->saved.attr = screen->attr; - screen->saved.gl = screen->gl; - screen->saved.gr = screen->gr; + screen->state.gl = &screen->g0; + screen->state.gr = &screen->g1; + screen->saved = screen->state; r = term_page_new(&screen->page_main); if (r < 0) @@ -224,7 +219,7 @@ static bool screen_tab_is_set(term_screen *screen, unsigned int pos) { static inline void screen_age_cursor(term_screen *screen) { term_cell *cell; - cell = term_page_get_cell(screen->page, screen->cursor_x, screen->cursor_y); + cell = term_page_get_cell(screen->page, screen->state.cursor_x, screen->state.cursor_y); if (cell) cell->age = screen->age; } @@ -237,21 +232,21 @@ static void screen_cursor_set(term_screen *screen, unsigned int x, unsigned int x = screen_clamp_x(screen, x); y = screen_clamp_y(screen, y); - if (x == screen->cursor_x && y == screen->cursor_y) + if (x == screen->state.cursor_x && y == screen->state.cursor_y) return; if (!(screen->flags & TERM_FLAG_HIDE_CURSOR)) screen_age_cursor(screen); - screen->cursor_x = x; - screen->cursor_y = y; + screen->state.cursor_x = x; + screen->state.cursor_y = y; if (!(screen->flags & TERM_FLAG_HIDE_CURSOR)) screen_age_cursor(screen); } static void screen_cursor_set_rel(term_screen *screen, unsigned int x, unsigned int y) { - if (screen->flags & TERM_FLAG_ORIGIN_MODE) { + if (screen->state.origin_mode) { x = screen_clamp_x(screen, x); y = screen_clamp_x(screen, y) + screen->page->scroll_idx; @@ -266,53 +261,53 @@ static void screen_cursor_set_rel(term_screen *screen, unsigned int x, unsigned } static void screen_cursor_left(term_screen *screen, unsigned int num) { - if (num > screen->cursor_x) - num = screen->cursor_x; + if (num > screen->state.cursor_x) + num = screen->state.cursor_x; - screen_cursor_set(screen, screen->cursor_x - num, screen->cursor_y); + screen_cursor_set(screen, screen->state.cursor_x - num, screen->state.cursor_y); } static void screen_cursor_left_tab(term_screen *screen, unsigned int num) { unsigned int i; - i = screen->cursor_x; + i = screen->state.cursor_x; while (i > 0 && num > 0) { if (screen_tab_is_set(screen, --i)) --num; } - screen_cursor_set(screen, i, screen->cursor_y); + screen_cursor_set(screen, i, screen->state.cursor_y); } static void screen_cursor_right(term_screen *screen, unsigned int num) { if (num > screen->page->width) num = screen->page->width; - screen_cursor_set(screen, screen->cursor_x + num, screen->cursor_y); + screen_cursor_set(screen, screen->state.cursor_x + num, screen->state.cursor_y); } static void screen_cursor_right_tab(term_screen *screen, unsigned int num) { unsigned int i; - i = screen->cursor_x; + i = screen->state.cursor_x; while (i + 1 < screen->page->width && num > 0) { if (screen_tab_is_set(screen, ++i)) --num; } - screen_cursor_set(screen, i, screen->cursor_y); + screen_cursor_set(screen, i, screen->state.cursor_y); } static void screen_cursor_up(term_screen *screen, unsigned int num, bool scroll) { unsigned int max; - if (screen->cursor_y < screen->page->scroll_idx) { - if (num > screen->cursor_y) - num = screen->cursor_y; + if (screen->state.cursor_y < screen->page->scroll_idx) { + if (num > screen->state.cursor_y) + num = screen->state.cursor_y; - screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num); + screen_cursor_set(screen, screen->state.cursor_x, screen->state.cursor_y - num); } else { - max = screen->cursor_y - screen->page->scroll_idx; + max = screen->state.cursor_y - screen->page->scroll_idx; if (num > max) { if (num < 1) return; @@ -321,14 +316,14 @@ static void screen_cursor_up(term_screen *screen, unsigned int num, bool scroll) screen_age_cursor(screen); if (scroll) - term_page_scroll_down(screen->page, num - max, &screen->attr, screen->age, NULL); + term_page_scroll_down(screen->page, num - max, &screen->state.attr, screen->age, NULL); - screen->cursor_y = screen->page->scroll_idx; + screen->state.cursor_y = screen->page->scroll_idx; if (!(screen->flags & TERM_FLAG_HIDE_CURSOR)) screen_age_cursor(screen); } else { - screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num); + screen_cursor_set(screen, screen->state.cursor_x, screen->state.cursor_y - num); } } } @@ -336,13 +331,13 @@ static void screen_cursor_up(term_screen *screen, unsigned int num, bool scroll) static void screen_cursor_down(term_screen *screen, unsigned int num, bool scroll) { unsigned int max; - if (screen->cursor_y >= screen->page->scroll_idx + screen->page->scroll_num) { + if (screen->state.cursor_y >= screen->page->scroll_idx + screen->page->scroll_num) { if (num > screen->page->height) num = screen->page->height; - screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num); + screen_cursor_set(screen, screen->state.cursor_x, screen->state.cursor_y - num); } else { - max = screen->page->scroll_idx + screen->page->scroll_num - 1 - screen->cursor_y; + max = screen->page->scroll_idx + screen->page->scroll_num - 1 - screen->state.cursor_y; if (num > max) { if (num < 1) return; @@ -351,18 +346,27 @@ static void screen_cursor_down(term_screen *screen, unsigned int num, bool scrol screen_age_cursor(screen); if (scroll) - term_page_scroll_up(screen->page, num - max, &screen->attr, screen->age, screen->history); + term_page_scroll_up(screen->page, num - max, &screen->state.attr, screen->age, screen->history); - screen->cursor_y = screen->page->scroll_idx + screen->page->scroll_num - 1; + screen->state.cursor_y = screen->page->scroll_idx + screen->page->scroll_num - 1; if (!(screen->flags & TERM_FLAG_HIDE_CURSOR)) screen_age_cursor(screen); } else { - screen_cursor_set(screen, screen->cursor_x, screen->cursor_y + num); + screen_cursor_set(screen, screen->state.cursor_x, screen->state.cursor_y + num); } } } +static void screen_save_state(term_screen *screen, term_state *where) { + *where = screen->state; +} + +static void screen_restore_state(term_screen *screen, term_state *from) { + screen_cursor_set(screen, from->cursor_x, from->cursor_y); + screen->state = *from; +} + static inline void set_reset(term_screen *screen, unsigned int flag, bool set) { if (set) screen->flags |= flag; @@ -388,7 +392,7 @@ static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, * DECOM: origin-mode * TODO */ - set_reset(screen, TERM_FLAG_ORIGIN_MODE, set); + screen->state.origin_mode = set; } break; @@ -398,7 +402,7 @@ static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, * DECAWN: auto-wrap mode * TODO */ - set_reset(screen, TERM_FLAG_AUTO_WRAP, set); + screen->state.auto_wrap = set; } break; @@ -435,19 +439,19 @@ static uint32_t screen_map(term_screen *screen, uint32_t val) { * identity. */ switch (val) { case 33 ... 126: - if (screen->glt) { - nval = (**screen->glt)[val - 32]; - screen->glt = NULL; + if (screen->state.glt) { + nval = (**screen->state.glt)[val - 32]; + screen->state.glt = NULL; } else { - nval = (**screen->gl)[val - 32]; + nval = (**screen->state.gl)[val - 32]; } break; case 160 ... 255: - if (screen->grt) { - nval = (**screen->grt)[val - 160]; - screen->grt = NULL; + if (screen->state.grt) { + nval = (**screen->state.grt)[val - 160]; + screen->state.grt = NULL; } else { - nval = (**screen->gr)[val - 160]; + nval = (**screen->state.gr)[val - 160]; } break; } @@ -471,20 +475,20 @@ static int screen_GRAPHIC(term_screen *screen, const term_seq *seq) { term_char_t ch = TERM_CHAR_NULL; uint32_t c; - if (screen->cursor_x + 1 == screen->page->width + if (screen->state.cursor_x + 1 == screen->page->width && screen->flags & TERM_FLAG_PENDING_WRAP - && screen->flags & TERM_FLAG_AUTO_WRAP) { + && screen->state.auto_wrap) { screen_cursor_down(screen, 1, true); - screen_cursor_set(screen, 0, screen->cursor_y); + screen_cursor_set(screen, 0, screen->state.cursor_y); } screen_cursor_clear_wrap(screen); c = screen_map(screen, seq->terminator); ch = term_char_merge(ch, screen_map(screen, c)); - term_page_write(screen->page, screen->cursor_x, screen->cursor_y, ch, 1, &screen->attr, screen->age, false); + term_page_write(screen->page, screen->state.cursor_x, screen->state.cursor_y, ch, 1, &screen->state.attr, screen->age, false); - if (screen->cursor_x + 1 == screen->page->width) + if (screen->state.cursor_x + 1 == screen->page->width) screen->flags |= TERM_FLAG_PENDING_WRAP; else screen_cursor_right(screen, 1); @@ -556,7 +560,7 @@ static int screen_CHA(term_screen *screen, const term_seq *seq) { pos = seq->args[0]; screen_cursor_clear_wrap(screen); - screen_cursor_set(screen, pos - 1, screen->cursor_y); + screen_cursor_set(screen, pos - 1, screen->state.cursor_y); return 0; } @@ -635,7 +639,7 @@ static int screen_CR(term_screen *screen, const term_seq *seq) { */ screen_cursor_clear_wrap(screen); - screen_cursor_set(screen, 0, screen->cursor_y); + screen_cursor_set(screen, 0, screen->state.cursor_y); return 0; } @@ -901,7 +905,7 @@ static int screen_DCH(term_screen *screen, const term_seq *seq) { num = seq->args[0]; screen_cursor_clear_wrap(screen); - term_page_delete_cells(screen->page, screen->cursor_x, screen->cursor_y, num, &screen->attr, screen->age); + term_page_delete_cells(screen->page, screen->state.cursor_x, screen->state.cursor_y, num, &screen->state.attr, screen->age); return 0; } @@ -1254,14 +1258,7 @@ static int screen_DECRC(term_screen *screen, const term_seq *seq) { * state for the main display and the status line. */ - screen->attr = screen->saved.attr; - screen->gl = screen->saved.gl; - screen->gr = screen->saved.gr; - screen->glt = screen->saved.glt; - screen->grt = screen->saved.grt; - set_reset(screen, TERM_FLAG_AUTO_WRAP, screen->saved.flags & TERM_FLAG_AUTO_WRAP); - set_reset(screen, TERM_FLAG_ORIGIN_MODE, screen->saved.flags & TERM_FLAG_ORIGIN_MODE); - screen_cursor_set(screen, screen->saved.cursor_x, screen->saved.cursor_y); + screen_restore_state(screen, &screen->saved); return 0; } @@ -1468,15 +1465,7 @@ static int screen_DECSC(term_screen *screen, const term_seq *seq) { * * Any single shift 2 (SS2) or single shift 3 (SS3) functions sent */ - screen->saved.cursor_x = screen->cursor_x; - screen->saved.cursor_y = screen->cursor_y; - screen->saved.attr = screen->attr; - screen->saved.gl = screen->gl; - screen->saved.gr = screen->gr; - screen->saved.glt = screen->glt; - screen->saved.grt = screen->grt; - screen->saved.flags = screen->flags & (TERM_FLAG_AUTO_WRAP - | TERM_FLAG_ORIGIN_MODE); + screen_save_state(screen, &screen->saved); return 0; } @@ -1503,10 +1492,10 @@ static int screen_DECSCA(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: case 2: - screen->attr.protect = 0; + screen->state.attr.protect = 0; break; case 1: - screen->attr.protect = 1; + screen->state.attr.protect = 1; break; } @@ -1671,21 +1660,21 @@ static int screen_DECSED(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: term_page_erase(screen->page, - screen->cursor_x, screen->cursor_y, + screen->state.cursor_x, screen->state.cursor_y, screen->page->width, screen->page->height, - &screen->attr, screen->age, true); + &screen->state.attr, screen->age, true); break; case 1: term_page_erase(screen->page, 0, 0, - screen->cursor_x, screen->cursor_y, - &screen->attr, screen->age, true); + screen->state.cursor_x, screen->state.cursor_y, + &screen->state.attr, screen->age, true); break; case 2: term_page_erase(screen->page, 0, 0, screen->page->width, screen->page->height, - &screen->attr, screen->age, true); + &screen->state.attr, screen->age, true); break; } @@ -1717,21 +1706,21 @@ static int screen_DECSEL(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: term_page_erase(screen->page, - screen->cursor_x, screen->cursor_y, - screen->page->width, screen->cursor_y, - &screen->attr, screen->age, true); + screen->state.cursor_x, screen->state.cursor_y, + screen->page->width, screen->state.cursor_y, + &screen->state.attr, screen->age, true); break; case 1: term_page_erase(screen->page, - 0, screen->cursor_y, - screen->cursor_x, screen->cursor_y, - &screen->attr, screen->age, true); + 0, screen->state.cursor_y, + screen->state.cursor_x, screen->state.cursor_y, + &screen->state.attr, screen->age, true); break; case 2: term_page_erase(screen->page, - 0, screen->cursor_y, - screen->page->width, screen->cursor_y, - &screen->attr, screen->age, true); + 0, screen->state.cursor_y, + screen->page->width, screen->state.cursor_y, + &screen->state.attr, screen->age, true); break; } @@ -2078,7 +2067,7 @@ static int screen_DL(term_screen *screen, const term_seq *seq) { if (seq->args[0] > 0) num = seq->args[0]; - term_page_delete_lines(screen->page, screen->cursor_y, num, &screen->attr, screen->age); + term_page_delete_lines(screen->page, screen->state.cursor_y, num, &screen->state.attr, screen->age); return 0; } @@ -2123,9 +2112,9 @@ static int screen_ECH(term_screen *screen, const term_seq *seq) { num = seq->args[0]; term_page_erase(screen->page, - screen->cursor_x, screen->cursor_y, - screen->cursor_x + num, screen->cursor_y, - &screen->attr, screen->age, false); + screen->state.cursor_x, screen->state.cursor_y, + screen->state.cursor_x + num, screen->state.cursor_y, + &screen->state.attr, screen->age, false); return 0; } @@ -2154,21 +2143,21 @@ static int screen_ED(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: term_page_erase(screen->page, - screen->cursor_x, screen->cursor_y, + screen->state.cursor_x, screen->state.cursor_y, screen->page->width, screen->page->height, - &screen->attr, screen->age, false); + &screen->state.attr, screen->age, false); break; case 1: term_page_erase(screen->page, 0, 0, - screen->cursor_x, screen->cursor_y, - &screen->attr, screen->age, false); + screen->state.cursor_x, screen->state.cursor_y, + &screen->state.attr, screen->age, false); break; case 2: term_page_erase(screen->page, 0, 0, screen->page->width, screen->page->height, - &screen->attr, screen->age, false); + &screen->state.attr, screen->age, false); break; } @@ -2198,21 +2187,21 @@ static int screen_EL(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: term_page_erase(screen->page, - screen->cursor_x, screen->cursor_y, - screen->page->width, screen->cursor_y, - &screen->attr, screen->age, false); + screen->state.cursor_x, screen->state.cursor_y, + screen->page->width, screen->state.cursor_y, + &screen->state.attr, screen->age, false); break; case 1: term_page_erase(screen->page, - 0, screen->cursor_y, - screen->cursor_x, screen->cursor_y, - &screen->attr, screen->age, false); + 0, screen->state.cursor_y, + screen->state.cursor_x, screen->state.cursor_y, + &screen->state.attr, screen->age, false); break; case 2: term_page_erase(screen->page, - 0, screen->cursor_y, - screen->page->width, screen->cursor_y, - &screen->attr, screen->age, false); + 0, screen->state.cursor_y, + screen->page->width, screen->state.cursor_y, + &screen->state.attr, screen->age, false); break; } @@ -2271,7 +2260,7 @@ static int screen_HPA(term_screen *screen, const term_seq *seq) { num = seq->args[0]; screen_cursor_clear_wrap(screen); - screen_cursor_set(screen, num - 1, screen->cursor_y); + screen_cursor_set(screen, num - 1, screen->state.cursor_y); return 0; } @@ -2327,7 +2316,7 @@ static int screen_HTS(term_screen *screen, const term_seq *seq) { unsigned int pos; - pos = screen->cursor_x; + pos = screen->state.cursor_x; if (screen->page->width > 0) screen->tabs[pos / 8] |= 1U << (pos % 8); @@ -2372,7 +2361,7 @@ static int screen_ICH(term_screen *screen, const term_seq *seq) { num = seq->args[0]; screen_cursor_clear_wrap(screen); - term_page_insert_cells(screen->page, screen->cursor_x, screen->cursor_y, num, &screen->attr, screen->age); + term_page_insert_cells(screen->page, screen->state.cursor_x, screen->state.cursor_y, num, &screen->state.attr, screen->age); return 0; } @@ -2398,7 +2387,7 @@ static int screen_IL(term_screen *screen, const term_seq *seq) { num = seq->args[0]; screen_cursor_clear_wrap(screen); - term_page_insert_lines(screen->page, screen->cursor_y, num, &screen->attr, screen->age); + term_page_insert_lines(screen->page, screen->state.cursor_y, num, &screen->state.attr, screen->age); return 0; } @@ -2424,7 +2413,7 @@ static int screen_LF(term_screen *screen, const term_seq *seq) { screen_cursor_down(screen, 1, true); if (screen->flags & TERM_FLAG_NEWLINE_MODE) - screen_cursor_left(screen, screen->cursor_x); + screen_cursor_left(screen, screen->state.cursor_x); return 0; } @@ -2435,7 +2424,7 @@ static int screen_LS1R(term_screen *screen, const term_seq *seq) { * Map G1 into GR. */ - screen->gr = &screen->g1; + screen->state.gr = &screen->g1; return 0; } @@ -2446,7 +2435,7 @@ static int screen_LS2(term_screen *screen, const term_seq *seq) { * Map G2 into GL. */ - screen->gl = &screen->g2; + screen->state.gl = &screen->g2; return 0; } @@ -2457,7 +2446,7 @@ static int screen_LS2R(term_screen *screen, const term_seq *seq) { * Map G2 into GR. */ - screen->gr = &screen->g2; + screen->state.gr = &screen->g2; return 0; } @@ -2468,7 +2457,7 @@ static int screen_LS3(term_screen *screen, const term_seq *seq) { * Map G3 into GL. */ - screen->gl = &screen->g3; + screen->state.gl = &screen->g3; return 0; } @@ -2479,7 +2468,7 @@ static int screen_LS3R(term_screen *screen, const term_seq *seq) { * Map G3 into GR. */ - screen->gr = &screen->g3; + screen->state.gr = &screen->g3; return 0; } @@ -2513,7 +2502,7 @@ static int screen_NEL(term_screen *screen, const term_seq *seq) { screen_cursor_clear_wrap(screen); screen_cursor_down(screen, 1, true); - screen_cursor_set(screen, 0, screen->cursor_y); + screen_cursor_set(screen, 0, screen->state.cursor_y); return 0; } @@ -2834,7 +2823,7 @@ static int screen_SD(term_screen *screen, const term_seq *seq) { if (seq->args[0] > 0) num = seq->args[0]; - term_page_scroll_down(screen->page, num, &screen->attr, screen->age, NULL); + term_page_scroll_down(screen->page, num, &screen->state.attr, screen->age, NULL); return 0; } @@ -2849,7 +2838,7 @@ static int screen_SGR(term_screen *screen, const term_seq *seq) { int v; if (seq->n_args < 1) { - zero(screen->attr); + zero(screen->state.attr); return 0; } @@ -2857,67 +2846,67 @@ static int screen_SGR(term_screen *screen, const term_seq *seq) { v = seq->args[i]; switch (v) { case 1: - screen->attr.bold = 1; + screen->state.attr.bold = 1; break; case 3: - screen->attr.italic = 1; + screen->state.attr.italic = 1; break; case 4: - screen->attr.underline = 1; + screen->state.attr.underline = 1; break; case 5: - screen->attr.blink = 1; + screen->state.attr.blink = 1; break; case 7: - screen->attr.inverse = 1; + screen->state.attr.inverse = 1; break; case 8: - screen->attr.hidden = 1; + screen->state.attr.hidden = 1; break; case 22: - screen->attr.bold = 0; + screen->state.attr.bold = 0; break; case 23: - screen->attr.italic = 0; + screen->state.attr.italic = 0; break; case 24: - screen->attr.underline = 0; + screen->state.attr.underline = 0; break; case 25: - screen->attr.blink = 0; + screen->state.attr.blink = 0; break; case 27: - screen->attr.inverse = 0; + screen->state.attr.inverse = 0; break; case 28: - screen->attr.hidden = 0; + screen->state.attr.hidden = 0; break; case 30 ... 37: - screen->attr.fg.ccode = v - 30 + TERM_CCODE_BLACK; + screen->state.attr.fg.ccode = v - 30 + TERM_CCODE_BLACK; break; case 39: - screen->attr.fg.ccode = 0; + screen->state.attr.fg.ccode = 0; break; case 40 ... 47: - screen->attr.bg.ccode = v - 40 + TERM_CCODE_BLACK; + screen->state.attr.bg.ccode = v - 40 + TERM_CCODE_BLACK; break; case 49: - screen->attr.bg.ccode = 0; + screen->state.attr.bg.ccode = 0; break; case 90 ... 97: - screen->attr.fg.ccode = v - 90 + TERM_CCODE_LIGHT_BLACK; + screen->state.attr.fg.ccode = v - 90 + TERM_CCODE_LIGHT_BLACK; break; case 100 ... 107: - screen->attr.bg.ccode = v - 100 + TERM_CCODE_LIGHT_BLACK; + screen->state.attr.bg.ccode = v - 100 + TERM_CCODE_LIGHT_BLACK; break; case 38: /* fallthrough */ case 48: if (v == 38) - dst = &screen->attr.fg; + dst = &screen->state.attr.fg; else - dst = &screen->attr.bg; + dst = &screen->state.attr.bg; ++i; if (i >= seq->n_args) @@ -2955,7 +2944,7 @@ static int screen_SGR(term_screen *screen, const term_seq *seq) { case -1: /* fallthrough */ case 0: - zero(screen->attr); + zero(screen->state.attr); break; } } @@ -2969,7 +2958,7 @@ static int screen_SI(term_screen *screen, const term_seq *seq) { * Map G0 into GL. */ - screen->gl = &screen->g0; + screen->state.gl = &screen->g0; return 0; } @@ -3009,7 +2998,7 @@ static int screen_SO(term_screen *screen, const term_seq *seq) { * Map G1 into GL. */ - screen->gl = &screen->g1; + screen->state.gl = &screen->g1; return 0; } @@ -3030,7 +3019,7 @@ static int screen_SS2(term_screen *screen, const term_seq *seq) { * Temporarily map G2 into GL for the next graphics character. */ - screen->glt = &screen->g2; + screen->state.glt = &screen->g2; return 0; } @@ -3041,7 +3030,7 @@ static int screen_SS3(term_screen *screen, const term_seq *seq) { * Temporarily map G3 into GL for the next graphics character */ - screen->glt = &screen->g3; + screen->state.glt = &screen->g3; return 0; } @@ -3077,7 +3066,7 @@ static int screen_SU(term_screen *screen, const term_seq *seq) { if (seq->args[0] > 0) num = seq->args[0]; - term_page_scroll_up(screen->page, num, &screen->attr, screen->age, screen->history); + term_page_scroll_up(screen->page, num, &screen->state.attr, screen->age, screen->history); return 0; } @@ -3116,7 +3105,7 @@ static int screen_TBC(term_screen *screen, const term_seq *seq) { switch (mode) { case 0: - pos = screen->cursor_x; + pos = screen->state.cursor_x; if (screen->page->width > 0) screen->tabs[pos / 8] &= ~(1U << (pos % 8)); break; @@ -3147,7 +3136,7 @@ static int screen_VPA(term_screen *screen, const term_seq *seq) { pos = seq->args[0]; screen_cursor_clear_wrap(screen); - screen_cursor_set_rel(screen, screen->cursor_x, pos - 1); + screen_cursor_set_rel(screen, screen->state.cursor_x, pos - 1); return 0; } @@ -4104,11 +4093,11 @@ int term_screen_resize(term_screen *screen, unsigned int x, unsigned int y) { assert_return(screen, -EINVAL); - r = term_page_reserve(screen->page_main, x, y, &screen->attr, screen->age); + r = term_page_reserve(screen->page_main, x, y, &screen->state.attr, screen->age); if (r < 0) return r; - r = term_page_reserve(screen->page_alt, x, y, &screen->attr, screen->age); + r = term_page_reserve(screen->page_alt, x, y, &screen->state.attr, screen->age); if (r < 0) return r; @@ -4124,11 +4113,11 @@ int term_screen_resize(term_screen *screen, unsigned int x, unsigned int y) { for (i = (screen->page->width + 7) / 8 * 8; i < x; i += 8) screen->tabs[i / 8] = 0x1; - term_page_resize(screen->page_main, x, y, &screen->attr, screen->age, screen->history); - term_page_resize(screen->page_alt, x, y, &screen->attr, screen->age, NULL); + term_page_resize(screen->page_main, x, y, &screen->state.attr, screen->age, screen->history); + term_page_resize(screen->page_alt, x, y, &screen->state.attr, screen->age, NULL); - screen->cursor_x = screen_clamp_x(screen, screen->cursor_x); - screen->cursor_y = screen_clamp_x(screen, screen->cursor_y); + screen->state.cursor_x = screen_clamp_x(screen, screen->state.cursor_x); + screen->state.cursor_y = screen_clamp_x(screen, screen->state.cursor_y); screen_cursor_clear_wrap(screen); return 0; @@ -4139,29 +4128,26 @@ void term_screen_soft_reset(term_screen *screen) { assert(screen); - screen->gl = &screen->g0; - screen->gr = &screen->g1; - screen->glt = NULL; - screen->grt = NULL; screen->g0 = &term_unicode_lower; screen->g1 = &term_unicode_upper; screen->g2 = &term_unicode_lower; screen->g3 = &term_unicode_upper; + screen->state.attr = screen->default_attr; + screen->state.gl = &screen->g0; + screen->state.gr = &screen->g1; + screen->state.glt = NULL; + screen->state.grt = NULL; + screen->state.auto_wrap = 0; + screen->state.origin_mode = 0; + + screen->saved = screen->state; + screen->saved.cursor_x = 0; + screen->saved.cursor_y = 0; screen->page = screen->page_main; screen->history = screen->history_main; screen->flags = TERM_FLAG_7BIT_MODE; screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT400; - screen->attr = screen->default_attr; - - screen->saved.cursor_x = 0; - screen->saved.cursor_y = 0; - screen->saved.attr = screen->attr; - screen->saved.gl = screen->gl; - screen->saved.gr = screen->gr; - screen->saved.glt = NULL; - screen->saved.grt = NULL; - screen->flags = 0; for (i = 0; i < screen->page->width; i += 8) screen->tabs[i / 8] = 0x1; @@ -4175,10 +4161,10 @@ void term_screen_hard_reset(term_screen *screen) { term_screen_soft_reset(screen); zero(screen->utf8); - screen->cursor_x = 0; - screen->cursor_y = 0; - term_page_erase(screen->page_main, 0, 0, screen->page->width, screen->page->height, &screen->attr, screen->age, false); - term_page_erase(screen->page_alt, 0, 0, screen->page->width, screen->page->height, &screen->attr, screen->age, false); + screen->state.cursor_x = 0; + screen->state.cursor_y = 0; + term_page_erase(screen->page_main, 0, 0, screen->page->width, screen->page->height, &screen->state.attr, screen->age, false); + term_page_erase(screen->page_alt, 0, 0, screen->page->width, screen->page->height, &screen->state.attr, screen->age, false); } int term_screen_set_answerback(term_screen *screen, const char *answerback) { @@ -4248,7 +4234,7 @@ int term_screen_draw(term_screen *screen, cw = MAX(cell->cwidth, 1U); attr = cell->attr; - if (i == screen->cursor_x && j == screen->cursor_y && + if (i == screen->state.cursor_x && j == screen->state.cursor_y && !(screen->flags & TERM_FLAG_HIDE_CURSOR)) attr.inverse ^= 1;