kernel/syscons: Factor out font-scaling calculation to sc_font_scale().
authorImre Vadász <imre@vdsz.com>
Wed, 17 Feb 2016 22:01:23 +0000 (23:01 +0100)
committerImre Vadász <imre@vdsz.com>
Thu, 18 Feb 2016 19:43:08 +0000 (20:43 +0100)
Avoid setting desired_cols after calculating the font scaling factor,
otherwise multiple calls to sc_font_scale() could give surprising results.

Also use sc_font_scale in init_scp, and limit the terminal size on the
first vty to 80x25 to deal with the statically allocated sc_buffer for the
kernel console.

sys/dev/misc/syscons/scvidctl.c
sys/dev/misc/syscons/syscons.c
sys/dev/misc/syscons/syscons.h

index 9654bd0..9b2e40e 100644 (file)
@@ -51,9 +51,6 @@
 
 SET_DECLARE(scrndr_set, const sc_renderer_t);
 
-static int desired_cols = 0;
-TUNABLE_INT("kern.kms_columns", &desired_cols);
-
 int
 sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
                 int fontsize)
@@ -819,31 +816,7 @@ sc_update_render(scr_stat *scp)
                kprintf("kms console: xpixels %d ypixels %d\n",
                        scp->xpixel, scp->ypixel);
 
-               /*
-                * If columns not specified in /boot/loader.conf then
-                * calculate a non-fractional scaling that yields a
-                * reasonable number of rows and columns. If it is <0,
-                * don't scale at all.
-                */
-               if (desired_cols == 0) {
-                       int nomag = 1;
-                       while (scp->xpixel / (scp->font_width * nomag) >= 80 &&
-                              scp->ypixel / (scp->font_height * nomag) >= 25) {
-                               ++nomag;
-                       }
-                       if (nomag > 1)
-                               --nomag;
-                       desired_cols = scp->xpixel / (scp->font_width * nomag);
-               } else if (desired_cols < 0) {
-                       desired_cols = scp->xpixel / scp->font_width;
-               }
-               scp->blk_width = scp->xpixel / desired_cols;
-               scp->blk_height = scp->blk_width * scp->font_height /
-                                 scp->font_width;
-
-               /* scp->xsize = scp->xpixel / scp->blk_width; total possible */
-               scp->xsize = desired_cols;
-               scp->ysize = scp->ypixel / scp->blk_height;
+               sc_font_scale(scp, 0, 0);
 
                kprintf("kms console: scale-to %dx%d cols=%d rows=%d\n",
                        scp->blk_width, scp->blk_height,
index 7dba68c..7bbe714 100644 (file)
@@ -138,6 +138,9 @@ static      int             syscons_async;
 SYSCTL_INT(_kern, OID_AUTO, syscons_async, CTLFLAG_RW, &syscons_async,
           0, "Asynchronous bulk syscons fb updates");
 
+static int desired_cols = 0;
+TUNABLE_INT("kern.kms_columns", &desired_cols);
+
 #define SC_CONSOLECTL  255
 
 #define VIRTUAL_TTY(sc, x) ((SC_DEV((sc),(x)) != NULL) ?       \
@@ -329,6 +332,40 @@ register_framebuffer(struct fb_info *info)
     return 0;
 }
 
+void
+sc_font_scale(scr_stat *scp, int max_cols, int max_rows)
+{
+       int cols, rows;
+
+       /*
+        * If columns not specified in /boot/loader.conf then
+        * calculate a non-fractional scaling that yields a
+        * reasonable number of rows and columns. If it is <0,
+        * don't scale at all.
+        */
+       if (desired_cols == 0) {
+               int nomag = 1;
+               while (scp->xpixel / (scp->font_width * nomag) >= 80 &&
+                      scp->ypixel / (scp->font_height * nomag) >= 25) {
+                       ++nomag;
+               }
+               if (nomag > 1)
+                       --nomag;
+               cols = scp->xpixel / (scp->font_width * nomag);
+       } else if (desired_cols < 0) {
+               cols = scp->xpixel / scp->font_width;
+       } else {
+               cols = desired_cols;
+       }
+       scp->blk_width = scp->xpixel / cols;
+       scp->blk_height = scp->blk_width * scp->font_height / scp->font_width;
+       rows = scp->ypixel / scp->blk_height;
+
+       /* scp->xsize = scp->xpixel / scp->blk_width; total possible */
+       scp->xsize = max_cols ? imin(max_cols, cols) : cols;
+       scp->ysize = max_rows ? imin(max_rows, rows) : rows;
+}
+
 /* probe video adapters, return TRUE if found */ 
 static int
 scvidprobe(int unit, int flags, int cons)
@@ -3259,7 +3296,6 @@ static void
 init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
 {
     video_info_t info;
-    int scaled_font_height;
 
     bzero(scp, sizeof(*scp));
 
@@ -3268,10 +3304,29 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
     scp->status = 0;
     scp->mode = sc->initial_mode;
     callout_init_mp(&scp->blink_screen_ch);
-    lwkt_gettoken(&tty_token);
-    (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info);
-    lwkt_reltoken(&tty_token);
-    if (info.vi_flags & V_INFO_GRAPHICS) {
+    if (sc->fbi == NULL) {
+       lwkt_gettoken(&tty_token);
+       (*vidsw[sc->adapter]->get_info)(sc->adp, scp->mode, &info);
+       lwkt_reltoken(&tty_token);
+    }
+    if (scp->fbi != NULL) {
+       scp->xpixel = scp->fbi->width;
+       scp->ypixel = scp->fbi->height;
+       scp->font_width = 8;
+       scp->font_height = 16;
+
+       /* The first vty uses a statically allocated 80x25 buffer */
+       if (vty == sc->first_vty)
+               sc_font_scale(scp, 80, 25);
+       else
+               sc_font_scale(scp, 0, 0);
+
+#ifndef SC_NO_FONT_LOADING
+       scp->font = sc->font_16;
+#else
+       scp->font = NULL;
+#endif
+    } else if (info.vi_flags & V_INFO_GRAPHICS) {
        scp->status |= GRAPHICS_MODE;
        scp->xpixel = info.vi_width;
        scp->ypixel = info.vi_height;
@@ -3311,18 +3366,6 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
     }
     scp->xoff = scp->yoff = 0;
     scp->xpos = scp->ypos = 0;
-    scp->fbi = sc->fbi;
-    if (scp->fbi != NULL) {
-       scp->xpixel = scp->fbi->width;
-       scp->ypixel = scp->fbi->height;
-
-       scp->blk_width = scp->xpixel / 80;
-       scaled_font_height = scp->blk_width * 100 / scp->font_width;
-       scp->blk_height = scp->ypixel * 100 / scaled_font_height;
-
-       scp->xsize = scp->xpixel / scp->blk_width;
-       scp->ysize = scp->ypixel / scp->blk_height;
-    }
     sc_vtb_init(&scp->vtb, VTB_MEMORY, 0, 0, NULL, FALSE);
     sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, 0, 0, NULL, FALSE);
     scp->start = scp->xsize * scp->ysize - 1;
index 59922f5..2280e78 100644 (file)
@@ -525,6 +525,7 @@ void                sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard);
 int            sc_init_emulator(scr_stat *scp, char *name);
 void           sc_paste(scr_stat *scp, u_char *p, int count);
 void           sc_bell(scr_stat *scp, int pitch, int duration);
+void           sc_font_scale(scr_stat *scp, int max_cols, int max_rows);
 
 /* schistory.c */
 #ifndef SC_NO_HISTORY