diff options
author | ray <ray@FreeBSD.org> | 2014-06-16 11:51:00 +0000 |
---|---|---|
committer | ray <ray@FreeBSD.org> | 2014-06-16 11:51:00 +0000 |
commit | d518940c2d68ca3a4315ec34e4e46f51cd31eddb (patch) | |
tree | bd821febe98b876bee5c80fca4805b793d4e1ae6 /usr.sbin | |
parent | 720dde12b535f530bea4077e6db9a11dc6fa5307 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/kbdcontrol/kbdcontrol.c | 17 | ||||
-rw-r--r-- | usr.sbin/kbdcontrol/path.h | 4 | ||||
-rw-r--r-- | usr.sbin/vidcontrol/path.h | 4 | ||||
-rw-r--r-- | usr.sbin/vidcontrol/vidcontrol.c | 151 |
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': |