summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorray <ray@FreeBSD.org>2014-06-16 11:51:00 +0000
committerray <ray@FreeBSD.org>2014-06-16 11:51:00 +0000
commitd518940c2d68ca3a4315ec34e4e46f51cd31eddb (patch)
treebd821febe98b876bee5c80fca4805b793d4e1ae6
parent720dde12b535f530bea4077e6db9a11dc6fa5307 (diff)
downloadFreeBSD-src-d518940c2d68ca3a4315ec34e4e46f51cd31eddb.zip
FreeBSD-src-d518940c2d68ca3a4315ec34e4e46f51cd31eddb.tar.gz
MFC: 266836, 266839
vt(4) support for vidcontrol(1). o Teach vidcontrol(1) how to load vt(4) font. o Teach vidcontrol(1) to distinct which virtual terminal system is running now. o Load vt(4) fonts from different location. o Add $FreeBSD$ tag for path.h. vt(4) support for kbdcontrol(1). Enable kbdcontrol(1) to use maps from vt(4) keymaps dir /usr/share/vt/keymaps if vt(4) is present. Sponsored by: The FreeBSD Foundation
-rw-r--r--usr.sbin/kbdcontrol/kbdcontrol.c17
-rw-r--r--usr.sbin/kbdcontrol/path.h4
-rw-r--r--usr.sbin/vidcontrol/path.h4
-rw-r--r--usr.sbin/vidcontrol/vidcontrol.c151
4 files changed, 162 insertions, 14 deletions
diff --git a/usr.sbin/kbdcontrol/kbdcontrol.c b/usr.sbin/kbdcontrol/kbdcontrol.c
index 8c9bb81..d38eda0 100644
--- a/usr.sbin/kbdcontrol/kbdcontrol.c
+++ b/usr.sbin/kbdcontrol/kbdcontrol.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <sys/kbio.h>
#include <sys/consio.h>
+#include <sys/sysctl.h>
#include "path.h"
#include "lex.h"
@@ -141,6 +142,17 @@ static void set_keyrates(char *opt);
static void show_kbd_info(void);
static void usage(void) __dead2;
+/* Detect presence of vt(4). */
+static int
+is_vt4(void)
+{
+
+ if (sysctlbyname("kern.vt.deadtimer", NULL, NULL, NULL, 0) == 0)
+ return (1);
+
+ return (0);
+}
+
static char *
nextarg(int ac, char **av, int *indp, int oc)
{
@@ -785,10 +797,13 @@ load_keymap(char *opt, int dumponly)
FILE *fd;
int i, j;
char *name, *cp;
- char blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd";
+ char blank[] = "", keymap_path[] = KEYMAP_PATH;
+ char vt_keymap_path[] = VT_KEYMAP_PATH, dotkbd[] = ".kbd";
char *prefix[] = {blank, blank, keymap_path, NULL};
char *postfix[] = {blank, dotkbd, NULL};
+ if (is_vt4())
+ prefix[2] = vt_keymap_path;
cp = getenv("KEYMAP_PATH");
if (cp != NULL)
asprintf(&(prefix[0]), "%s/", cp);
diff --git a/usr.sbin/kbdcontrol/path.h b/usr.sbin/kbdcontrol/path.h
index 709acbc..e1fa341 100644
--- a/usr.sbin/kbdcontrol/path.h
+++ b/usr.sbin/kbdcontrol/path.h
@@ -1,4 +1,8 @@
+/* $FreeBSD$ */
+
#define KEYMAP_PATH "/usr/share/syscons/keymaps/"
#define FONT_PATH "/usr/share/syscons/fonts/"
#define SCRNMAP_PATH "/usr/share/syscons/scrnmaps/"
+#define VT_KEYMAP_PATH "/usr/share/vt/keymaps/"
+#define VT_FONT_PATH "/usr/share/vt/fonts/"
diff --git a/usr.sbin/vidcontrol/path.h b/usr.sbin/vidcontrol/path.h
index 709acbc..e1fa341 100644
--- a/usr.sbin/vidcontrol/path.h
+++ b/usr.sbin/vidcontrol/path.h
@@ -1,4 +1,8 @@
+/* $FreeBSD$ */
+
#define KEYMAP_PATH "/usr/share/syscons/keymaps/"
#define FONT_PATH "/usr/share/syscons/fonts/"
#define SCRNMAP_PATH "/usr/share/syscons/scrnmaps/"
+#define VT_KEYMAP_PATH "/usr/share/vt/keymaps/"
+#define VT_FONT_PATH "/usr/share/vt/fonts/"
diff --git a/usr.sbin/vidcontrol/vidcontrol.c b/usr.sbin/vidcontrol/vidcontrol.c
index f4f1f0d..2096e2a 100644
--- a/usr.sbin/vidcontrol/vidcontrol.c
+++ b/usr.sbin/vidcontrol/vidcontrol.c
@@ -45,9 +45,12 @@ static const char rcsid[] =
#include <unistd.h>
#include <sys/fbio.h>
#include <sys/consio.h>
+#include <sys/endian.h>
#include <sys/errno.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include "path.h"
#include "decode.h"
@@ -78,6 +81,15 @@ static struct {
struct video_info video_mode_info;
} cur_info;
+struct vt4font_header {
+ uint8_t magic[8];
+ uint8_t width;
+ uint8_t height;
+ uint16_t pad;
+ uint32_t glyph_count;
+ uint32_t map_count[4];
+} __packed;
+
static int hex = 0;
static int vesa_cols;
static int vesa_rows;
@@ -86,6 +98,7 @@ static int colors_changed;
static int video_mode_changed;
static int normal_fore_color, normal_back_color;
static int revers_fore_color, revers_back_color;
+static int vt4_mode = 0;
static struct vid_info info;
static struct video_info new_mode_info;
@@ -115,7 +128,9 @@ init(void)
if (ioctl(0, CONS_GETINFO, &cur_info.console_info) == -1)
errc(1, errno, "getting console information");
- if (ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) == -1)
+ /* vt(4) use unicode, so no screen mapping required. */
+ if (vt4_mode == 0 &&
+ ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) == -1)
errc(1, errno, "getting screen map");
if (ioctl(0, CONS_GET, &cur_info.video_mode_number) == -1)
@@ -153,7 +168,8 @@ revert(void)
fprintf(stderr, "\033[=%dH", cur_info.console_info.mv_rev.fore);
fprintf(stderr, "\033[=%dI", cur_info.console_info.mv_rev.back);
- ioctl(0, PIO_SCRNMAP, &cur_info.screen_map);
+ if (vt4_mode == 0)
+ ioctl(0, PIO_SCRNMAP, &cur_info.screen_map);
if (cur_info.video_mode_number >= M_VESA_BASE)
ioctl(0, _IO('V', cur_info.video_mode_number - M_VESA_BASE),
@@ -179,7 +195,15 @@ revert(void)
static void
usage(void)
{
- fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
+ if (vt4_mode)
+ fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
+"usage: vidcontrol [-CHPpx] [-b color] [-c appearance] [-f [size] file]",
+" [-g geometry] [-h size] [-i adapter | mode]",
+" [-M char] [-m on | off] [-r foreground background]",
+" [-S on | off] [-s number] [-T xterm | cons25] [-t N | off]",
+" [mode] [foreground [background]] [show]");
+ else
+ fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
"usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]",
" [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]",
" [-M char] [-m on | off] [-r foreground background]",
@@ -188,6 +212,16 @@ usage(void)
exit(1);
}
+/* Detect presence of vt(4). */
+static int
+is_vt4(void)
+{
+
+ if (sysctlbyname("kern.vt.deadtimer", NULL, NULL, NULL, 0) == 0)
+ return (1);
+
+ return (0);
+}
/*
* Retrieve the next argument from the command line (for options that require
@@ -349,6 +383,72 @@ fsize(FILE *file)
return -1;
}
+static vfnt_map_t *
+load_vt4mappingtable(unsigned int nmappings, FILE *f)
+{
+ vfnt_map_t *t;
+ unsigned int i;
+
+ if (nmappings == 0)
+ return (NULL);
+
+ t = malloc(sizeof *t * nmappings);
+
+ if (fread(t, sizeof *t * nmappings, 1, f) != 1) {
+ perror("mappings");
+ exit(1);
+ }
+
+ for (i = 0; i < nmappings; i++) {
+ t[i].src = be32toh(t[i].src);
+ t[i].dst = be16toh(t[i].dst);
+ t[i].len = be16toh(t[i].len);
+ }
+
+ return (t);
+}
+
+static int
+load_vt4font(FILE *f)
+{
+ struct vt4font_header fh;
+ static vfnt_t vfnt;
+ size_t glyphsize;
+ unsigned int i;
+
+ if (fread(&fh, sizeof fh, 1, f) != 1) {
+ perror("file_header");
+ return (1);
+ }
+
+ if (memcmp(fh.magic, "VFNT0002", 8) != 0) {
+ fprintf(stderr, "Bad magic\n");
+ return (1);
+ }
+
+ for (i = 0; i < VFNT_MAPS; i++)
+ vfnt.map_count[i] = be32toh(fh.map_count[i]);
+ vfnt.glyph_count = be32toh(fh.glyph_count);
+ vfnt.width = fh.width;
+ vfnt.height = fh.height;
+
+ glyphsize = howmany(vfnt.width, 8) * vfnt.height * vfnt.glyph_count;
+ vfnt.glyphs = malloc(glyphsize);
+
+ if (fread(vfnt.glyphs, glyphsize, 1, f) != 1) {
+ perror("glyphs");
+ return (1);
+ }
+
+ for (i = 0; i < VFNT_MAPS; i++)
+ vfnt.map[i] = load_vt4mappingtable(vfnt.map_count[i], f);
+
+ if (ioctl(STDIN_FILENO, PIO_VFONT, &vfnt) == -1) {
+ perror("PIO_VFONT");
+ return (1);
+ }
+ return (0);
+}
/*
* Load a font from file and set it.
@@ -362,6 +462,7 @@ load_font(const char *type, const char *filename)
unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */
char *name, *fontmap, size_sufx[6];
const char *a[] = {"", FONT_PATH, NULL};
+ const char *vt4a[] = {"", VT_FONT_PATH, NULL};
const char *b[] = {filename, NULL};
const char *c[] = {"", size_sufx, NULL};
const char *d[] = {"", ".fnt", NULL};
@@ -376,21 +477,32 @@ load_font(const char *type, const char *filename)
{8, 8, PIO_FONT8x8},
{0, 0, 0}};
- _info.size = sizeof(_info);
- if (ioctl(0, CONS_GETINFO, &_info) == -1) {
- revert();
- warn("failed to obtain current video mode parameters");
- return;
- }
+ if (vt4_mode) {
+ size_sufx[0] = '\0';
+ } else {
+ _info.size = sizeof(_info);
+ if (ioctl(0, CONS_GETINFO, &_info) == -1) {
+ revert();
+ warn("failed to obtain current video mode parameters");
+ return;
+ }
- snprintf(size_sufx, sizeof(size_sufx), "-8x%d", _info.font_size);
- fd = openguess(a, b, c, d, &name);
+ snprintf(size_sufx, sizeof(size_sufx), "-8x%d", _info.font_size);
+ }
+ fd = openguess((vt4_mode == 0) ? a : vt4a, b, c, d, &name);
if (fd == NULL) {
revert();
errx(1, "%s: can't load font file", filename);
}
+ if (vt4_mode) {
+ if(load_vt4font(fd))
+ warn("failed to load font \"%s\"", filename);
+ fclose(fd);
+ return;
+ }
+
if (type != NULL) {
size = 0;
if (sscanf(type, "%dx%d", &w, &h) == 2) {
@@ -1199,9 +1311,12 @@ int
main(int argc, char **argv)
{
char *font, *type, *termmode;
+ const char *opts;
int dumpmod, dumpopt, opt;
int reterr;
+ vt4_mode = is_vt4();
+
init();
info.size = sizeof(info);
@@ -1211,8 +1326,12 @@ main(int argc, char **argv)
dumpmod = 0;
dumpopt = DUMP_FBF;
termmode = NULL;
- while ((opt = getopt(argc, argv,
- "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:T:t:x")) != -1)
+ if (vt4_mode)
+ opts = "b:Cc:f:g:h:Hi:M:m:pPr:S:s:T:t:x";
+ else
+ opts = "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:T:t:x";
+
+ while ((opt = getopt(argc, argv, opts)) != -1)
switch(opt) {
case 'b':
set_border_color(optarg);
@@ -1224,6 +1343,8 @@ main(int argc, char **argv)
set_cursor_type(optarg);
break;
case 'd':
+ if (vt4_mode)
+ break;
print_scrnmap();
break;
case 'f':
@@ -1255,9 +1376,13 @@ main(int argc, char **argv)
show_info(optarg);
break;
case 'l':
+ if (vt4_mode)
+ break;
load_scrnmap(optarg);
break;
case 'L':
+ if (vt4_mode)
+ break;
load_default_scrnmap();
break;
case 'M':
OpenPOWER on IntegriCloud