summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-10-04 20:14:31 +0200
committerTom Gundersen <teg@jklm.no>2014-10-05 01:23:42 +0200
commit10b119d9a85fbaf99ebc2324eac509319b950aaf (patch)
tree19fa244bc020cb74159b2fa51baaf07374f2918e
parentbdf7026e9557349cd3eeb291c01655d5f2a55db8 (diff)
sd-terminal: support alternate page switching
This adds rmcup/smcup support.
-rw-r--r--src/libsystemd-terminal/term-screen.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/src/libsystemd-terminal/term-screen.c b/src/libsystemd-terminal/term-screen.c
index 145dcdaee..f9352ad94 100644
--- a/src/libsystemd-terminal/term-screen.c
+++ b/src/libsystemd-terminal/term-screen.c
@@ -370,6 +370,26 @@ static inline void set_reset(term_screen *screen, unsigned int flag, bool set) {
screen->flags &= ~flag;
}
+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) {
+ 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);
+}
+
+static inline void screen_set_alt(term_screen *screen, bool set) {
+ if (set) {
+ screen->page = screen->page_alt;
+ screen->history = NULL;
+ } else {
+ screen->page = screen->page_main;
+ screen->history = screen->history_main;
+ }
+
+ screen->page->age = screen->age;
+}
+
static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, bool set) {
switch (mode) {
case 1:
@@ -423,6 +443,44 @@ static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec,
}
break;
+ case 47:
+ if (dec)
+ screen_set_alt(screen, set);
+
+ break;
+ case 1047:
+ if (dec) {
+ if (!set)
+ screen_clear_alt(screen);
+
+ screen_set_alt(screen, set);
+ }
+
+ break;
+ case 1048:
+ if (dec) {
+ if (set)
+ screen_DECSC(screen, seq);
+ else
+ screen_DECRC(screen, seq);
+ }
+
+ 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_clear_alt(screen);
+ }
+
+ screen_set_alt(screen, set);
+
+ if (!set)
+ screen_DECRC(screen, seq);
+ }
+
+ break;
}
}
@@ -1235,7 +1293,7 @@ static int screen_DECRARA(term_screen *screen, const term_seq *seq) {
return 0;
}
-static int screen_DECRC(term_screen *screen, const term_seq *seq) {
+int screen_DECRC(term_screen *screen, const term_seq *seq) {
/*
* DECRC - restore-cursor
* Restores the terminal to the state saved by the save cursor (DECSC)
@@ -1454,7 +1512,7 @@ static int screen_DECSASD(term_screen *screen, const term_seq *seq) {
return 0;
}
-static int screen_DECSC(term_screen *screen, const term_seq *seq) {
+int screen_DECSC(term_screen *screen, const term_seq *seq) {
/*
* DECSC - save-cursor
* Save cursor and terminal state so it can be restored later on.