summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Stein <jcs@cvs.openbsd.org>2018-04-27 21:36:13 +0000
committerJoshua Stein <jcs@cvs.openbsd.org>2018-04-27 21:36:13 +0000
commitd8f64152dfaaddf25de9dca020b84c322b874855 (patch)
treedd5c53d4a83bef65dabf710495532dca0aec1bbc
parenta0d21cd0e540e643e7252beb7186922fdb28785e (diff)
rasops: implement scrollback
activate it for efifb and inteldrm ok kettenis
-rw-r--r--sys/arch/amd64/amd64/efifb.c15
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.c11
-rw-r--r--sys/dev/rasops/rasops.c101
-rw-r--r--sys/dev/rasops/rasops.h3
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];