diff options
author | Joshua Stein <jcs@cvs.openbsd.org> | 2018-04-27 21:36:13 +0000 |
---|---|---|
committer | Joshua Stein <jcs@cvs.openbsd.org> | 2018-04-27 21:36:13 +0000 |
commit | d8f64152dfaaddf25de9dca020b84c322b874855 (patch) | |
tree | dd5c53d4a83bef65dabf710495532dca0aec1bbc | |
parent | a0d21cd0e540e643e7252beb7186922fdb28785e (diff) |
rasops: implement scrollback
activate it for efifb and inteldrm
ok kettenis
-rw-r--r-- | sys/arch/amd64/amd64/efifb.c | 15 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 11 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.c | 101 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.h | 3 |
4 files changed, 111 insertions, 19 deletions
diff --git a/sys/arch/amd64/amd64/efifb.c b/sys/arch/amd64/amd64/efifb.c index 0343f18445b..e3dc22abfe2 100644 --- a/sys/arch/amd64/amd64/efifb.c +++ b/sys/arch/amd64/amd64/efifb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efifb.c,v 1.15 2018/04/25 00:46:28 jsg Exp $ */ +/* $OpenBSD: efifb.c,v 1.16 2018/04/27 21:36:12 jcs Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -101,6 +101,7 @@ int efifb_show_screen(void *, void *, int, void (*cb) (void *, int, int), void *); int efifb_list_font(void *, struct wsdisplay_font *); int efifb_load_font(void *, void *, struct wsdisplay_font *); +void efifb_scrollback(void *, void *, int lines); void efifb_efiinfo_init(struct efifb *); void efifb_cnattach_common(void); @@ -133,7 +134,8 @@ struct wsdisplay_accessops efifb_accessops = { .free_screen = efifb_free_screen, .show_screen = efifb_show_screen, .load_font = efifb_load_font, - .list_font = efifb_list_font + .list_font = efifb_list_font, + .scrollback = efifb_scrollback, }; struct cfdriver efifb_cd = { @@ -399,6 +401,15 @@ efifb_list_font(void *v, struct wsdisplay_font *font) return (rasops_list_font(ri, font)); } +void +efifb_scrollback(void *v, void *cookie, int lines) +{ + struct efifb_softc *sc = v; + struct rasops_info *ri = &sc->sc_fb->rinfo; + + rasops_scrollback(ri, cookie, lines); +} + int efifb_cnattach(void) { diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index aa3361110a1..f71019c4ee1 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -1925,6 +1925,7 @@ int inteldrm_list_font(void *, struct wsdisplay_font *); int inteldrm_getchar(void *, int, int, struct wsdisplay_charcell *); void inteldrm_burner(void *, u_int, u_int); void inteldrm_burner_cb(void *); +void inteldrm_scrollback(void *, void *, int lines); struct wsscreen_descr inteldrm_stdscreen = { "std", @@ -1953,6 +1954,7 @@ struct wsdisplay_accessops inteldrm_accessops = { .getchar = inteldrm_getchar, .load_font = inteldrm_load_font, .list_font = inteldrm_list_font, + .scrollback = inteldrm_scrollback, .burn_screen = inteldrm_burner }; @@ -2174,6 +2176,15 @@ const struct backlight_ops inteldrm_backlight_ops = { .get_brightness = inteldrm_backlight_get_brightness }; +void +inteldrm_scrollback(void *v, void *cookie, int lines) +{ + struct inteldrm_softc *dev_priv = v; + struct rasops_info *ri = &dev_priv->ro; + + rasops_scrollback(ri, cookie, lines); +} + int inteldrm_match(struct device *, void *, void *); void inteldrm_attach(struct device *, struct device *, void *); int inteldrm_detach(struct device *, int); diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c index 138db2ebc82..2005e0a10f1 100644 --- a/sys/dev/rasops/rasops.c +++ b/sys/dev/rasops/rasops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops.c,v 1.52 2018/04/20 16:09:37 deraadt Exp $ */ +/* $OpenBSD: rasops.c,v 1.53 2018/04/27 21:36:12 jcs Exp $ */ /* $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $ */ /*- @@ -1373,6 +1373,11 @@ struct rasops_screen { int rs_visible; int rs_crow; int rs_ccol; + + int rs_sbscreens; +#define RS_SCROLLBACK_SCREENS 5 + int rs_dispoffset; /* rs_bs index, start of our actual screen */ + int rs_visibleoffset; /* rs_bs index, current scrollback screen */ }; int @@ -1387,13 +1392,16 @@ rasops_alloc_screen(void *v, void **cookiep, if (scr == NULL) return (ENOMEM); - scr->rs_bs = mallocarray(ri->ri_rows, + scr->rs_sbscreens = RS_SCROLLBACK_SCREENS; + scr->rs_bs = mallocarray(ri->ri_rows * (scr->rs_sbscreens + 1), ri->ri_cols * sizeof(struct wsdisplay_charcell), M_DEVBUF, M_NOWAIT); if (scr->rs_bs == NULL) { free(scr, M_DEVBUF, sizeof(*scr)); return (ENOMEM); } + scr->rs_visibleoffset = scr->rs_dispoffset = ri->ri_rows * + scr->rs_sbscreens * ri->ri_cols; *cookiep = scr; *curxp = 0; @@ -1405,13 +1413,19 @@ rasops_alloc_screen(void *v, void **cookiep, scr->rs_crow = -1; scr->rs_ccol = -1; + for (i = 0; i < scr->rs_dispoffset; i++) { + scr->rs_bs[i].uc = ' '; + scr->rs_bs[i].attr = *attrp; + } + if (ri->ri_bs && scr->rs_visible) { - memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols * + memcpy(scr->rs_bs + scr->rs_dispoffset, ri->ri_bs, + ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); } else { for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { - scr->rs_bs[i].uc = ' '; - scr->rs_bs[i].attr = *attrp; + scr->rs_bs[scr->rs_dispoffset + i].uc = ' '; + scr->rs_bs[scr->rs_dispoffset + i].attr = *attrp; } } @@ -1431,7 +1445,8 @@ rasops_free_screen(void *v, void *cookie) ri->ri_nscreens--; free(scr->rs_bs, M_DEVBUF, - ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); + ri->ri_rows * (scr->rs_sbscreens + 1) * ri->ri_cols * + sizeof(struct wsdisplay_charcell)); free(scr, M_DEVBUF, sizeof(*scr)); } @@ -1467,9 +1482,11 @@ rasops_doswitch(void *v) ri->ri_eraserows(ri, 0, ri->ri_rows, attr); ri->ri_active = scr; ri->ri_active->rs_visible = 1; + ri->ri_active->rs_visibleoffset = ri->ri_active->rs_dispoffset; for (row = 0; row < ri->ri_rows; row++) { for (col = 0; col < ri->ri_cols; col++) { - int off = row * scr->rs_ri->ri_cols + col; + int off = row * scr->rs_ri->ri_cols + col + + scr->rs_visibleoffset; ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc, scr->rs_bs[off].attr); @@ -1491,7 +1508,7 @@ rasops_getchar(void *v, int row, int col, struct wsdisplay_charcell *cell) if (scr == NULL || scr->rs_bs == NULL) return (1); - *cell = scr->rs_bs[row * ri->ri_cols + col]; + *cell = scr->rs_bs[row * ri->ri_cols + col + scr->rs_dispoffset]; return (0); } @@ -1521,7 +1538,10 @@ int rasops_vcons_putchar(void *cookie, int row, int col, u_int uc, long attr) { struct rasops_screen *scr = cookie; - int off = row * scr->rs_ri->ri_cols + col; + int off = row * scr->rs_ri->ri_cols + col + scr->rs_dispoffset; + + if (scr->rs_visible && scr->rs_visibleoffset != scr->rs_dispoffset) + rasops_scrollback(scr->rs_ri, scr, 0); scr->rs_bs[off].uc = uc; scr->rs_bs[off].attr = attr; @@ -1540,7 +1560,8 @@ rasops_vcons_copycols(void *cookie, int row, int src, int dst, int num) int cols = scr->rs_ri->ri_cols; int col, rc; - memmove(&scr->rs_bs[row * cols + dst], &scr->rs_bs[row * cols + src], + memmove(&scr->rs_bs[row * cols + dst + scr->rs_dispoffset], + &scr->rs_bs[row * cols + src + scr->rs_dispoffset], num * sizeof(struct wsdisplay_charcell)); if (!scr->rs_visible) @@ -1550,7 +1571,7 @@ rasops_vcons_copycols(void *cookie, int row, int src, int dst, int num) return ri->ri_copycols(ri, row, src, dst, num); for (col = dst; col < dst + num; col++) { - int off = row * cols + col; + int off = row * cols + col + scr->rs_dispoffset; rc = ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc, scr->rs_bs[off].attr); @@ -1569,7 +1590,7 @@ rasops_vcons_erasecols(void *cookie, int row, int col, int num, long attr) int i; for (i = 0; i < num; i++) { - int off = row * cols + col + i; + int off = row * cols + col + i + scr->rs_dispoffset; scr->rs_bs[off].uc = ' '; scr->rs_bs[off].attr = attr; @@ -1589,8 +1610,14 @@ rasops_vcons_copyrows(void *cookie, int src, int dst, int num) int cols = ri->ri_cols; int row, col, rc; - memmove(&scr->rs_bs[dst * cols], &scr->rs_bs[src * cols], - num * cols * sizeof(struct wsdisplay_charcell)); + if (dst == 0 && (src + num == ri->ri_rows) && scr->rs_sbscreens > 0) + memmove(&scr->rs_bs[dst], &scr->rs_bs[src * cols], + ((ri->ri_rows * (scr->rs_sbscreens + 1) * cols) - + (src * cols)) * sizeof(struct wsdisplay_charcell)); + else + memmove(&scr->rs_bs[dst * cols + scr->rs_dispoffset], + &scr->rs_bs[src * cols + scr->rs_dispoffset], + num * cols * sizeof(struct wsdisplay_charcell)); if (!scr->rs_visible) return 0; @@ -1600,7 +1627,7 @@ rasops_vcons_copyrows(void *cookie, int src, int dst, int num) for (row = dst; row < dst + num; row++) { for (col = 0; col < cols; col++) { - int off = row * cols + col; + int off = row * cols + col + scr->rs_dispoffset; rc = ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc, scr->rs_bs[off].attr); @@ -1620,7 +1647,7 @@ rasops_vcons_eraserows(void *cookie, int row, int num, long attr) int i; for (i = 0; i < num * cols; i++) { - int off = row * cols + i; + int off = row * cols + i + scr->rs_dispoffset; scr->rs_bs[off].uc = ' '; scr->rs_bs[off].attr = attr; @@ -1872,3 +1899,45 @@ rasops_list_font(void *v, struct wsdisplay_font *font) font->cookie = font->data = NULL; /* don't leak kernel pointers */ return 0; } + +void +rasops_scrollback(void *v, void *cookie, int lines) +{ + struct rasops_info *ri = v; + struct rasops_screen *scr = cookie; + int row, col, oldvoff; + long attr; + + oldvoff = scr->rs_visibleoffset; + + if (lines == 0) + scr->rs_visibleoffset = scr->rs_dispoffset; + else { + int off = scr->rs_visibleoffset + (lines * ri->ri_cols); + + if (off < 0) + off = 0; + else if (off > scr->rs_dispoffset) + off = scr->rs_dispoffset; + + scr->rs_visibleoffset = off; + } + + if (scr->rs_visibleoffset == oldvoff) + return; + + rasops_cursor(ri, 0, 0, 0); + ri->ri_eraserows(ri, 0, ri->ri_rows, attr); + for (row = 0; row < ri->ri_rows; row++) { + for (col = 0; col < ri->ri_cols; col++) { + int off = row * scr->rs_ri->ri_cols + col + + scr->rs_visibleoffset; + + ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc, + scr->rs_bs[off].attr); + } + } + + if (scr->rs_crow != -1 && scr->rs_visibleoffset == scr->rs_dispoffset) + rasops_cursor(ri, 1, scr->rs_crow, scr->rs_ccol); +} diff --git a/sys/dev/rasops/rasops.h b/sys/dev/rasops/rasops.h index 015e46bfcd7..bab120e5309 100644 --- a/sys/dev/rasops/rasops.h +++ b/sys/dev/rasops/rasops.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops.h,v 1.21 2018/04/20 16:09:37 deraadt Exp $ */ +/* $OpenBSD: rasops.h,v 1.22 2018/04/27 21:36:12 jcs Exp $ */ /* $NetBSD: rasops.h,v 1.13 2000/06/13 13:36:54 ad Exp $ */ /*- @@ -178,6 +178,7 @@ int rasops_show_screen(void *, void *, int, int rasops_load_font(void *, void *, struct wsdisplay_font *); int rasops_list_font(void *, struct wsdisplay_font *); int rasops_getchar(void *, int, int, struct wsdisplay_charcell *); +void rasops_scrollback(void *, void *, int); extern const u_char rasops_isgray[16]; extern const u_char rasops_cmap[256*3]; |