summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryokota <yokota@FreeBSD.org>1999-09-19 08:07:46 +0000
committeryokota <yokota@FreeBSD.org>1999-09-19 08:07:46 +0000
commit09aa378c3422ad091498dce5633107c5610ab1e1 (patch)
treedc367cc913ac237b97db13ba9587b3ba4d2a4818
parent30dba378e9ab72e2f18039afa73b5517a1b7f4e5 (diff)
downloadFreeBSD-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.c53
-rw-r--r--sys/dev/syscons/scvidctl.c8
-rw-r--r--sys/dev/syscons/syscons.h1
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);
OpenPOWER on IntegriCloud