From fa6e846f31bb4e1ca0093c707bd2d2080526939c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Imre=20Vad=C3=A1sz?= Date: Wed, 11 Nov 2015 21:53:03 +0100 Subject: [PATCH] syscons: Keep screen content and cursor pos when switching to kms console. --- sys/dev/misc/syscons/schistory.c | 21 +++++++++++++++++++-- sys/dev/misc/syscons/scvidctl.c | 12 ++++++++++++ sys/dev/misc/syscons/syscons.h | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/sys/dev/misc/syscons/schistory.c b/sys/dev/misc/syscons/schistory.c index dbd0291c9f..d75f32b663 100644 --- a/sys/dev/misc/syscons/schistory.c +++ b/sys/dev/misc/syscons/schistory.c @@ -66,6 +66,7 @@ static int extra_history_size /* local functions */ static void copy_history(sc_vtb_t *from, sc_vtb_t *to); static void history_to_screen(scr_stat *scp); +static void history_to_screen_lines(scr_stat *scp, int cnt); /* allocate a history buffer */ int @@ -219,15 +220,23 @@ sc_hist_restore(scr_stat *scp) /* copy screen-full of saved lines */ static void history_to_screen(scr_stat *scp) +{ + history_to_screen_lines(scp, scp->ysize); +} + +/* copy cnt of saved lines */ +static void +history_to_screen_lines(scr_stat *scp, int cnt) { int pos; int i; + int lines = imin(cnt, scp->ysize); pos = scp->history_pos; - for (i = 1; i <= scp->ysize; ++i) { + for (i = 1; i <= lines; ++i) { pos = sc_vtb_pos(scp->history, pos, -scp->xsize); sc_vtb_copy(scp->history, pos, - &scp->vtb, scp->xsize*(scp->ysize - i), + &scp->vtb, scp->xsize*(lines - i), scp->xsize); } mark_all(scp); @@ -241,6 +250,14 @@ sc_hist_home(scr_stat *scp) history_to_screen(scp); } +/* Restore old_ysize lines from the tail of the history buffer */ +void +sc_hist_getback(scr_stat *scp, int old_ysize) +{ + scp->history_pos = sc_vtb_tail(scp->history); + history_to_screen_lines(scp, old_ysize); +} + /* go to the top of the history buffer */ void sc_hist_end(scr_stat *scp) diff --git a/sys/dev/misc/syscons/scvidctl.c b/sys/dev/misc/syscons/scvidctl.c index 58dfcb3f0d..68f07965ec 100644 --- a/sys/dev/misc/syscons/scvidctl.c +++ b/sys/dev/misc/syscons/scvidctl.c @@ -762,6 +762,9 @@ sc_update_render(scr_stat *scp) sc_term_sw_t *sw; struct tty *tp; int prev_ysize, new_ysize; +#ifndef SC_NO_HISTORY + int old_xpos, old_ypos; +#endif int error; sw = scp->tsw; @@ -793,7 +796,12 @@ sc_update_render(scr_stat *scp) } new_ysize = 0; #ifndef SC_NO_HISTORY + old_xpos = old_ypos = 0; if (scp->history != NULL) { + if (scp->xsize > 0) { + old_xpos = scp->xpos; + old_ypos = scp->ypos; + } sc_hist_save(scp); new_ysize = sc_vtb_rows(scp->history); } @@ -850,6 +858,10 @@ sc_update_render(scr_stat *scp) #endif #ifndef SC_NO_HISTORY sc_alloc_history_buffer(scp, new_ysize, prev_ysize, FALSE); + if (scp->history != NULL) { + sc_hist_getback(scp, prev_ysize); + sc_move_cursor(scp, old_xpos, old_ypos); + } #endif crit_exit(); scp->status &= ~UNKNOWN_MODE; diff --git a/sys/dev/misc/syscons/syscons.h b/sys/dev/misc/syscons/syscons.h index b05d33d6e1..2137e39bd7 100644 --- a/sys/dev/misc/syscons/syscons.h +++ b/sys/dev/misc/syscons/syscons.h @@ -537,6 +537,7 @@ void sc_hist_save(scr_stat *scp); sc_vtb_append(&(scp)->vtb, (from), (scp)->history, (scp)->xsize) int sc_hist_restore(scr_stat *scp); void sc_hist_home(scr_stat *scp); +void sc_hist_getback(scr_stat *scp, int old_ysize); void sc_hist_end(scr_stat *scp); int sc_hist_up_line(scr_stat *scp); int sc_hist_down_line(scr_stat *scp); -- 2.41.0