diff options
author | yokota <yokota@FreeBSD.org> | 1999-09-19 08:07:46 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1999-09-19 08:07:46 +0000 |
commit | 09aa378c3422ad091498dce5633107c5610ab1e1 (patch) | |
tree | dc367cc913ac237b97db13ba9587b3ba4d2a4818 | |
parent | 30dba378e9ab72e2f18039afa73b5517a1b7f4e5 (diff) | |
download | FreeBSD-src-09aa378c3422ad091498dce5633107c5610ab1e1.zip FreeBSD-src-09aa378c3422ad091498dce5633107c5610ab1e1.tar.gz |
- Preserve the content of the back scroll buffer when changing the
video mode.
Requested by: a lot of people.
PR: kern/13764
-rw-r--r-- | sys/dev/syscons/schistory.c | 53 | ||||
-rw-r--r-- | sys/dev/syscons/scvidctl.c | 8 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 1 |
3 files changed, 52 insertions, 10 deletions
diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c index cf9585b..71c8991 100644 --- a/sys/dev/syscons/schistory.c +++ b/sys/dev/syscons/schistory.c @@ -64,6 +64,7 @@ static int extra_history_size = SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE*MAXCONS; /* local functions */ +static void copy_history(sc_vtb_t *from, sc_vtb_t *to); static void history_to_screen(scr_stat *scp); /* allocate a history buffer */ @@ -111,28 +112,60 @@ sc_alloc_history_buffer(scr_stat *scp, int lines, int prev_ysize, int wait) } } - /* destroy the previous buffer and allocate a new one */ - if (prev_history == NULL) { - history = (sc_vtb_t *)malloc(sizeof(*history), - M_DEVBUF, - (wait) ? M_WAITOK : M_NOWAIT); - } else { - extra_history_size += delta; - sc_vtb_destroy(prev_history); - } + /* allocate a new buffer */ + history = (sc_vtb_t *)malloc(sizeof(*history), + M_DEVBUF, + (wait) ? M_WAITOK : M_NOWAIT); if (history != NULL) { if (lines > min_lines) extra_history_size -= lines - min_lines; sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines, NULL, wait); + sc_vtb_clear(history, scp->sc->scr_map[0x20], + scp->term.cur_color); + if (prev_history != NULL) + copy_history(prev_history, history); + scp->history_pos = sc_vtb_tail(history); + } else { + scp->history_pos = 0; + } + + /* destroy the previous buffer */ + if (prev_history != NULL) { + extra_history_size += delta; + sc_vtb_destroy(prev_history); } - scp->history_pos = 0; scp->history = history; return 0; } +static void +copy_history(sc_vtb_t *from, sc_vtb_t *to) +{ + int lines; + int cols; + int cols1; + int cols2; + int pos; + int i; + + lines = sc_vtb_rows(from); + cols1 = sc_vtb_cols(from); + cols2 = sc_vtb_cols(to); + cols = imin(cols1, cols2); + pos = sc_vtb_tail(from); + for (i = 0; i < lines; ++i) { + sc_vtb_append(from, pos, to, cols); + if (cols < cols2) + sc_vtb_seek(to, sc_vtb_pos(to, + sc_vtb_tail(to), + cols2 - cols)); + pos = sc_vtb_pos(from, pos, cols1); + } +} + void sc_free_history_buffer(scr_stat *scp, int prev_ysize) { diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index eeee089..e9716c3 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -189,6 +189,10 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, } /* set up scp */ +#ifndef SC_NO_HISTORY + if (scp->history != NULL) + sc_hist_save(scp); +#endif prev_ysize = scp->ysize; /* * This is a kludge to fend off scrn_update() while we @@ -401,6 +405,10 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, } /* set up scp */ +#ifndef SC_NO_HISTORY + if (scp->history != NULL) + sc_hist_save(scp); +#endif prev_ysize = scp->ysize; scp->status |= (UNKNOWN_MODE | PIXEL_MODE); scp->status &= ~GRAPHICS_MODE; diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index 01d82a0..674371f1 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -489,6 +489,7 @@ int sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset); #define sc_vtb_tail(vtb) ((vtb)->vtb_tail) #define sc_vtb_rows(vtb) ((vtb)->vtb_rows) +#define sc_vtb_cols(vtb) ((vtb)->vtb_cols) void sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count); |