summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-09-07 18:00:59 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-09-07 18:00:59 +0000
commit6dcaf406932d2f53fd6b1b7fdf7f623e576aa5eb (patch)
treedf4e44d987ba491d1222095bde0382951a694637
parente0cf59e2af5be922cb257040e6f910c6bb89c58f (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.c124
-rw-r--r--sys/dev/rasops/rasops.h3
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 */