diff options
author | Tom Gundersen <teg@jklm.no> | 2014-10-04 23:48:22 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-10-05 01:24:57 +0200 |
commit | a6a94db23a2a43ef46ee2450aaa4d81b084a4937 (patch) | |
tree | d17b6057d4fc12ed3c74b55ba6434718eab73196 | |
parent | 498572a75f8261fd12caf84c04f53f754b2bbe24 (diff) |
sd-terminal: save cursor settings per-page rather than per-screenterminal
This is how xterm works:
<http://invisible-island.net/xterm/xterm.log.html#xterm_90>.
-rw-r--r-- | src/libsystemd-terminal/term-internal.h | 41 | ||||
-rw-r--r-- | src/libsystemd-terminal/term-screen.c | 74 |
2 files changed, 64 insertions, 51 deletions
diff --git a/src/libsystemd-terminal/term-internal.h b/src/libsystemd-terminal/term-internal.h index f0f4432c8..c5e0be6b7 100644 --- a/src/libsystemd-terminal/term-internal.h +++ b/src/libsystemd-terminal/term-internal.h @@ -600,6 +600,17 @@ enum { TERM_CONFORMANCE_LEVEL_CNT, }; +struct term_cursor { + 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; +}; + struct term_screen { unsigned long ref; term_age_t age; @@ -621,32 +632,26 @@ struct term_screen { term_screen_cmd_fn cmd_fn; void *cmd_fn_data; - unsigned int flags; unsigned int conformance_level; + term_attr default_attr; + + term_charset *g0; + term_charset *g1; + term_charset *g2; + term_charset *g3; + 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; - term_charset *g3; + unsigned int flags; - char *answerback; + struct term_cursor *saved; + struct term_cursor saved_main; + struct term_cursor saved_alt; - 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; + char *answerback; }; diff --git a/src/libsystemd-terminal/term-screen.c b/src/libsystemd-terminal/term-screen.c index ec6c14d98..3aeb6ed39 100644 --- a/src/libsystemd-terminal/term-screen.c +++ b/src/libsystemd-terminal/term-screen.c @@ -77,11 +77,13 @@ int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *writ 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->saved_main.cursor_x = 0; + screen->saved_main.cursor_y = 0; + screen->saved_main.attr = screen->attr; + screen->saved_main.gl = screen->gl; + screen->saved_main.gr = screen->gr; + + screen->saved_alt = screen->saved_main; r = term_page_new(&screen->page_main); if (r < 0) @@ -101,6 +103,7 @@ int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *writ screen->page = screen->page_main; screen->history = screen->history_main; + screen->saved = &screen->saved_main; *out = screen; screen = NULL; @@ -374,6 +377,11 @@ static int screen_DECSC(term_screen *screen, const term_seq *seq); static int screen_DECRC(term_screen *screen, const term_seq *seq); static inline void screen_clear_alt(term_screen *screen) { + zero(screen->saved_alt); + screen->saved_main.attr = screen->attr; + screen->saved_main.gl = screen->gl; + screen->saved_main.gr = screen->gr; + term_page_set_scroll_region(screen->page_alt, 0, screen->page->height); term_page_erase(screen->page_alt, 0, 0, screen->page->width, screen->page->height, &screen->attr, screen->age, false); } @@ -460,24 +468,23 @@ static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, case 1048: if (dec) { if (set) - screen_DECSC(screen, seq); + screen_DECSC(screen, NULL); else - screen_DECRC(screen, seq); + screen_DECRC(screen, NULL); } break; case 1049: if (dec) { - /* TODO: should DEC{S,R}C be done per-page, rather than per-screen? */ if (set) { - screen_DECSC(screen, seq); + screen_DECSC(screen, NULL); screen_clear_alt(screen); } screen_set_alt(screen, set); if (!set) - screen_DECRC(screen, seq); + screen_DECRC(screen, NULL); } break; @@ -1312,14 +1319,14 @@ 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->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); return 0; } @@ -1526,14 +1533,14 @@ 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 + 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); return 0; @@ -4208,17 +4215,18 @@ void term_screen_soft_reset(term_screen *screen) { screen->page = screen->page_main; screen->history = screen->history_main; + screen->saved = &screen->saved_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; + zero(screen->saved_main); + screen->saved_main.attr = screen->attr; + screen->saved_main.gl = screen->gl; + screen->saved_main.gr = screen->gr; + + screen->saved_alt = screen->saved_main; + screen->flags = 0; for (i = 0; i < screen->page->width; i += 8) |