vidcontrol.c revision 66834
118334Speter/*-
272566Sobrien * Copyright (c) 1994-1996 S�ren Schmidt
390282Sobrien * All rights reserved.
418334Speter *
590282Sobrien * Redistribution and use in source and binary forms, with or without
618334Speter * modification, are permitted provided that the following conditions
790282Sobrien * are met:
890282Sobrien * 1. Redistributions of source code must retain the above copyright
990282Sobrien *    notice, this list of conditions and the following disclaimer,
1090282Sobrien *    in this position and unchanged.
1118334Speter * 2. Redistributions in binary form must reproduce the above copyright
1290282Sobrien *    notice, this list of conditions and the following disclaimer in the
1390282Sobrien *    documentation and/or other materials provided with the distribution.
1490282Sobrien * 3. The name of the author may not be used to endorse or promote products
1590282Sobrien *    derived from this software withough specific prior written permission
1618334Speter *
1718334Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1890282Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1990282Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2090282Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2118334Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2252558Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2352558Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2418334Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2518334Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2618334Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2718334Speter */
2818334Speter
2918334Speter#ifndef lint
3050615Sobrienstatic const char rcsid[] =
3150615Sobrien  "$FreeBSD: head/usr.sbin/vidcontrol/vidcontrol.c 66834 2000-10-08 21:34:00Z phk $";
3250615Sobrien#endif /* not lint */
3318334Speter
3418334Speter#include <ctype.h>
3518334Speter#include <err.h>
3650615Sobrien#include <limits.h>
3750615Sobrien#include <stdio.h>
3818334Speter#include <stdlib.h>
3950615Sobrien#include <string.h>
4050615Sobrien#include <unistd.h>
4150615Sobrien#include <sys/fbio.h>
4218334Speter#include <sys/consio.h>
4318334Speter#include <sys/errno.h>
4418334Speter#include "path.h"
4518334Speter#include "decode.h"
4618334Speter
4790282Sobrienchar 	legal_colors[16][16] = {
4818334Speter	"black", "blue", "green", "cyan",
4918334Speter	"red", "magenta", "brown", "white",
5050615Sobrien	"grey", "lightblue", "lightgreen", "lightcyan",
5190282Sobrien	"lightred", "lightmagenta", "yellow", "lightwhite"
5290282Sobrien};
5350615Sobrienint 	hex = 0;
5418334Speterint 	number;
5550615Sobrienchar 	letter;
5690282Sobrienstruct 	vid_info info;
5750615Sobrien
5852558Sobrien
5952558Sobrienstatic void
6052558Sobrienusage()
6190282Sobrien{
6290282Sobrien	fprintf(stderr, "%s\n%s\n%s\n%s\n",
6390282Sobrien"usage: vidcontrol [-r fg bg] [-b color] [-c appearance] [-d] [-l scrmap]",
6490282Sobrien"                  [-i adapter | mode] [-L] [-M char] [-m on|off]",
6590282Sobrien"                  [-f size file] [-s number] [-t N|off] [-x] [mode]",
6690282Sobrien"                  [fgcol [bgcol]] [show]");
6790282Sobrien	exit(1);
6890282Sobrien}
6990282Sobrien
7090282Sobrienchar *
7190282Sobriennextarg(int ac, char **av, int *indp, int oc)
7290282Sobrien{
7390282Sobrien	if (*indp < ac)
7490282Sobrien		return(av[(*indp)++]);
7518334Speter	errx(1, "option requires two arguments -- %c", oc);
7650615Sobrien	return("");
7750615Sobrien}
7850615Sobrien
7950615Sobrienchar *
8050615Sobrienmkfullname(const char *s1, const char *s2, const char *s3)
8150615Sobrien{
8250615Sobrien	static char *buf = NULL;
8350615Sobrien	static int bufl = 0;
8450615Sobrien	int f;
8550615Sobrien
8650615Sobrien	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
8750615Sobrien	if (f > bufl) {
8818334Speter		if (buf)
8990282Sobrien			buf = (char *)realloc(buf, f);
9090282Sobrien		else
9118334Speter			buf = (char *)malloc(f);
9290282Sobrien	}
9390282Sobrien	if (!buf) {
9490282Sobrien		bufl = 0;
9590282Sobrien		return(NULL);
9618334Speter	}
9718334Speter
9818334Speter	bufl = f;
9990282Sobrien	strcpy(buf, s1);
10018334Speter	strcat(buf, s2);
10118334Speter	strcat(buf, s3);
10290282Sobrien	return(buf);
10390282Sobrien}
10418334Speter
10518334Spetervoid
10618334Speterload_scrnmap(char *filename)
10718334Speter{
10818334Speter	FILE *fd = 0;
10918334Speter	int i, size;
11018334Speter	char *name;
11118334Speter	scrmap_t scrnmap;
11218334Speter	char *prefix[]  = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL};
11318334Speter	char *postfix[] = {"", ".scm", "", ".scm"};
11418334Speter
11518334Speter	for (i=0; prefix[i]; i++) {
11690282Sobrien		name = mkfullname(prefix[i], filename, postfix[i]);
11718334Speter		fd = fopen(name, "r");
11890282Sobrien		if (fd)
11918334Speter			break;
12018334Speter	}
12118334Speter	if (fd == NULL) {
12218334Speter		warn("screenmap file not found");
12318334Speter		return;
12418334Speter	}
12518334Speter	size = sizeof(scrnmap);
12690282Sobrien	if (decode(fd, (char *)&scrnmap) != size) {
12790282Sobrien		rewind(fd);
12890282Sobrien		if (fread(&scrnmap, 1, size, fd) != size) {
12990282Sobrien			warnx("bad screenmap file");
13090282Sobrien			fclose(fd);
13190282Sobrien			return;
13290282Sobrien		}
13390282Sobrien	}
13418334Speter	if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0)
13590282Sobrien		warn("can't load screenmap");
13690282Sobrien	fclose(fd);
13750615Sobrien}
13890282Sobrien
13990282Sobrienvoid
14090282Sobrienload_default_scrnmap()
14190282Sobrien{
14290282Sobrien	scrmap_t scrnmap;
14390282Sobrien	int i;
14418334Speter
14590282Sobrien	for (i=0; i<256; i++)
14690282Sobrien		*((char*)&scrnmap + i) = i;
14790282Sobrien	if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0)
14890282Sobrien		warn("can't load default screenmap");
14990282Sobrien}
15090282Sobrien
15190282Sobrienvoid
15290282Sobrienprint_scrnmap()
15352558Sobrien{
15452558Sobrien	unsigned char map[256];
15590282Sobrien	int i;
15652558Sobrien
15752558Sobrien	if (ioctl(0, GIO_SCRNMAP, &map) < 0) {
15850615Sobrien		warn("getting screenmap");
15950615Sobrien		return;
16018334Speter	}
16118334Speter	for (i=0; i<sizeof(map); i++) {
16218334Speter		if (i > 0 && i % 16 == 0)
16390282Sobrien			fprintf(stdout, "\n");
16418334Speter		if (hex)
16590282Sobrien			fprintf(stdout, " %02x", map[i]);
16618334Speter		else
16718334Speter			fprintf(stdout, " %03d", map[i]);
16818334Speter	}
16918334Speter	fprintf(stdout, "\n");
17018334Speter
17118334Speter}
17290282Sobrien
17318334Spetervoid
17418334Speterload_font(char *type, char *filename)
17518334Speter{
17618334Speter	FILE	*fd = 0;
17718334Speter	int	i, size;
17890282Sobrien	unsigned long io;
17918334Speter	char	*name, *fontmap;
18018334Speter	char	*prefix[]  = {"", "", FONT_PATH, FONT_PATH, NULL};
18118334Speter	char	*postfix[] = {"", ".fnt", "", ".fnt"};
18218334Speter
18318334Speter	for (i=0; prefix[i]; i++) {
18452558Sobrien		name = mkfullname(prefix[i], filename, postfix[i]);
18552558Sobrien		fd = fopen(name, "r");
18652558Sobrien		if (fd)
18718334Speter			break;
18818334Speter	}
18918334Speter	if (fd == NULL) {
19018334Speter		warn("font file not found");
19118334Speter		return;
19218334Speter	}
19318334Speter	if (!strcmp(type, "8x8")) {
19418334Speter		size = 8*256;
19518334Speter		io = PIO_FONT8x8;
19652558Sobrien	}
19718334Speter	else if (!strcmp(type, "8x14")) {
19890282Sobrien		size = 14*256;
19990282Sobrien		io = PIO_FONT8x14;
20090282Sobrien	}
20190282Sobrien	else if (!strcmp(type, "8x16")) {
20290282Sobrien		size = 16*256;
20318334Speter		io = PIO_FONT8x16;
20418334Speter	}
20518334Speter	else {
20618334Speter		warn("bad font size specification");
20718334Speter		fclose(fd);
20818334Speter		return;
20990282Sobrien	}
21018334Speter	fontmap = (char*) malloc(size);
21190282Sobrien	if (decode(fd, fontmap) != size) {
21290282Sobrien		rewind(fd);
21390282Sobrien		if (fread(fontmap, 1, size, fd) != size) {
21490282Sobrien			warnx("bad font file");
21590282Sobrien			fclose(fd);
21690282Sobrien			free(fontmap);
21790282Sobrien			return;
21890282Sobrien		}
21990282Sobrien	}
22090282Sobrien	if (ioctl(0, io, fontmap) < 0)
22190282Sobrien		warn("can't load font");
22290282Sobrien	fclose(fd);
22390282Sobrien	free(fontmap);
22490282Sobrien}
22590282Sobrien
22690282Sobrienvoid
22790282Sobrienset_screensaver_timeout(char *arg)
22890282Sobrien{
22990282Sobrien	int nsec;
23090282Sobrien
23190282Sobrien	if (!strcmp(arg, "off"))
23290282Sobrien		nsec = 0;
23390282Sobrien	else {
23490282Sobrien		nsec = atoi(arg);
23590282Sobrien		if ((*arg == '\0') || (nsec < 1)) {
23690282Sobrien			warnx("argument must be a positive number");
23790282Sobrien			return;
23890282Sobrien		}
23990282Sobrien	}
24090282Sobrien	if (ioctl(0, CONS_BLANKTIME, &nsec) == -1)
24190282Sobrien		warn("setting screensaver period");
24290282Sobrien}
24390282Sobrien
24490282Sobrienvoid
24590282Sobrienset_cursor_type(char *appearence)
24690282Sobrien{
24790282Sobrien	int type;
24890282Sobrien
24990282Sobrien	if (!strcmp(appearence, "normal"))
25090282Sobrien		type = 0;
25190282Sobrien	else if (!strcmp(appearence, "blink"))
25290282Sobrien		type = 1;
25390282Sobrien	else if (!strcmp(appearence, "destructive"))
25490282Sobrien		type = 3;
25590282Sobrien	else {
25690282Sobrien		warnx("argument to -c must be normal, blink or destructive");
25790282Sobrien		return;
25890282Sobrien	}
25990282Sobrien	ioctl(0, CONS_CURSORTYPE, &type);
26090282Sobrien}
26190282Sobrien
26290282Sobrienvoid
26390282Sobrienvideo_mode(int argc, char **argv, int *index)
26490282Sobrien{
26590282Sobrien	static struct {
26690282Sobrien		char *name;
26790282Sobrien		unsigned long mode;
26890282Sobrien	} modes[] = {
26990282Sobrien		{ "80x25",		SW_TEXT_80x25 },
27090282Sobrien		{ "80x30",		SW_TEXT_80x30 },
27190282Sobrien		{ "80x43",		SW_TEXT_80x43 },
27290282Sobrien		{ "80x50",		SW_TEXT_80x50 },
27390282Sobrien		{ "80x60",		SW_TEXT_80x60 },
27490282Sobrien		{ "132x25",		SW_TEXT_132x25 },
27590282Sobrien		{ "132x30",		SW_TEXT_132x30 },
27690282Sobrien		{ "132x43",		SW_TEXT_132x43 },
27790282Sobrien		{ "132x50",		SW_TEXT_132x50 },
27890282Sobrien		{ "132x60",		SW_TEXT_132x60 },
27990282Sobrien		{ "VGA_40x25",		SW_VGA_C40x25 },
28090282Sobrien		{ "VGA_80x25",		SW_VGA_C80x25 },
28190282Sobrien		{ "VGA_80x30",		SW_VGA_C80x30 },
28290282Sobrien		{ "VGA_80x50",		SW_VGA_C80x50 },
28390282Sobrien		{ "VGA_80x60",		SW_VGA_C80x60 },
28490282Sobrien#ifdef SW_VGA_C90x25
28590282Sobrien		{ "VGA_90x25",		SW_VGA_C90x25 },
28690282Sobrien		{ "VGA_90x30",		SW_VGA_C90x30 },
28790282Sobrien		{ "VGA_90x43",		SW_VGA_C90x43 },
28890282Sobrien		{ "VGA_90x50",		SW_VGA_C90x50 },
28990282Sobrien		{ "VGA_90x60",		SW_VGA_C90x60 },
29090282Sobrien#endif
29190282Sobrien		{ "VGA_320x200",	SW_VGA_CG320 },
29290282Sobrien		{ "EGA_80x25",		SW_ENH_C80x25 },
29390282Sobrien		{ "EGA_80x43",		SW_ENH_C80x43 },
29490282Sobrien		{ "VESA_132x25",	SW_VESA_C132x25 },
29590282Sobrien		{ "VESA_132x43",	SW_VESA_C132x43 },
29690282Sobrien		{ "VESA_132x50",	SW_VESA_C132x50 },
29790282Sobrien		{ "VESA_132x60",	SW_VESA_C132x60 },
29890282Sobrien		{ "VESA_800x600",	SW_VESA_800x600 },
29990282Sobrien		{ NULL },
30090282Sobrien	};
30190282Sobrien	unsigned long mode = 0;
30290282Sobrien	int cur_mode;
30390282Sobrien	int ioerr;
30490282Sobrien	int size[3];
30590282Sobrien	int i;
30690282Sobrien
30790282Sobrien	if (ioctl(0, CONS_GET, &cur_mode) < 0)
30890282Sobrien		err(1, "cannot get the current video mode");
30990282Sobrien	if (*index < argc) {
31090282Sobrien		for (i = 0; modes[i].name != NULL; ++i) {
31190282Sobrien			if (!strcmp(argv[*index], modes[i].name)) {
31290282Sobrien				mode = modes[i].mode;
31390282Sobrien				break;
31490282Sobrien			}
31590282Sobrien		}
31690282Sobrien		if (modes[i].name == NULL)
31790282Sobrien			return;
31890282Sobrien		if (ioctl(0, mode, NULL) < 0)
31990282Sobrien			warn("cannot set videomode");
32090282Sobrien		if (mode == SW_VESA_800x600) {
32190282Sobrien			size[0] = 80;	/* columns */
32290282Sobrien			size[1] = 25;	/* rows */
32390282Sobrien			size[2] = 16;	/* font size */
32490282Sobrien			if (ioctl(0, KDRASTER, size)) {
32590282Sobrien				ioerr = errno;
32690282Sobrien				if (cur_mode >= M_VESA_BASE)
32752558Sobrien					ioctl(0, _IO('V', cur_mode), NULL);
32818334Speter				else
32918334Speter					ioctl(0, _IO('S', cur_mode), NULL);
33018334Speter				warnc(ioerr, "cannot activate raster display");
33118334Speter			}
33218334Speter		}
33318334Speter		(*index)++;
33418334Speter	}
33518334Speter	return;
33618334Speter}
33718334Speter
33818334Speterint
33918334Speterget_color_number(char *color)
34018334Speter{
34118334Speter	int i;
34218334Speter
34318334Speter	for (i=0; i<16; i++)
34418334Speter		if (!strcmp(color, legal_colors[i]))
34518334Speter			return i;
34618334Speter	return -1;
34718334Speter}
34818334Speter
34918334Spetervoid
35018334Speterset_normal_colors(int argc, char **argv, int *index)
35118334Speter{
35218334Speter	int color;
35318334Speter
35418334Speter	if (*index < argc && (color = get_color_number(argv[*index])) != -1) {
35518334Speter		(*index)++;
35618334Speter		fprintf(stderr, "[=%dF", color);
35718334Speter		if (*index < argc
35818334Speter		    && (color = get_color_number(argv[*index])) != -1
35918334Speter		    && color < 8) {
36018334Speter			(*index)++;
36150615Sobrien			fprintf(stderr, "[=%dG", color);
36250615Sobrien		}
36350615Sobrien	}
36450615Sobrien}
36550615Sobrien
36650615Sobrienvoid
36750615Sobrienset_reverse_colors(int argc, char **argv, int *index)
36890282Sobrien{
36990282Sobrien	int color;
37018334Speter
37190282Sobrien	if ((color = get_color_number(argv[*(index)-1])) != -1) {
37290282Sobrien		fprintf(stderr, "[=%dH", color);
37390282Sobrien		if (*index < argc
37418334Speter		    && (color = get_color_number(argv[*index])) != -1
37590282Sobrien		    && color < 8) {
37690282Sobrien			(*index)++;
37790282Sobrien			fprintf(stderr, "[=%dI", color);
37890282Sobrien		}
37950615Sobrien	}
38050615Sobrien}
38150615Sobrien
38250615Sobrienvoid
38350615Sobrienset_console(char *arg)
38450615Sobrien{
38550615Sobrien	int n;
38618334Speter
38790282Sobrien	if( !arg || strspn(arg,"0123456789") != strlen(arg)) {
38818334Speter		warnx("bad console number");
38918334Speter		return;
39018334Speter	}
39152558Sobrien
39290282Sobrien	n = atoi(arg);
39352558Sobrien	if (n < 1 || n > 16) {
39418334Speter		warnx("console number out of range");
39552558Sobrien	} else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1)
39652558Sobrien		warn("ioctl(VT_ACTIVATE)");
39718334Speter}
39818334Speter
39918334Spetervoid
40090282Sobrienset_border_color(char *arg)
40118334Speter{
40290282Sobrien	int color;
40390282Sobrien
40490282Sobrien	if ((color = get_color_number(arg)) != -1) {
40590282Sobrien		fprintf(stderr, "[=%dA", color);
40618334Speter	}
40718334Speter	else
40818334Speter		usage();
40918334Speter}
41050615Sobrien
41150615Sobrienvoid
41250615Sobrienset_mouse_char(char *arg)
41350615Sobrien{
41450615Sobrien	struct mouse_info mouse;
41550615Sobrien	long l;
41650615Sobrien
41750615Sobrien	l = strtol(arg, NULL, 0);
41850615Sobrien	if ((l < 0) || (l > UCHAR_MAX)) {
41950615Sobrien		warnx("argument to -M must be 0 through %d", UCHAR_MAX);
42050615Sobrien		return;
42150615Sobrien	}
42290282Sobrien	mouse.operation = MOUSE_MOUSECHAR;
42390282Sobrien	mouse.u.mouse_char = (int)l;
42490282Sobrien	ioctl(0, CONS_MOUSECTL, &mouse);
42590282Sobrien}
42690282Sobrien
42790282Sobrienvoid
42890282Sobrienset_mouse(char *arg)
42990282Sobrien{
43090282Sobrien	struct mouse_info mouse;
43118334Speter
43218334Speter	if (!strcmp(arg, "on"))
43318334Speter		mouse.operation = MOUSE_SHOW;
43418334Speter	else if (!strcmp(arg, "off"))
43518334Speter		mouse.operation = MOUSE_HIDE;
43618334Speter	else {
43718334Speter		warnx("argument to -m must either on or off");
43818334Speter		return;
43918334Speter	}
44018334Speter	ioctl(0, CONS_MOUSECTL, &mouse);
44190282Sobrien}
44218334Speter
44390282Sobrienstatic char
44418334Speter*adapter_name(int type)
44590282Sobrien{
44618334Speter    static struct {
44790282Sobrien	int type;
44890282Sobrien	char *name;
44990282Sobrien    } names[] = {
45090282Sobrien	{ KD_MONO,	"MDA" },
45190282Sobrien	{ KD_HERCULES,	"Hercules" },
45290282Sobrien	{ KD_CGA,	"CGA" },
45390282Sobrien	{ KD_EGA,	"EGA" },
45490282Sobrien	{ KD_VGA,	"VGA" },
45590282Sobrien	{ KD_PC98,	"PC-98xx" },
45690282Sobrien	{ KD_TGA,	"TGA" },
45790282Sobrien	{ -1,		"Unknown" },
45818334Speter    };
45918334Speter    int i;
46018334Speter
46118334Speter    for (i = 0; names[i].type != -1; ++i)
46218334Speter	if (names[i].type == type)
46318334Speter	    break;
46418334Speter    return names[i].name;
46518334Speter}
46618334Speter
46718334Spetervoid
46818334Spetershow_adapter_info(void)
46918334Speter{
47018334Speter	struct video_adapter_info ad;
47118334Speter
47218334Speter	ad.va_index = 0;
47318334Speter	if (ioctl(0, CONS_ADPINFO, &ad)) {
47418334Speter		warn("failed to obtain adapter information");
47518334Speter		return;
47618334Speter	}
47718334Speter
47818334Speter	printf("fb%d:\n", ad.va_index);
47918334Speter	printf("    %.*s%d, type:%s%s (%d), flags:0x%x\n",
48018334Speter	       (int)sizeof(ad.va_name), ad.va_name, ad.va_unit,
48118334Speter	       (ad.va_flags & V_ADP_VESA) ? "VESA " : "",
48218334Speter	       adapter_name(ad.va_type), ad.va_type, ad.va_flags);
48318334Speter	printf("    initial mode:%d, current mode:%d, BIOS mode:%d\n",
48418334Speter	       ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode);
48518334Speter	printf("    frame buffer window:0x%x, buffer size:0x%x\n",
48618334Speter	       ad.va_window, ad.va_buffer_size);
48718334Speter	printf("    window size:0x%x, origin:0x%x\n",
48818334Speter	       ad.va_window_size, ad.va_window_orig);
48918334Speter	printf("    display start address (%d, %d), scan line width:%d\n",
49018334Speter	       ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width);
49118334Speter	printf("    reserved:0x%x\n", ad.va_unused0);
49218334Speter}
49318334Speter
49418334Spetervoid
49518334Spetershow_mode_info(void)
49618334Speter{
49718334Speter	struct video_info info;
49818334Speter	char buf[80];
49918334Speter	int mode;
50018334Speter	int c;
50118334Speter
50218334Speter	printf("    mode#     flags   type    size       "
50318334Speter	       "font      window      linear buffer\n");
50418334Speter	printf("---------------------------------------"
50518334Speter	       "---------------------------------------\n");
50618334Speter	for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) {
50718334Speter		info.vi_mode = mode;
50818334Speter		if (ioctl(0, CONS_MODEINFO, &info))
50918334Speter			continue;
51018334Speter		if (info.vi_mode != mode)
51118334Speter			continue;
51218334Speter
51318334Speter		printf("%3d (0x%03x)", mode, mode);
51418334Speter    		printf(" 0x%08x", info.vi_flags);
51518334Speter		if (info.vi_flags & V_INFO_GRAPHICS) {
51618334Speter			c = 'G';
51718334Speter			snprintf(buf, sizeof(buf), "%dx%dx%d %d",
51818334Speter				 info.vi_width, info.vi_height,
51918334Speter				 info.vi_depth, info.vi_planes);
52018334Speter		} else {
52118334Speter			c = 'T';
52218334Speter			snprintf(buf, sizeof(buf), "%dx%d",
52318334Speter				 info.vi_width, info.vi_height);
52418334Speter		}
52518334Speter		printf(" %c %-15s", c, buf);
52618334Speter		snprintf(buf, sizeof(buf), "%dx%d",
52718334Speter			 info.vi_cwidth, info.vi_cheight);
52818334Speter		printf(" %-5s", buf);
52918334Speter    		printf(" 0x%05x %2dk %2dk",
53018334Speter		       info.vi_window, (int)info.vi_window_size/1024,
53118334Speter		       (int)info.vi_window_gran/1024);
53218334Speter    		printf(" 0x%08x %dk\n",
53318334Speter		       info.vi_buffer, (int)info.vi_buffer_size/1024);
53418334Speter	}
53518334Speter}
53618334Speter
53718334Spetervoid
53818334Spetershow_info(char *arg)
53918334Speter{
54018334Speter	if (!strcmp(arg, "adapter"))
54118334Speter		show_adapter_info();
54218334Speter	else if (!strcmp(arg, "mode"))
54318334Speter		show_mode_info();
54418334Speter	else {
54518334Speter		warnx("argument to -i must either adapter or mode");
54690282Sobrien		return;
54790282Sobrien	}
54890282Sobrien}
54990282Sobrien
55050615Sobrienvoid
55190282Sobrientest_frame()
55250615Sobrien{
55350615Sobrien	int i;
55450615Sobrien
55550615Sobrien	fprintf(stdout, "[=0G\n\n");
55690282Sobrien	for (i=0; i<8; i++) {
55750615Sobrien		fprintf(stdout, "[=15F[=0G        %2d [=%dF%-16s"
55850615Sobrien				"[=15F[=0G        %2d [=%dF%-16s        "
55950615Sobrien				"[=15F %2d [=%dGBACKGROUND[=0G\n",
56050615Sobrien			i, i, legal_colors[i], i+8, i+8,
56150615Sobrien			legal_colors[i+8], i, i);
56250615Sobrien	}
56350615Sobrien	fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n",
56450615Sobrien		info.mv_norm.fore, info.mv_norm.back,
56518334Speter		info.mv_rev.fore, info.mv_rev.back);
56618334Speter}
56718334Speter
56818334Speterint
56918334Spetermain(int argc, char **argv)
57018334Speter{
57118334Speter	int		opt;
57218334Speter
57318334Speter
57418334Speter	info.size = sizeof(info);
57518334Speter	if (ioctl(0, CONS_GETINFO, &info) < 0)
57618334Speter		err(1, "must be on a virtual console");
57718334Speter	while((opt = getopt(argc, argv, "b:c:df:i:l:LM:m:r:s:t:x")) != -1)
57818334Speter		switch(opt) {
57918334Speter			case 'b':
58018334Speter				set_border_color(optarg);
58150615Sobrien				break;
58250615Sobrien			case 'c':
58350615Sobrien				set_cursor_type(optarg);
58450615Sobrien				break;
58550615Sobrien			case 'd':
58652558Sobrien				print_scrnmap();
58790282Sobrien				break;
58852558Sobrien			case 'f':
58952558Sobrien				load_font(optarg,
59018334Speter					nextarg(argc, argv, &optind, 'f'));
59118334Speter				break;
59218334Speter			case 'i':
59318334Speter				show_info(optarg);
59490282Sobrien				break;
59518334Speter			case 'l':
59690282Sobrien				load_scrnmap(optarg);
59718334Speter				break;
59852558Sobrien			case 'L':
59990282Sobrien				load_default_scrnmap();
60052558Sobrien				break;
60152558Sobrien			case 'M':
60252558Sobrien				set_mouse_char(optarg);
60390282Sobrien				break;
60490282Sobrien			case 'm':
60590282Sobrien				set_mouse(optarg);
60690282Sobrien				break;
60790282Sobrien			case 'r':
60890282Sobrien				set_reverse_colors(argc, argv, &optind);
60990282Sobrien				break;
61090282Sobrien			case 's':
61190282Sobrien				set_console(optarg);
61290282Sobrien				break;
61390282Sobrien			case 't':
61490282Sobrien				set_screensaver_timeout(optarg);
61590282Sobrien				break;
61652558Sobrien			case 'x':
61752558Sobrien				hex = 1;
61890282Sobrien				break;
61952558Sobrien			default:
62052558Sobrien				usage();
62152558Sobrien		}
62218334Speter	video_mode(argc, argv, &optind);
62318334Speter	set_normal_colors(argc, argv, &optind);
62418334Speter	if (optind < argc && !strcmp(argv[optind], "show")) {
62518334Speter		test_frame();
62652558Sobrien		optind++;
62718334Speter	}
62818334Speter	if ((optind != argc) || (argc == 1))
62918334Speter		usage();
63052558Sobrien	return 0;
63152558Sobrien}
63252558Sobrien
63352558Sobrien