The default built-in font, Boldface
, which is loaded at boot-time on a framebuffer (whether genfb
or DRM) console is too small as it is 8x16. The other font built into the kernel is Boldface 16x32
, and this, if you load it, will give you a console approximating a 80x25 screen--ie. this font is too large. Try it:
$ sudo wsconsctl -f $(tty) -dw font="Boldface 16x32"
The other fonts in /usr/share/wscons/fonts/
are all also small (8x16, 8x10, 8x8), as their extensions indicate.
The solution that is usually advocated to get a reasonable-size font is to a) edit the kernel config, b) add one of the fonts in /usr/src/sys/dev/wsfont/
using directives like options FONT_SPLEEN16x32
, and c) then recompile the kernel. But, this is a pain. Simpler to write a program to suck in the fonts and load them into the kernel as needed. This is what the code below does.
Compile, and then run it as follows:
$ ./wsfont list
Compiled in fonts:
Fontname Int. Name 1ch Nch Enc Wid Hei Str bO BO Size
DejaVu_Sans_Mono_12x22 DejaVu Sans Mono 0 256 iso 12 22 12 LR LR 67584
Droid_Sans_Mono_12x22 Droid Sans Mono 0 256 iso 12 22 12 LR LR 67584
Droid_Sans_Mono_19x36 Droid Sans Mono 0 256 iso 19 36 19 LR LR 175104
Droid_Sans_Mono_9x18 Droid Sans Mono 0 256 iso 9 18 9 LR LR 41472
Go_Mono_12x23 Go Mono 0 256 iso 12 23 12 LR LR 70656
bold16x32 Boldface 16x32 1 254 ibm 16 32 2 LR LR 16256
bold8x16 Boldface 1 254 ibm 8 16 1 LR LR 4064
gallant12x22 Gallant 0 256 iso 12 22 2 LR LR 11264
Glass_TTY_VT220_10x19 Glass TTY VT220 0 256 iso 10 19 10 LR LR 48640
Glass_TTY_VT220_10x25 Glass TTY VT220 0 256 iso 10 25 10 LR LR 64000
lucida16x29 Lucida 32 95 iso 16 29 2 LR LR 5510
omron12x20 omron12x20 32 95 iso 12 20 2 LR LR 3800
qvss8x15 QVSS 32 224 iso 8 15 1 RL LR 3360
sony12x24 sony12x24 32 224 iso 12 24 2 LR LR 10752
sony8x16 sony8x16 32 224 iso 8 16 1 LR LR 3584
spleen12x24 Spleen 12x24 32 224 iso 12 24 2 LR LR 10752
spleen16x32 Spleen 16x32 32 224 iso 16 32 2 LR LR 14336
spleen32x64 Spleen 32x64 32 224 iso 32 64 4 LR LR 57344
spleen5x8 Spleen 5x8 32 96 iso 5 8 1 LR LR 768
spleen8x16 Spleen 8x16 32 224 iso 8 16 1 LR LR 3584
vt220iso8x16 vt220iso8x16 32 224 iso 8 16 1 LR LR 3584
vt220iso8x8 vt220iso8x8 32 224 iso 8 8 1 LR LR 1792
vt220l8x10 vt220l 0 256 ibm 8 10 1 LR LR 2560
vt220l8x16 vt220l 0 256 ibm 8 16 1 LR LR 4096
vt220l8x8 vt220l 0 256 ibm 8 8 1 LR LR 2048
$ sudo ./wsfont set DejaVu_Sans_Mono_12x22
# Font should change on current console.
After you've checked out the fonts available on NetBSD (9.1 shown above), you can write all the fonts into /usr/share/wscons/fonts/
and then load your choice at boot-time via /etc/wsconf.conf
:
$ sudo ./wsfont dump /usr/share/wscons/fonts/
$ ls -ltr /usr/share/wscons/fonts/*.fnt
-rw-r--r-- 1 root wheel 67684 Nov 15 10:28 DejaVu_Sans_Mono_12x22.fnt
-rw-r--r-- 1 root wheel 67684 Nov 15 10:28 Droid_Sans_Mono_12x22.fnt
-rw-r--r-- 1 root wheel 175204 Nov 15 10:28 Droid_Sans_Mono_19x36.fnt
-rw-r--r-- 1 root wheel 41572 Nov 15 10:28 Droid_Sans_Mono_9x18.fnt
-rw-r--r-- 1 root wheel 70756 Nov 15 10:28 Go_Mono_12x23.fnt
-rw-r--r-- 1 root wheel 16356 Nov 15 10:28 bold16x32.fnt
-rw-r--r-- 1 root wheel 4164 Nov 15 10:28 bold8x16.fnt
-rw-r--r-- 1 root wheel 11364 Nov 15 10:28 gallant12x22.fnt
-rw-r--r-- 1 root wheel 48740 Nov 15 10:28 Glass_TTY_VT220_10x19.fnt
-rw-r--r-- 1 root wheel 64100 Nov 15 10:28 Glass_TTY_VT220_10x25.fnt
-rw-r--r-- 1 root wheel 5610 Nov 15 10:28 lucida16x29.fnt
-rw-r--r-- 1 root wheel 3900 Nov 15 10:28 omron12x20.fnt
-rw-r--r-- 1 root wheel 3460 Nov 15 10:28 qvss8x15.fnt
-rw-r--r-- 1 root wheel 10852 Nov 15 10:28 sony12x24.fnt
-rw-r--r-- 1 root wheel 3684 Nov 15 10:28 sony8x16.fnt
-rw-r--r-- 1 root wheel 10852 Nov 15 10:28 spleen12x24.fnt
-rw-r--r-- 1 root wheel 14436 Nov 15 10:28 spleen16x32.fnt
-rw-r--r-- 1 root wheel 57444 Nov 15 10:28 spleen32x64.fnt
-rw-r--r-- 1 root wheel 868 Nov 15 10:28 spleen5x8.fnt
-rw-r--r-- 1 root wheel 3684 Nov 15 10:28 spleen8x16.fnt
-rw-r--r-- 1 root wheel 3684 Nov 15 10:28 vt220iso8x16.fnt
-rw-r--r-- 1 root wheel 1892 Nov 15 10:28 vt220iso8x8.fnt
-rw-r--r-- 1 root wheel 2660 Nov 15 10:28 vt220l8x10.fnt
-rw-r--r-- 1 root wheel 4196 Nov 15 10:28 vt220l8x16.fnt
-rw-r--r-- 1 root wheel 2148 Nov 15 10:28 vt220l8x8.fnt
$
Edit your /etc/wsconf.conf
and add lines like these (read the wscons.conf(5)
, wsfontload(8)
and wsconsctl(8)
man-pages for details):
font dejavu 12 22 iso /usr/share/wscons/fonts/DejaVu_Sans_Mono_12x22.fnt
setvar ttyE0 font dejavu
setvar ttyE1 font dejavu
setvar ttyE2 font dejavu
setvar ttyE3 font dejavu
You'll easily find the locations where you should add those lines. Check out the QVSS font, where somebody's clearly been having fun.
Makefile (imp: all blanks at the beginning are actually tabs):
CC ?= gcc
CFLAGS ?= -Wall -Wextra -g -pipe
LDFLAGS ?=
INC = -I/usr/src/sys
EXE = wsfont
SRC = wsfont.c
HDR = wsfont.h
${EXE}: ${SRC} ${HDR}
${CC} ${CFLAGS} ${INC} -o ${EXE} ${SRC} ${LDFLAGS}
${HDR}:
awk -f mkhdr.awk /usr/src/sys/dev/wsfont/*.h > ${HDR}
clean:
rm -f ${EXE} ${HDR}
mkhdr.awk:
#!/usr/bin/awk -f
BEGIN {
N = 0
}
{
FNAME = FILENAME
gsub(/^.+\//, "", FNAME)
sub(/\.h$/, "", FNAME)
if (FNAME ~ /vt220koi8x10/)
nextfile # we get a macro--skip this
PAT = "(static[[:blank:]]+)?struct[[:blank:]]+wsdisplay_font[[:blank:]]+[^[:blank:]]+[[:blank:]]*=[[:blank:]]*{"
if ($0 ~ PAT) {
printf("#include <dev/wsfont/%s.h>\n", FNAME)
PFX = "(static[[:blank:]]+)?struct[[:blank:]]+wsdisplay_font[[:blank:]]+"
SUF = "[[:blank:]]*=[[:blank:]]*{"
FONT = $0
sub(PFX, "", FONT)
sub(SUF, "", FONT)
if (length FONT > 0)
FONTS[N++] = FONT
nextfile
}
}
END {
printf("\nstatic struct wsfont {\n")
printf("\tchar* fname;\n")
printf("\tstruct wsdisplay_font* wsdfont;\n")
printf("} wsfonts[] = {\n")
for (i = 0; i < N; i++)
printf("\t{ \"%s\", \t&%s },\n", FONTS[i], FONTS[i])
printf("\t{ NULL, NULL }\n};\n");
}
wsfont.c:
#include <dev/wscons/wsconsio.h>
#include <sys/ioctl.h>
#include <endian.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "wsfont.h"
static int do_help(void);
static int do_list(void);
static int do_set(int argc, char* argv[]);
static int do_dump(int argc, char* argv[]);
static int wr_font(struct wsdisplay_font* wsf, char* path);
static void pr_font(struct wsdisplay_font* wsf);
static int set_font(char* fname, struct wsdisplay_font* wsf, char* cdev);
static char* bord2s(int b_order);
static char* enc2s(int encoding);
static char* prog;
int
main(int argc, char* argv[])
{
char* cmd;
int rc = EXIT_FAILURE;
prog = argv[0];
if (argc == 1) {
rc = do_help();
exit(rc);
}
cmd = argv[1];
if (strcmp(cmd, "help") == 0)
rc = do_help();
else if (strcmp(cmd, "list") == 0)
rc = do_list();
else if (strcmp(cmd, "dump") == 0)
rc = do_dump(argc, argv);
else if (strcmp(cmd, "set") == 0)
rc = do_set(argc, argv);
else
warnx("%s: unknown command.\nTry: help\n", cmd);
return rc;
}
static int
do_help(void)
{
printf(
"Available commands:\n"
" list: List compiled-in fonts\n"
"\n"
" dump DIR: Dump fonts into \"DIR\" (which must exist)\n"
" eg.: wsfont dump /usr/share/wscons/fonts\n"
"\n"
" set FONT [DEV]: Load & set \"FONT\" on console \"DEV\" (or current)\n"
" eg.: wsfont set Go_Mono_12x23 /dev/ttyE0\n"
" eg.: wsfont set Go_Mono_12x23\n"
"\n"
" help: This list\n");
return EXIT_SUCCESS;
}
static int
do_list(void)
{
int i, rc = EXIT_FAILURE;
for (i = 0; wsfonts[i].fname != NULL; i++) {
if (i == 0) { /* print heading */
printf("Compiled in fonts:\n");
printf("%-22s %-16s ", "Fontname", "Int. Name");
printf("%3s %3s %-5s ", "1ch", "Nch", "Enc");
printf("%3s %3s %3s ", "Wid", "Hei", "Str");
printf("%-2s %-2s %6s\n", "bO", "BO", "Size");
}
printf("%-22s", wsfonts[i].fname);
pr_font(wsfonts[i].wsdfont);
}
if (i == 0)
warnx("error: no fonts compiled in!");
else
rc = EXIT_SUCCESS;
return rc;
}
static void
pr_font(struct wsdisplay_font* wsf)
{
printf(" %-16s %3d %3d", wsf->name, wsf->firstchar, wsf->numchars);
printf(" ");
printf("%-5s", enc2s(wsf->encoding));
printf(" %3d %3d %3d", wsf->fontwidth, wsf->fontheight, wsf->stride);
printf(" %-2s", bord2s(wsf->bitorder));
printf(" %-2s", bord2s(wsf->byteorder));
printf(" %6u\n", wsf->fontheight * wsf->stride * wsf->numchars);
}
static char*
enc2s(int encoding)
{
switch (encoding) {
case WSDISPLAY_FONTENC_ISO: return "iso";
case WSDISPLAY_FONTENC_IBM: return "ibm";
case WSDISPLAY_FONTENC_PCVT: return "pcvt";
case WSDISPLAY_FONTENC_ISO7: return "iso7";
case WSDISPLAY_FONTENC_ISO2: return "iso2";
case WSDISPLAY_FONTENC_KOI8_R: return "koi8r";
default: return "?";
}
}
static char*
bord2s(int b_order)
{
switch (b_order) {
case WSDISPLAY_FONTORDER_KNOWN: return "K";
case WSDISPLAY_FONTORDER_L2R: return "LR";
case WSDISPLAY_FONTORDER_R2L: return "RL";
default: return "?";
}
}
static int
do_dump(int argc, char* argv[])
{
int i, rc = EXIT_FAILURE;
char* dir, *p;
if (argc != 3) {
warnx("Usage: %s dump DIR", prog);
return rc;
}
dir = argv[2];
if (*dir == '\0') {
warnx("error: empty directory name");
return rc;
}
p = dir + strlen(dir);
while (--p >= dir && *p == '/')
*p = '\0';
rc = EXIT_SUCCESS;
for (i = 0; wsfonts[i].fname != NULL; i++) {
char path[PATH_MAX];
snprintf(path, sizeof path, "%s/%s.fnt", dir, wsfonts[i].fname);
rc = wr_font(wsfonts[i].wsdfont, path);
if (rc != EXIT_SUCCESS)
break;
}
return rc;
}
static int
wr_font(struct wsdisplay_font* wsf, char* path)
{
char buf[4 + 64];
int fd, n, rc = EXIT_FAILURE;
if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1) {
warn("%s: open failed", path);
return rc;
}
memset(buf, 0, sizeof buf);
memcpy(buf, "WSFT", 4);
strcpy(buf + 4, wsf->name);
n = sizeof buf;
if (write(fd, buf, n) != n) {
warn("%s: write failed", path);
unlink(path);
goto out;
}
n = htole32(wsf->firstchar); write(fd, &n, 4);
n = htole32(wsf->numchars); write(fd, &n, 4);
n = htole32(wsf->encoding); write(fd, &n, 4);
n = htole32(wsf->fontwidth); write(fd, &n, 4);
n = htole32(wsf->fontheight); write(fd, &n, 4);
n = htole32(wsf->stride); write(fd, &n, 4);
n = htole32(wsf->bitorder); write(fd, &n, 4);
n = htole32(wsf->byteorder); write(fd, &n, 4);
n = wsf->numchars * wsf->fontheight * wsf->stride;
if (write(fd, wsf->data, n) != n) {
warn("%s: write failed", path);
unlink(path);
} else
rc = EXIT_SUCCESS;
out:
close(fd);
return rc;
}
static int
do_set(int argc, char* argv[])
{
char* cdev, *fname;
int i, rc = EXIT_FAILURE;
if (argc < 3) {
warnx("Usage: %s set fontname console_device", prog);
return rc;
}
fname = argv[2];
if (argc == 4)
cdev = argv[3];
else { /* set font on current tty */
cdev = ttyname(STDIN_FILENO);
if (cdev == NULL) {
warn("ttyname failed");
return rc;
}
}
for (i = 0; wsfonts[i].fname != NULL; i++) {
if (strcmp(wsfonts[i].fname, fname) == 0) {
rc = set_font(fname, wsfonts[i].wsdfont, cdev);
break;
}
}
return rc;
}
static int
set_font(char* fname, struct wsdisplay_font* wsf, char* cdev)
{
int fd, rc = EXIT_FAILURE;
char* cmd = NULL;
if ((fd = open("/dev/wsfont", O_RDWR)) < 0) {
warn("/dev/wsfont: open failed");
return rc;
}
wsf->name = fname; /* VT220 has multiple fonts with same name */
if (ioctl(fd, WSDISPLAYIO_LDFONT, wsf) < 0) {
if (errno == EEXIST)
warnx("%s: font already loaded", wsf->name);
else {
warn("ioctl WSDISPLAYIO_LDFONT failed");
return rc;
}
}
close(fd);
if (asprintf(&cmd, "/sbin/wsconsctl -f \"%s\" -dw font=\"%s\"",
cdev, wsf->name) == -1) {
warn("asprintf failed");
return rc;
}
if (system(cmd) != 0)
warn("warning: %s: cmd failed", cmd);
else
rc = EXIT_SUCCESS;
free(cmd);
return rc;
}
Enjoy.