diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 1999-09-06 00:12:41 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 1999-09-06 00:12:41 +0000 |
commit | 5a62cd9616ed6003bb80b5ea059f93b7df501b4e (patch) | |
tree | 02e6bee514174c4ec97ff20a48cc6e6b1afac396 /sys/arch | |
parent | fd7828d77426587c17477b91a61261c53380bfdb (diff) |
Add scrollback support to the pcvt (i386 only) console driver.
Press LEFT_SHIFT+PGUP/PGDN to navigate. Number of buffered pages is currently
only configurable by editing sys/arch/i386/isa/pcvt/pcvt_hdr.h and changing
the SCROLLBACK_PAGES constant.
You must add "option PCVT_SCROLLBACK" to your kernel config file to enable
this support, or uncomment it from sys/arch/i386/conf/GENERIC.
Known issues:
- Few little buglets when switching line (font) or column modes in scon(1).
- Can't hold down LEFT_SHIFT+PGUP/PGDN keys. This will be fixed...
Idea from Linux, code by me.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/i386/isa/pcvt/pcvt_drv.c | 8 | ||||
-rw-r--r-- | sys/arch/i386/isa/pcvt/pcvt_ext.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/isa/pcvt/pcvt_hdr.h | 23 | ||||
-rw-r--r-- | sys/arch/i386/isa/pcvt/pcvt_kbd.c | 141 | ||||
-rw-r--r-- | sys/arch/i386/isa/pcvt/pcvt_out.c | 86 |
6 files changed, 267 insertions, 9 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index 550965e35ff..d9e04e5c5b1 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.126 1999/08/31 07:55:01 fgsch Exp $ +# $OpenBSD: GENERIC,v 1.127 1999/09/06 00:12:39 aaron Exp $ # $NetBSD: GENERIC,v 1.48 1996/05/20 18:17:23 mrg Exp $ # # GENERIC -- everything that's currently supported @@ -31,6 +31,8 @@ option COMPAT_LINUX # binary compatibility with Linux option COMPAT_FREEBSD # binary compatibility with FreeBSD option COMPAT_BSDOS # binary compatibility with BSD/OS +#option PCVT_SCROLLBACK # pcvt console scrollback support + maxusers 32 # estimated number of users config bsd swap generic diff --git a/sys/arch/i386/isa/pcvt/pcvt_drv.c b/sys/arch/i386/isa/pcvt/pcvt_drv.c index 33f2adde5e1..1ae909417d9 100644 --- a/sys/arch/i386/isa/pcvt/pcvt_drv.c +++ b/sys/arch/i386/isa/pcvt/pcvt_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcvt_drv.c,v 1.22 1998/11/20 15:57:25 deraadt Exp $ */ +/* $OpenBSD: pcvt_drv.c,v 1.23 1999/09/06 00:12:39 aaron Exp $ */ /* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. @@ -706,7 +706,13 @@ pcstart(register struct tty *tp) */ while ((len = q_to_b(&tp->t_outq, buf, PCVT_PCBURST)) != 0) + { +#ifdef PCVT_SCROLLBACK + if (vs[minor(tp->t_dev)].scrolling) + sgetc(31337); +#endif sput(&buf[0], 0, len, minor(tp->t_dev)); + } s = spltty(); diff --git a/sys/arch/i386/isa/pcvt/pcvt_ext.c b/sys/arch/i386/isa/pcvt/pcvt_ext.c index c9a89c09bf3..1bb3c492ff1 100644 --- a/sys/arch/i386/isa/pcvt/pcvt_ext.c +++ b/sys/arch/i386/isa/pcvt/pcvt_ext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcvt_ext.c,v 1.17 1998/09/28 03:00:27 downsj Exp $ */ +/* $OpenBSD: pcvt_ext.c,v 1.18 1999/09/06 00:12:40 aaron Exp $ */ /* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. @@ -2552,6 +2552,18 @@ vgapage(int new_screen) { /* we are committed */ vt_switch_pending = 0; +#ifdef PCVT_SCROLLBACK + if (vsp->Scrollback) + { + vsp->scrolling = 0; + fillw(user_attr | ' ', (caddr_t)vsp->Scrollback, + vsp->screen_rowsize * vsp->maxcol * + SCROLLBACK_PAGES); + bcopy(vsp->Crtat, vsp->Scrollback, + vsp->screen_rows * vsp->maxcol * CHR); + vsp->scr_offset = vsp->row - 1; + } +#endif } } return 0; diff --git a/sys/arch/i386/isa/pcvt/pcvt_hdr.h b/sys/arch/i386/isa/pcvt/pcvt_hdr.h index c59a577030b..5d3bf399143 100644 --- a/sys/arch/i386/isa/pcvt/pcvt_hdr.h +++ b/sys/arch/i386/isa/pcvt/pcvt_hdr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcvt_hdr.h,v 1.21 1998/09/06 23:00:03 niklas Exp $ */ +/* $OpenBSD: pcvt_hdr.h,v 1.22 1999/09/06 00:12:40 aaron Exp $ */ /* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. @@ -603,6 +603,13 @@ #define SYS_FKL 0 /* in hp mode, sys-fkls are active */ #define USR_FKL 1 /* in hp mode, user-fkls are active */ +#ifdef PCVT_SCROLLBACK + +/* scrollback buffer size (in pages) */ +#define SCROLLBACK_PAGES 8 + +#endif + /* variables */ #ifdef EXTERN @@ -646,6 +653,12 @@ struct rgb { typedef struct video_state { u_short *Crtat; /* video page start addr */ u_short *Memory; /* malloc'ed memory start address */ +#ifdef PCVT_SCROLLBACK + u_short *Scrollback; /* scrollback buffer */ + u_short scr_offset; /* current scrollback offset (lines) */ + short scrolling; /* current scrollback page */ + u_short max_off; /* maximum scrollback offset */ +#endif struct tty *vs_tty; /* pointer to this screen's tty */ u_char maxcol; /* 80 or 132 cols on screen */ u_char row, col; /* current cursor position */ @@ -821,6 +834,10 @@ struct tty *pcconsp; /* ptr to current device, see pcattach() */ u_short *Crtat; /* screen start address */ +#ifdef PCVT_SCROLLBACK +u_short *Scrollbuffer; /* scrollback buffer */ +#endif + #if PCVT_EMU_MOUSE struct mousestat mouse = {{0}}; struct mousedefs mousedef = {0x3b, 0x3c, 0x3d, 0, 250000}; @@ -978,6 +995,10 @@ extern u_char vga_family; extern u_char keyboard_is_initialized; extern u_char kbd_polling; +#ifdef PCVT_SCROLLBACK +extern u_short *Scrollbuffer; +#endif + #if PCVT_SHOWKEYS extern u_char keyboard_show; #endif /* PCVT_SHOWKEYS */ diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.c b/sys/arch/i386/isa/pcvt/pcvt_kbd.c index 293955e4ef3..369ff540929 100644 --- a/sys/arch/i386/isa/pcvt/pcvt_kbd.c +++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcvt_kbd.c,v 1.20 1999/07/06 07:59:54 deraadt Exp $ */ +/* $OpenBSD: pcvt_kbd.c,v 1.21 1999/09/06 00:12:40 aaron Exp $ */ /* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. @@ -115,6 +115,13 @@ static int tpmrate = KBD_TPD500|KBD_TPM100; static u_char altkpflag = 0; static u_short altkpval = 0; +#ifdef PCVT_SCROLLBACK +static u_short *scrollback_savedscreen = (u_short *)0; +static size_t scrnsv_size = (size_t)-1; +static void scrollback_save_screen ( void ); +static void scrollback_restore_screen ( void ); +#endif + extern int kbd_reset; #if PCVT_SHOWKEYS @@ -1088,6 +1095,13 @@ loop: #if PCVT_KBD_FIFO +#ifdef PCVT_SCROLLBACK + if (noblock == 31337) { + vsp->scrolling = 1; + goto scroll_reset; + } +#endif + /* see if there is data from the keyboard available either from */ /* the keyboard fifo or from the 8042 keyboard controller */ @@ -1413,7 +1427,7 @@ no_mouse_event: #if PCVT_SHOWKEYS showkey (' ', dt); -#endif /* PCVT_SHOWKEYS */ +#endif /* PCVT_SHOWKEYS */ /* lets look what we got */ switch(dt) @@ -1474,6 +1488,98 @@ regular: kbd_status.extended = kbd_status.ext1 = 0; +#ifdef PCVT_SCROLLBACK + if ((key == 85) && shift_down && kbd_lastkey != 85) + { + if (vsp->scr_offset >= (vsp->screen_rows - 1)) + { + if (!vsp->scrolling) + { + vsp->scrolling += vsp->screen_rows - 1; + if (vsp->Scrollback) + { + scrollback_save_screen(); + if (vsp->scr_offset == vsp->max_off) + { + bcopy(vsp->Scrollback + + vsp->maxcol, + vsp->Scrollback, + vsp->maxcol * + vsp->max_off * CHR); + vsp->scr_offset--; + } + bcopy(vsp->Crtat + vsp->cur_offset - + vsp->col, vsp->Scrollback + + ((vsp->scr_offset + 1) * + vsp->maxcol), vsp->maxcol * CHR); + } + + if (vsp->cursor_on) + sw_cursor(0); + } + + vsp->scrolling += vsp->screen_rows - 1; + if (vsp->scrolling > vsp->scr_offset) + vsp->scrolling = vsp->scr_offset; + + bcopy(vsp->Scrollback + ((vsp->scr_offset - + vsp->scrolling) * vsp->maxcol), vsp->Crtat, + vsp->screen_rows * vsp->maxcol * CHR); + } + + kbd_lastkey = 85; + goto loop; + } + else if ((key == 86) && shift_down && kbd_lastkey != 86) + { +scroll_reset: + if (vsp->scrolling > 0) + { + vsp->scrolling -= vsp->screen_rows - 1; + if (vsp->scrolling < 0) + vsp->scrolling = 0; + + if (vsp->scrolling <= vsp->screen_rows) + { + vsp->scrolling = 0; + scrollback_restore_screen(); + } + else + { + bcopy(vsp->Scrollback + ((vsp->scr_offset - + vsp->scrolling) * vsp->maxcol), + vsp->Crtat, vsp->screen_rows * + vsp->maxcol * CHR); + } + } + + if (vsp->scrolling == 0) + { + if (vsp->cursor_on) + { + sw_cursor(1); + } + } + + if (noblock == 31337) + return NULL; + + if (key != 86) + goto regular; + else + { + kbd_lastkey = 86; + goto loop; + } + } + else if (vsp->scrolling && key != 128 && key != 44 && key != 85 && + key != 86) + { + vsp->scrolling = 1; + goto scroll_reset; + } +#endif + if(kbd_reset && (key == 76) && ctrl_down && (meta_down||altgr_down)) { printf("\nconsole halt requested: going down.\n"); kbd_reset = 0; @@ -3043,4 +3149,35 @@ cfkey12(void) #endif /* NVT > 0 */ +#ifdef PCVT_SCROLLBACK +static void +scrollback_save_screen(void) +{ + int x = spltty(); + register size_t s; + + s = sizeof(u_short) * vsp->screen_rowsize * vsp->maxcol; + + if (scrollback_savedscreen) + free(scrollback_savedscreen, M_TEMP); + + scrnsv_size = s; + + if (!(scrollback_savedscreen = (u_short *)malloc(s, M_TEMP, M_NOWAIT))) + { + splx(x); + return; + } + bcopy(vsp->Crtat, scrollback_savedscreen, scrnsv_size); + splx(x); +} + +static void +scrollback_restore_screen(void) +{ + if (scrollback_savedscreen) + bcopy(scrollback_savedscreen, vsp->Crtat, scrnsv_size); +} +#endif + /* ------------------------------- EOF -------------------------------------*/ diff --git a/sys/arch/i386/isa/pcvt/pcvt_out.c b/sys/arch/i386/isa/pcvt/pcvt_out.c index e6e9d232d20..734e19f2426 100644 --- a/sys/arch/i386/isa/pcvt/pcvt_out.c +++ b/sys/arch/i386/isa/pcvt/pcvt_out.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcvt_out.c,v 1.7 1999/01/13 07:26:02 niklas Exp $ */ +/* $OpenBSD: pcvt_out.c,v 1.8 1999/09/06 00:12:40 aaron Exp $ */ /* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. @@ -80,6 +80,9 @@ static void wrfkl ( int num, u_char *string, struct video_state *svsp ); static void writefkl ( int num, u_char *string, struct video_state *svsp ); static __inline void write_char (struct video_state *, u_short, u_short ch); +#ifdef PCVT_SCROLLBACK +static int check_scrollback ( struct video_state *svsp ); +#endif /*---------------------------------------------------------------------------* * do character set transformation and write to display memory (inline) @@ -147,6 +150,9 @@ void sput (u_char *s, U_char kernel, int len, int page) { register struct video_state *svsp; +#ifdef PCVT_SCROLLBACK + int extra; +#endif u_short attrib; u_short ch; @@ -269,6 +275,20 @@ sput (u_char *s, U_char kernel, int len, int page) case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ +#ifdef PCVT_SCROLLBACK + if (check_scrollback(svsp)) + { + extra = (svsp->cur_offset % + svsp->maxcol) ? + svsp->col : 0; + bcopy(svsp->Crtat + + svsp->cur_offset - extra, + svsp->Scrollback + + (svsp->scr_offset * + svsp->maxcol), + svsp->maxcol * CHR); + } +#endif if(svsp->lnm) { svsp->cur_offset -= svsp->col; @@ -421,6 +441,18 @@ sput (u_char *s, U_char kernel, int len, int page) svsp->cur_offset++; svsp->col = 0; svsp->lastchar = 0; +#ifdef PCVT_SCROLLBACK + if (check_scrollback(svsp)) + { + bcopy(svsp->Crtat + + svsp->cur_offset - + svsp->maxcol, + svsp->Scrollback + + (svsp->scr_offset * + svsp->maxcol), + svsp->maxcol * CHR); + } +#endif check_scroll(svsp); } @@ -813,6 +845,11 @@ sput (u_char *s, U_char kernel, int len, int page) case 'K': /* erase line */ vt_clreol(svsp); svsp->state = STATE_INIT; +#ifdef PCVT_SCROLLBACK + if (svsp->scr_offset > 0 && + svsp == vsp) + svsp->scr_offset--; +#endif break; case 'L': /* insert line */ @@ -1094,6 +1131,11 @@ vt_coldinit(void) { svsp->Crtat = Crtat; /* all same until malloc'ed */ svsp->Memory = Crtat; /* until malloc'ed */ +#ifdef PCVT_SCROLLBACK + svsp->Scrollback = 0; /* until malloc'ed */ + svsp->scr_offset = 0; /* scrollback offset (lines) */ + svsp->scrolling = 0; /* current scrollback page */ +#endif svsp->cur_offset = 0; /* cursor offset */ svsp->c_attr = user_attr; /* non-kernel attributes */ svsp->bell_on = 1; /* enable bell */ @@ -1128,6 +1170,9 @@ vt_coldinit(void) #endif /* PCVT_24LINESDEF */ svsp->screen_rowsize = 25; /* default 25 rows on screen */ +#ifdef PCVT_SCROLLBACK + svsp->max_off = svsp->screen_rowsize * SCROLLBACK_PAGES - 1; +#endif svsp->scrr_beg = 0; /* scrolling region begin row*/ svsp->scrr_len = svsp->screen_rows; /* scrolling region length*/ svsp->scrr_end = svsp->scrr_len - 1;/* scrolling region end */ @@ -1361,6 +1406,15 @@ vt_coldmalloc(void) MAXROW_VGA * MAXCOL_VGA * CHR; } +#ifdef PCVT_SCROLLBACK + if ((Scrollbuffer = (u_short *)malloc(vs[0].maxcol * + vs[0].screen_rowsize * SCROLLBACK_PAGES * CHR * 2, M_DEVBUF, + M_WAITOK)) == NULL) + { + printf("pcvt: scrollback memory malloc failed\n"); + } +#endif + for(nscr = 0; nscr < PCVT_NSCREENS; nscr++) { if((vs[nscr].Memory = @@ -1372,6 +1426,9 @@ vt_coldmalloc(void) PCVT_NSCREENS, nscr); break; } +#ifdef PCVT_SCROLLBACK + vs[nscr].Scrollback = Scrollbuffer; +#endif if(nscr != 0) { vs[nscr].Crtat = vs[nscr].Memory; @@ -1423,6 +1480,29 @@ check_scroll(struct video_state *svsp) } } +#ifdef PCVT_SCROLLBACK +static int +check_scrollback(struct video_state *svsp) +{ + /* still waiting for scrollback memory or not on current page */ + if (!svsp->Scrollback || svsp != vsp) + return 0; + + /* remove first line of scrollback buffer to make room for new line */ + if (svsp->scr_offset == svsp->max_off) + { + bcopy(svsp->Scrollback + svsp->maxcol, svsp->Scrollback, + svsp->maxcol * svsp->max_off * CHR); + } + else + { + /* still room left, increase scroll offset (lines) */ + svsp->scr_offset++; + } + return 1; +} +#endif + /*---------------------------------------------------------------------------* * write to one user function key label *---------------------------------------------------------------------------*/ @@ -1877,8 +1957,8 @@ vt_col(struct video_state *svsp, int cols) clr_parms(svsp); /* escape parameter init */ svsp->state = STATE_INIT; /* initial state */ - svsp->col = 0; /* init row */ - svsp->row = 0; /* init col */ + svsp->col = 0; /* init col */ + svsp->row = 0; /* init row */ svsp->cur_offset = 0; /* cursor offset init */ svsp->sc_flag = 0; /* invalidate saved cursor position */ svsp->scrr_beg = 0; /* reset scrolling region */ |