diff options
Diffstat (limited to 'sys/dev/wscons/wsemul_sun.c')
-rw-r--r-- | sys/dev/wscons/wsemul_sun.c | 82 |
1 files changed, 70 insertions, 12 deletions
diff --git a/sys/dev/wscons/wsemul_sun.c b/sys/dev/wscons/wsemul_sun.c index 6e56fbf7087..944e934dae6 100644 --- a/sys/dev/wscons/wsemul_sun.c +++ b/sys/dev/wscons/wsemul_sun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsemul_sun.c,v 1.16 2006/07/01 16:16:53 miod Exp $ */ +/* $OpenBSD: wsemul_sun.c,v 1.17 2006/08/17 06:27:04 miod Exp $ */ /* $NetBSD: wsemul_sun.c,v 1.11 2000/01/05 11:19:36 drochner Exp $ */ /* @@ -38,7 +38,9 @@ * Color support from NetBSD's rcons color code, and wsemul_vt100. */ -#include <sys/cdefs.h> +#ifndef SMALL_KERNEL +#define JUMP_SCROLL +#endif #include <sys/param.h> #include <sys/systm.h> @@ -109,7 +111,7 @@ u_int wsemul_sun_output_control(struct wsemul_sun_emuldata *, u_char); void wsemul_sun_control(struct wsemul_sun_emuldata *, u_char); int wsemul_sun_selectattribute(struct wsemul_sun_emuldata *, int, int, int, long *, long *); -void wsemul_sun_scrollup(struct wsemul_sun_emuldata *); +void wsemul_sun_scrollup(struct wsemul_sun_emuldata *, u_int); struct wsemul_sun_emuldata wsemul_sun_console_emuldata; @@ -291,7 +293,7 @@ wsemul_sun_output_lowchars(edp, c, kernel) if (ROWS_LEFT > 0) edp->crow++; else - wsemul_sun_scrollup(edp); + wsemul_sun_scrollup(edp, edp->scrolldist); break; } } @@ -311,7 +313,7 @@ wsemul_sun_output_normal(edp, c, kernel) if (ROWS_LEFT > 0) edp->crow++; else - wsemul_sun_scrollup(edp); + wsemul_sun_scrollup(edp, edp->scrolldist); edp->ccol = 0; } } @@ -577,6 +579,11 @@ wsemul_sun_output(cookie, data, count, kernel) { struct wsemul_sun_emuldata *edp = cookie; u_int newstate; +#ifdef JUMP_SCROLL + const u_char *eot; + u_char curchar; + u_int cnt, pos, lines; +#endif #ifdef DIAGNOSTIC if (kernel && !edp->console) @@ -585,7 +592,57 @@ wsemul_sun_output(cookie, data, count, kernel) /* XXX */ (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); + for (; count > 0; data++, count--) { +#ifdef JUMP_SCROLL + /* + * If scrolling is not disabled and we are the bottom of + * the screen, count newlines until an escape sequence + * appears. + */ + if ((edp->state == SUN_EMUL_STATE_NORMAL || kernel) && + ROWS_LEFT == 0 && edp->scrolldist != 0) { + lines = 0; + pos = edp->ccol; + for (eot = data, cnt = count; cnt != 0; eot++, cnt--) { + curchar = *eot; + if (curchar == ASCII_FF || + curchar == ASCII_VT || curchar == ASCII_ESC) + break; + + switch (curchar) { + case ASCII_BS: + if (pos > 0) + pos--; + break; + case ASCII_CR: + pos = 0; + break; + case ASCII_HT: + pos = (pos + 7) & ~7; + if (pos >= edp->ncols) + pos = edp->ncols - 1; + break; + default: + if (++pos >= edp->ncols) { + pos = 0; + curchar = ASCII_LF; + } + break; + } + if (curchar == ASCII_LF) { + if (++lines >= edp->nrows - 1) + break; + } + } + + if (lines > 1) { + wsemul_sun_scrollup(edp, lines); + edp->crow--; + } + } +#endif + if (*data < ' ') { wsemul_sun_output_lowchars(edp, *data, kernel); continue; @@ -833,14 +890,15 @@ wsemul_sun_resetop(cookie, op) } void -wsemul_sun_scrollup(edp) +wsemul_sun_scrollup(edp, lines) struct wsemul_sun_emuldata *edp; + u_int lines; { /* * if we're in wrap-around mode, go to the first * line and clear it. */ - if (edp->scrolldist == 0) { + if (lines == 0) { edp->crow = 0; (*edp->emulops->eraserows)(edp->emulcookie, 0, 1, edp->bkgdattr); @@ -852,10 +910,10 @@ wsemul_sun_scrollup(edp) * (usually 34), clear the screen; otherwise, scroll by the * scrolling distance. */ - if (edp->scrolldist < edp->nrows) - (*edp->emulops->copyrows)(edp->emulcookie, edp->scrolldist, 0, - edp->nrows - edp->scrolldist); + if (lines < edp->nrows) + (*edp->emulops->copyrows)(edp->emulcookie, lines, 0, + edp->nrows - lines); (*edp->emulops->eraserows)(edp->emulcookie, - edp->nrows - edp->scrolldist, edp->scrolldist, edp->bkgdattr); - edp->crow -= edp->scrolldist - 1; + edp->nrows - lines, lines, edp->bkgdattr); + edp->crow -= lines - 1; } |