Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/wscons add support for loading fonts in vcons and su...



details:   https://anonhg.NetBSD.org/src/rev/26eb9148c4f6
branches:  trunk
changeset: 824040:26eb9148c4f6
user:      macallan <macallan%NetBSD.org@localhost>
date:      Fri May 19 19:22:33 2017 +0000

description:
add support for loading fonts in vcons and subsequently resizing screens
- drivers can use this by setting VCONS_LOADFONT and WSSCREEN_RESIZE
- each vcons screen can now have its own font and geometry
- while there, add support for xterm's ESC[18t to report the text buffer's
  size

With this tou can:
wsfontload -N foo  /usr/share/wscons/fonts/flori.816
wsconsctl -dw font=foo
currently this is limited to drivers that don't use the glyph cache, like genfb

diffstat:

 sys/dev/wscons/files.wscons         |    4 +-
 sys/dev/wscons/wsdisplay.c          |   51 ++++++-
 sys/dev/wscons/wsdisplay_vcons.c    |  251 ++++++++++++++++++++++++++---------
 sys/dev/wscons/wsdisplay_vconsvar.h |    8 +-
 sys/dev/wscons/wsdisplayvar.h       |    5 +-
 sys/dev/wscons/wsemul_dumb.c        |    5 +-
 sys/dev/wscons/wsemul_sun.c         |    5 +-
 sys/dev/wscons/wsemul_vt100.c       |   21 ++-
 sys/dev/wscons/wsemul_vt100_subr.c  |   16 ++-
 sys/dev/wscons/wsemulvar.h          |    3 +-
 10 files changed, 280 insertions(+), 89 deletions(-)

diffs (truncated from 820 to 300 lines):

diff -r 4fcc87500d03 -r 26eb9148c4f6 sys/dev/wscons/files.wscons
--- a/sys/dev/wscons/files.wscons       Fri May 19 16:56:35 2017 +0000
+++ b/sys/dev/wscons/files.wscons       Fri May 19 19:22:33 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.49 2014/10/17 10:09:21 uebayasi Exp $
+# $NetBSD: files.wscons,v 1.50 2017/05/19 19:22:33 macallan Exp $
 
 #
 # "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -76,7 +76,7 @@
 # generic virtual console support on bitmapped framebuffers
 file   dev/wscons/wsdisplay_vcons.c            vcons
 file   dev/wscons/wsdisplay_vcons_util.c       vcons
-defflag        opt_vcons.h             VCONS_DRAW_INTR VCONS_INTR_DEBUG
+defflag        opt_vcons.h             VCONS_DRAW_INTR VCONS_INTR_DEBUG VCONS_DEBUG
 
 # generic support code for caching rendered glyphs in video memory
 define glyphcache
diff -r 4fcc87500d03 -r 26eb9148c4f6 sys/dev/wscons/wsdisplay.c
--- a/sys/dev/wscons/wsdisplay.c        Fri May 19 16:56:35 2017 +0000
+++ b/sys/dev/wscons/wsdisplay.c        Fri May 19 19:22:33 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wsdisplay.c,v 1.141 2017/01/25 15:40:31 jakllsch Exp $ */
+/* $NetBSD: wsdisplay.c,v 1.142 2017/05/19 19:22:33 macallan Exp $ */
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.141 2017/01/25 15:40:31 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay.c,v 1.142 2017/05/19 19:22:33 macallan Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_wsdisplay_compat.h"
@@ -257,6 +257,9 @@
 static int wsdisplay_switch3(device_t, int, int);
 static void wsdisplay_switch3_cb(void *, int, int);
 
+static void wsdisplay_swdone_cb(void *, int, int);
+static int wsdisplay_dosync(struct wsdisplay_softc *, int);
+
 int wsdisplay_clearonclose;
 
 struct wsscreen *
@@ -331,6 +334,8 @@
                                                  &ccol, &crow);
                wsemul_drop(scr->scr_dconf->wsemul);
        }
+       if (scr->scr_dconf->scrdata->capabilities & WSSCREEN_FREE)
+               free(__UNCONST(scr->scr_dconf->scrdata), M_DEVBUF);
        free(scr->scr_dconf, M_DEVBUF);
        free(scr, M_DEVBUF);
 }
@@ -342,7 +347,6 @@
        const struct wsscreen_descr *scr;
 
        KASSERT(scrdata->nscreens > 0);
-
        if (name == NULL)
                return (scrdata->screens[0]);
 
@@ -377,6 +381,7 @@
        const char *screentype, const char *emul)
 {
        const struct wsscreen_descr *scrdesc;
+       struct wsscreen_descr *scrdescr2;
        int error;
        void *cookie;
        int ccol, crow;
@@ -388,10 +393,24 @@
                return (EINVAL);
        if (sc->sc_scr[idx] != NULL)
                return (EBUSY);
-
        scrdesc = wsdisplay_screentype_pick(sc->sc_scrdata, screentype);
        if (!scrdesc)
                return (ENXIO);
+
+       /*
+        * if this screen can resize we need to copy the descr so each screen
+        * gets its own
+        */
+       if (scrdesc->capabilities & WSSCREEN_RESIZE) {
+               /* we want per screen wsscreen_descr */
+               scrdescr2 = malloc(sizeof(struct wsscreen_descr), M_DEVBUF, M_NOWAIT);
+               if (scrdescr2 == NULL)
+                       return ENOMEM;
+               memcpy(scrdescr2, scrdesc, sizeof(struct wsscreen_descr));
+               scrdescr2->capabilities |= WSSCREEN_FREE;
+               scrdesc = scrdescr2;
+       }
+
        error = (*sc->sc_accessops->alloc_screen)(sc->sc_accesscookie,
                        scrdesc, &cookie, &ccol, &crow, &defattr);
        if (error)
@@ -1187,13 +1206,11 @@
        if (WSSCREEN_HAS_TTY(scr)) {
                tp = scr->scr_tty;
 
-/* printf("disc\n"); */
                /* do the line discipline ioctls first */
                error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
                if (error != EPASSTHROUGH)
                        return (error);
 
-/* printf("tty\n"); */
                /* then the tty ioctls */
                error = ttioctl(tp, cmd, data, flag, l);
                if (error != EPASSTHROUGH)
@@ -1328,9 +1345,29 @@
                fd.data = 0;
                error = (*sc->sc_accessops->load_font)(sc->sc_accesscookie,
                                        scr->scr_dconf->emulcookie, &fd);
-               if (!error && WSSCREEN_HAS_EMULATOR(scr))
+               if (!error && WSSCREEN_HAS_EMULATOR(scr)) {
                        (*scr->scr_dconf->wsemul->reset)
                                (scr->scr_dconf->wsemulcookie, WSEMUL_SYNCFONT);
+#ifdef DEBUG
+                       printf("resize: %d %d\n",
+                           scr->scr_dconf->scrdata->nrows,
+                           scr->scr_dconf->scrdata->ncols); 
+#endif
+                       if (scr->scr_dconf->wsemul->resize) {
+                               (*scr->scr_dconf->wsemul->resize)
+                                       (scr->scr_dconf->wsemulcookie,
+                                        scr->scr_dconf->scrdata);
+                               /* update the tty's size */
+                               scr->scr_tty->t_winsize.ws_row =
+                                   scr->scr_dconf->scrdata->nrows;
+                               scr->scr_tty->t_winsize.ws_col =
+                                   scr->scr_dconf->scrdata->ncols;
+                               /* send SIGWINCH to the process group on our tty */
+                               kpreempt_disable();
+                               ttysig(scr->scr_tty, TTYSIG_PG1, SIGWINCH);
+                               kpreempt_enable();
+                       }
+               }
                return (error);
 #undef d
 
diff -r 4fcc87500d03 -r 26eb9148c4f6 sys/dev/wscons/wsdisplay_vcons.c
--- a/sys/dev/wscons/wsdisplay_vcons.c  Fri May 19 16:56:35 2017 +0000
+++ b/sys/dev/wscons/wsdisplay_vcons.c  Fri May 19 19:22:33 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wsdisplay_vcons.c,v 1.36 2017/04/26 21:03:52 macallan Exp $ */
+/*     $NetBSD: wsdisplay_vcons.c,v 1.37 2017/05/19 19:22:33 macallan Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.36 2017/04/26 21:03:52 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.37 2017/05/19 19:22:33 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +57,12 @@
 #include "opt_vcons.h"
 #endif
 
+#ifdef VCONS_DEBUG
+#define DPRINTF printf
+#else
+#define DPRINTF if (0) printf
+#endif
+
 static void vcons_dummy_init_screen(void *, struct vcons_screen *, int, 
            long *);
 
@@ -66,6 +72,7 @@
 static void vcons_free_screen(void *, void *);
 static int  vcons_show_screen(void *, void *, int, void (*)(void *, int, int),
            void *);
+static int  vcons_load_font(void *, void *, struct wsdisplay_font *);
 
 #ifdef WSDISPLAY_SCROLLSUPPORT
 static void vcons_scroll(void *, void *, int);
@@ -139,6 +146,7 @@
        ao->alloc_screen = vcons_alloc_screen;
        ao->free_screen = vcons_free_screen;
        ao->show_screen = vcons_show_screen;
+       ao->load_font = vcons_load_font;
 #ifdef WSDISPLAY_SCROLLSUPPORT
        ao->scroll = vcons_scroll;
 #endif
@@ -147,6 +155,7 @@
        vd->active = NULL;
        vd->wanted = NULL;
        vd->currenttype = def;
+       vd->defaulttype = def;
        callout_init(&vd->switch_callout, 0);
        callout_setfunc(&vd->switch_callout, vcons_do_switch, vd);
 #ifdef VCONS_DRAW_INTR
@@ -220,9 +229,8 @@
               "supposed to supply a replacement for proper operation\n");
 }
 
-int
-vcons_init_screen(struct vcons_data *vd, struct vcons_screen *scr,
-    int existing, long *defattr)
+static int
+vcons_alloc_buffers(struct vcons_data *vd, struct vcons_screen *scr)
 {
        struct rasops_info *ri = &scr->scr_ri;
        int cnt, i;
@@ -230,9 +238,69 @@
        int size;
 #endif
 
+       /* 
+        * we allocate both chars and attributes in one chunk, attributes first 
+        * because they have the (potentially) bigger alignment 
+        */
+#ifdef WSDISPLAY_SCROLLSUPPORT
+       cnt = (ri->ri_rows + WSDISPLAY_SCROLLBACK_LINES) * ri->ri_cols;
+       scr->scr_lines_in_buffer = WSDISPLAY_SCROLLBACK_LINES;
+       scr->scr_current_line = 0;
+       scr->scr_line_wanted = 0;
+       scr->scr_offset_to_zero = ri->ri_cols * WSDISPLAY_SCROLLBACK_LINES;
+       scr->scr_current_offset = scr->scr_offset_to_zero;
+#else
+       cnt = ri->ri_rows * ri->ri_cols;
+#endif
+       scr->scr_attrs = malloc(cnt * (sizeof(long) + 
+           sizeof(uint32_t)), M_DEVBUF, M_WAITOK);
+       if (scr->scr_attrs == NULL)
+               return ENOMEM;
+
+       scr->scr_chars = (uint32_t *)&scr->scr_attrs[cnt];
+
+       /* 
+        * fill the attribute buffer with *defattr, chars with 0x20 
+        * since we don't know if the driver tries to mimic firmware output or
+        * reset everything we do nothing to VRAM here, any driver that feels
+        * the need to clear screen or something will have to do it on its own
+        * Additional screens will start out in the background anyway so
+        * cleaning or not only really affects the initial console screen
+        */
+       for (i = 0; i < cnt; i++) {
+               scr->scr_attrs[i] = scr->scr_defattr;
+               scr->scr_chars[i] = 0x20;
+       }
+
+#ifdef VCONS_DRAW_INTR
+       size = ri->ri_cols * ri->ri_rows;
+       if (size > vd->cells) {
+               if (vd->chars != NULL) free(vd->chars, M_DEVBUF);
+               if (vd->attrs != NULL) free(vd->attrs, M_DEVBUF);
+               vd->cells = size;
+               vd->chars = malloc(size * sizeof(uint32_t), M_DEVBUF,
+                   M_WAITOK|M_ZERO);
+               vd->attrs = malloc(size * sizeof(long), M_DEVBUF,
+                   M_WAITOK|M_ZERO);
+               vcons_invalidate_cache(vd);
+       } else if (SCREEN_IS_VISIBLE(scr))
+               vcons_invalidate_cache(vd);
+#endif
+       return 0;
+}
+
+int
+vcons_init_screen(struct vcons_data *vd, struct vcons_screen *scr,
+    int existing, long *defattr)
+{
+       struct rasops_info *ri = &scr->scr_ri;
+       int i;
+
        scr->scr_cookie = vd->cookie;
        scr->scr_vd = scr->scr_origvd = vd;
        scr->scr_busy = 0;
+       if (scr->scr_type == NULL)
+               scr->scr_type = vd->defaulttype;
        
        /*
         * call the driver-supplied init_screen function which is expected
@@ -246,7 +314,7 @@
         */
        vd->eraserows = ri->ri_ops.eraserows;
        vd->erasecols = ri->ri_ops.erasecols;
-       vd->putchar   = ri->ri_ops.putchar;
+       scr->putchar   = ri->ri_ops.putchar;
        vd->cursor    = ri->ri_ops.cursor;
 
        if (scr->scr_flags & VCONS_NO_COPYCOLS) {
@@ -271,27 +339,6 @@
 
        ri->ri_hw = scr;
 
-       /* 
-        * we allocate both chars and attributes in one chunk, attributes first 
-        * because they have the (potentially) bigger alignment 
-        */
-#ifdef WSDISPLAY_SCROLLSUPPORT
-       cnt = (ri->ri_rows + WSDISPLAY_SCROLLBACK_LINES) * ri->ri_cols;
-       scr->scr_lines_in_buffer = WSDISPLAY_SCROLLBACK_LINES;
-       scr->scr_current_line = 0;



Home | Main Index | Thread Index | Old Index