svn commit: r266836 - head/usr.sbin/vidcontrol

Aleksandr Rybalko ray at FreeBSD.org
Thu May 29 13:09:49 UTC 2014


Author: ray
Date: Thu May 29 13:09:48 2014
New Revision: 266836
URL: http://svnweb.freebsd.org/changeset/base/266836

Log:
  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.
  
  Tested by:	Claude Buisson <clbuisson at orange.fr>
  
  MFC after:	7 days
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/usr.sbin/vidcontrol/path.h
  head/usr.sbin/vidcontrol/vidcontrol.c

Modified: head/usr.sbin/vidcontrol/path.h
==============================================================================
--- head/usr.sbin/vidcontrol/path.h	Thu May 29 12:29:58 2014	(r266835)
+++ head/usr.sbin/vidcontrol/path.h	Thu May 29 13:09:48 2014	(r266836)
@@ -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/"

Modified: head/usr.sbin/vidcontrol/vidcontrol.c
==============================================================================
--- head/usr.sbin/vidcontrol/vidcontrol.c	Thu May 29 12:29:58 2014	(r266835)
+++ head/usr.sbin/vidcontrol/vidcontrol.c	Thu May 29 13:09:48 2014	(r266836)
@@ -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 *
 	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 *
 		     {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':


More information about the svn-src-head mailing list