diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-07 18:00:59 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-07 18:00:59 +0000 |
commit | 6dcaf406932d2f53fd6b1b7fdf7f623e576aa5eb (patch) | |
tree | df4e44d987ba491d1222095bde0382951a694637 | |
parent | e0cf59e2af5be922cb257040e6f910c6bb89c58f (diff) |
Make it possible to use RI_WRONLY for the aframebuffer during early boot.
In this case, the caller has to provide the backing store for the screen
contents by setting the ri_bs member of "struct rasops_info". The screen
contents are retained if the rasops_info descriptor is later reinitialized
after adding the RI_VCONS flag.
ok yasuoka@, deraadt@
-rw-r--r-- | sys/dev/rasops/rasops.c | 124 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.h | 3 |
2 files changed, 120 insertions, 7 deletions
diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c index bce7416e78f..8abe9c0f3f3 100644 --- a/sys/dev/rasops/rasops.c +++ b/sys/dev/rasops/rasops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops.c,v 1.41 2015/09/01 01:54:04 deraadt Exp $ */ +/* $OpenBSD: rasops.c,v 1.42 2015/09/07 18:00:58 kettenis Exp $ */ /* $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $ */ /*- @@ -174,6 +174,12 @@ int rasops_vcons_eraserows(void *, int, int, long); int rasops_vcons_alloc_attr(void *, int, int, int, long *); void rasops_vcons_unpack_attr(void *, long, int *, int *, int *); +int rasops_wronly_putchar(void *, int, int, u_int, long); +int rasops_wronly_copycols(void *, int, int, int, int); +int rasops_wronly_erasecols(void *, int, int, int, long); +int rasops_wronly_copyrows(void *, int, int, int); +int rasops_wronly_eraserows(void *, int, int, long); + int rasops_add_font(struct rasops_info *, struct wsdisplay_font *); int rasops_use_font(struct rasops_info *, struct wsdisplay_font *); int rasops_list_font_cb(void *, struct wsdisplay_font *); @@ -271,6 +277,21 @@ rasops_init(struct rasops_info *ri, int wantrows, int wantcols) ri->ri_ops.eraserows = rasops_vcons_eraserows; ri->ri_ops.alloc_attr = rasops_vcons_alloc_attr; ri->ri_ops.unpack_attr = rasops_vcons_unpack_attr; + } else if ((ri->ri_flg & RI_WRONLY) && ri->ri_bs != NULL) { + long attr; + int i; + + ri->ri_ops.putchar = rasops_wronly_putchar; + ri->ri_ops.copycols = rasops_wronly_copycols; + ri->ri_ops.erasecols = rasops_wronly_erasecols; + ri->ri_ops.copyrows = rasops_wronly_copyrows; + ri->ri_ops.eraserows = rasops_wronly_eraserows; + + ri->ri_alloc_attr(ri, 0, 0, 0, &attr); + for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { + ri->ri_bs[i].uc = ' '; + ri->ri_bs[i].attr = attr; + } } task_set(&ri->ri_switchtask, rasops_doswitch, ri); @@ -1368,7 +1389,6 @@ rasops_alloc_screen(void *v, void **cookiep, { struct rasops_info *ri = v; struct rasops_screen *scr; - size_t size; int i; scr = malloc(sizeof(*scr), M_DEVBUF, M_NOWAIT); @@ -1382,7 +1402,6 @@ rasops_alloc_screen(void *v, void **cookiep, free(scr, M_DEVBUF, sizeof(*scr)); return (ENOMEM); } - size = ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell); *cookiep = scr; *curxp = 0; @@ -1394,9 +1413,14 @@ rasops_alloc_screen(void *v, void **cookiep, scr->rs_crow = -1; scr->rs_ccol = -1; - for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { - scr->rs_bs[i].uc = ' '; - scr->rs_bs[i].attr = *attrp; + if (ri->ri_bs) { + memcpy(scr->rs_bs, 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; + } } LIST_INSERT_HEAD(&ri->ri_screens, scr, rs_next); @@ -1629,6 +1653,94 @@ rasops_vcons_unpack_attr(void *cookie, long attr, int *fg, int *bg, rasops_unpack_attr(scr->rs_ri, attr, fg, bg, underline); } +int +rasops_wronly_putchar(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = cookie; + int off = row * ri->ri_cols + col; + + ri->ri_bs[off].uc = uc; + ri->ri_bs[off].attr = attr; + + return ri->ri_putchar(ri, row, col, uc, attr); +} + +int +rasops_wronly_copycols(void *cookie, int row, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + int cols = ri->ri_cols; + int col, rc; + + memmove(&ri->ri_bs[row * cols + dst], &ri->ri_bs[row * cols + src], + num * sizeof(struct wsdisplay_charcell)); + + for (col = dst; col < dst + num; col++) { + int off = row * cols + col; + + rc = ri->ri_putchar(ri, row, col, + ri->ri_bs[off].uc, ri->ri_bs[off].attr); + if (rc != 0) + return rc; + } + + return 0; +} + +int +rasops_wronly_erasecols(void *cookie, int row, int col, int num, long attr) +{ + struct rasops_info *ri = cookie; + int cols = ri->ri_cols; + int i; + + for (i = 0; i < num; i++) { + ri->ri_bs[row * cols + col + i].uc = ' '; + ri->ri_bs[row * cols + col + i].attr = attr; + } + + return ri->ri_erasecols(ri, row, col, num, attr); +} + +int +rasops_wronly_copyrows(void *cookie, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + int cols = ri->ri_cols; + int row, col, rc; + + memmove(&ri->ri_bs[dst * cols], &ri->ri_bs[src * cols], + num * cols * sizeof(struct wsdisplay_charcell)); + + for (row = dst; row < dst + num; row++) { + for (col = 0; col < cols; col++) { + int off = row * cols + col; + + rc = ri->ri_putchar(ri, row, col, + ri->ri_bs[off].uc, ri->ri_bs[off].attr); + if (rc != 0) + return rc; + } + } + + return 0; +} + +int +rasops_wronly_eraserows(void *cookie, int row, int num, long attr) +{ + struct rasops_info *ri = cookie; + int cols = ri->ri_cols; + int i; + + for (i = 0; i < num * cols; i++) { + ri->ri_bs[row * cols + i].uc = ' '; + ri->ri_bs[row * cols + i].attr = attr; + } + + return ri->ri_eraserows(ri, row, num, attr); +} + /* * Font management. * diff --git a/sys/dev/rasops/rasops.h b/sys/dev/rasops/rasops.h index 31bbb577240..60d386fb254 100644 --- a/sys/dev/rasops/rasops.h +++ b/sys/dev/rasops/rasops.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rasops.h,v 1.16 2014/12/22 20:08:05 krw Exp $ */ +/* $OpenBSD: rasops.h,v 1.17 2015/09/07 18:00:58 kettenis Exp $ */ /* $NetBSD: rasops.h,v 1.13 2000/06/13 13:36:54 ad Exp $ */ /*- @@ -74,6 +74,7 @@ struct rasops_info { struct wsdisplay_font *ri_font; int ri_wsfcookie; /* wsfont cookie */ void *ri_hw; /* driver private data; ignored by rasops */ + struct wsdisplay_charcell *ri_bs; /* character backing store */ int ri_crow; /* cursor row */ int ri_ccol; /* cursor column */ int ri_flg; /* various operational flags */ |