Deleted Added
full compact
vidcontrol.c (146241) vidcontrol.c (146736)
1/*-
2 * Copyright (c) 1994-1996 S�ren Schmidt
3 * All rights reserved.
4 *
1/*-
2 * Copyright (c) 1994-1996 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Portions of this software are based in part on the work of
6 * Sascha Wildner <saw@online.de> contributed to The DragonFly Project
7 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the

--- 6 unchanged lines hidden (view full) ---

19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer,
13 * in this position and unchanged.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the

--- 6 unchanged lines hidden (view full) ---

22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $DragonFly: src/usr.sbin/vidcontrol/vidcontrol.c,v 1.10 2005/03/02 06:08:29 joerg Exp $
27 */
28
29#ifndef lint
30static const char rcsid[] =
32 */
33
34#ifndef lint
35static const char rcsid[] =
31 "$FreeBSD: head/usr.sbin/vidcontrol/vidcontrol.c 146241 2005-05-15 09:43:14Z nyan $";
36 "$FreeBSD: head/usr.sbin/vidcontrol/vidcontrol.c 146736 2005-05-29 08:43:44Z delphij $";
32#endif /* not lint */
33
34#include <ctype.h>
35#include <err.h>
36#include <limits.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41#include <sys/fbio.h>
42#include <sys/consio.h>
43#include <sys/errno.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include "path.h"
47#include "decode.h"
48
37#endif /* not lint */
38
39#include <ctype.h>
40#include <err.h>
41#include <limits.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46#include <sys/fbio.h>
47#include <sys/consio.h>
48#include <sys/errno.h>
49#include <sys/types.h>
50#include <sys/stat.h>
51#include "path.h"
52#include "decode.h"
53
49#define _VESA_800x600_DFL_COLS 80
50#define _VESA_800x600_DFL_ROWS 25
51#define _VESA_800x600_DFL_FNSZ 16
52
54
55#define DATASIZE(x) ((x).w * (x).h * 256 / 8)
56
53/* Screen dump modes */
54#define DUMP_FMT_RAW 1
55#define DUMP_FMT_TXT 2
56/* Screen dump options */
57#define DUMP_FBF 0
58#define DUMP_ALL 1
59/* Screen dump file format revision */
60#define DUMP_FMT_REV 1
61
62char legal_colors[16][16] = {
63 "black", "blue", "green", "cyan",
64 "red", "magenta", "brown", "white",
65 "grey", "lightblue", "lightgreen", "lightcyan",
66 "lightred", "lightmagenta", "yellow", "lightwhite"
67};
57/* Screen dump modes */
58#define DUMP_FMT_RAW 1
59#define DUMP_FMT_TXT 2
60/* Screen dump options */
61#define DUMP_FBF 0
62#define DUMP_ALL 1
63/* Screen dump file format revision */
64#define DUMP_FMT_REV 1
65
66char legal_colors[16][16] = {
67 "black", "blue", "green", "cyan",
68 "red", "magenta", "brown", "white",
69 "grey", "lightblue", "lightgreen", "lightcyan",
70 "lightred", "lightmagenta", "yellow", "lightwhite"
71};
68int hex = 0;
69int number;
70int vesa_cols = _VESA_800x600_DFL_COLS;
71int vesa_rows = _VESA_800x600_DFL_ROWS;
72char letter;
73struct vid_info info;
74
72
73struct {
74 int active_vty;
75 vid_info_t console_info;
76 unsigned char screen_map[256];
77 int video_mode_number;
78 struct video_info video_mode_info;
79} cur_info;
75
80
81int hex = 0;
82int number;
83int vesa_cols;
84int vesa_rows;
85int font_height;
86int colors_changed;
87int video_mode_changed;
88int normal_fore_color, normal_back_color;
89int revers_fore_color, revers_back_color;
90char letter;
91struct vid_info info;
92struct video_info new_mode_info;
93
94
95/*
96 * Initialize revert data.
97 *
98 * NOTE: the following parameters are not yet saved/restored:
99 *
100 * screen saver timeout
101 * cursor type
102 * mouse character and mouse show/hide state
103 * vty switching on/off state
104 * history buffer size
105 * history contents
106 * font maps
107 */
108
76static void
109static void
110init(void)
111{
112 if (ioctl(0, VT_GETACTIVE, &cur_info.active_vty) == -1)
113 errc(1, errno, "getting active vty");
114
115 cur_info.console_info.size = sizeof(cur_info.console_info);
116
117 if (ioctl(0, CONS_GETINFO, &cur_info.console_info) == -1)
118 errc(1, errno, "getting console information");
119
120 if (ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) == -1)
121 errc(1, errno, "getting screen map");
122
123 if (ioctl(0, CONS_GET, &cur_info.video_mode_number) == -1)
124 errc(1, errno, "getting video mode number");
125
126 cur_info.video_mode_info.vi_mode = cur_info.video_mode_number;
127
128 if (ioctl(0, CONS_MODEINFO, &cur_info.video_mode_info) == -1)
129 errc(1, errno, "getting video mode parameters");
130
131 normal_fore_color = cur_info.console_info.mv_norm.fore;
132 normal_back_color = cur_info.console_info.mv_norm.back;
133 revers_fore_color = cur_info.console_info.mv_rev.fore;
134 revers_back_color = cur_info.console_info.mv_rev.back;
135}
136
137
138/*
139 * If something goes wrong along the way we call revert() to go back to the
140 * console state we came from (which is assumed to be working).
141 *
142 * NOTE: please also read the comments of init().
143 */
144
145static void
146revert(void)
147{
148 int size[3];
149
150 ioctl(0, VT_ACTIVATE, (caddr_t) (long) cur_info.active_vty);
151
152 fprintf(stderr, "\033[=%dA", cur_info.console_info.mv_ovscan);
153 fprintf(stderr, "\033[=%dF", cur_info.console_info.mv_norm.fore);
154 fprintf(stderr, "\033[=%dG", cur_info.console_info.mv_norm.back);
155 fprintf(stderr, "\033[=%dH", cur_info.console_info.mv_rev.fore);
156 fprintf(stderr, "\033[=%dI", cur_info.console_info.mv_rev.back);
157
158 ioctl(0, PIO_SCRNMAP, &cur_info.screen_map);
159
160 if (cur_info.video_mode_number >= M_VESA_BASE)
161 ioctl(0, _IO('V', cur_info.video_mode_number - M_VESA_BASE),
162 NULL);
163 else
164 ioctl(0, _IO('S', cur_info.video_mode_number), NULL);
165
166 if (cur_info.video_mode_info.vi_flags & V_INFO_GRAPHICS) {
167 size[0] = cur_info.video_mode_info.vi_width / 8;
168 size[1] = cur_info.video_mode_info.vi_height /
169 cur_info.console_info.font_size;
170 size[2] = cur_info.console_info.font_size;
171
172 ioctl(0, KDRASTER, size);
173 }
174}
175
176
177/*
178 * Print a short usage string describing all options, then exit.
179 */
180
181static void
77usage(void)
78{
79 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
80"usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]",
81" [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]",
82" [-M char] [-m on | off] [-r foreground background]",
83" [-S on | off] [-s number] [-t N | off] [mode]",
84" [foreground [background]] [show]");
85 exit(1);
86}
87
182usage(void)
183{
184 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
185"usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]",
186" [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]",
187" [-M char] [-m on | off] [-r foreground background]",
188" [-S on | off] [-s number] [-t N | off] [mode]",
189" [foreground [background]] [show]");
190 exit(1);
191}
192
193
194/*
195 * Retrieve the next argument from the command line (for options that require
196 * more than one argument).
197 */
198
88static char *
89nextarg(int ac, char **av, int *indp, int oc, int strict)
90{
91 if (*indp < ac)
92 return(av[(*indp)++]);
199static char *
200nextarg(int ac, char **av, int *indp, int oc, int strict)
201{
202 if (*indp < ac)
203 return(av[(*indp)++]);
93 if (strict != 0)
204
205 if (strict != 0) {
206 revert();
94 errx(1, "option requires two arguments -- %c", oc);
207 errx(1, "option requires two arguments -- %c", oc);
208 }
209
95 return(NULL);
96}
97
210 return(NULL);
211}
212
213
214/*
215 * Guess which file to open. Try to open each combination of a specified set
216 * of file name components.
217 */
218
98static FILE *
99openguess(const char *a[], const char *b[], const char *c[], const char *d[], char **name)
100{
101 FILE *f;
102 int i, j, k, l;
103
104 for (i = 0; a[i] != NULL; i++) {
105 for (j = 0; b[j] != NULL; j++) {
106 for (k = 0; c[k] != NULL; k++) {
107 for (l = 0; d[l] != NULL; l++) {
219static FILE *
220openguess(const char *a[], const char *b[], const char *c[], const char *d[], char **name)
221{
222 FILE *f;
223 int i, j, k, l;
224
225 for (i = 0; a[i] != NULL; i++) {
226 for (j = 0; b[j] != NULL; j++) {
227 for (k = 0; c[k] != NULL; k++) {
228 for (l = 0; d[l] != NULL; l++) {
108 asprintf(name, "%s%s%s%s", a[i], b[j],
109 c[k], d[l]);
229 asprintf(name, "%s%s%s%s",
230 a[i], b[j], c[k], d[l]);
231
110 f = fopen(*name, "r");
232 f = fopen(*name, "r");
233
111 if (f != NULL)
112 return (f);
234 if (f != NULL)
235 return (f);
236
113 free(*name);
114 }
115 }
116 }
117 }
118 return (NULL);
119}
120
237 free(*name);
238 }
239 }
240 }
241 }
242 return (NULL);
243}
244
245
246/*
247 * Load a screenmap from a file and set it.
248 */
249
121static void
122load_scrnmap(const char *filename)
123{
124 FILE *fd;
125 int size;
126 char *name;
127 scrmap_t scrnmap;
128 const char *a[] = {"", SCRNMAP_PATH, NULL};
129 const char *b[] = {filename, NULL};
130 const char *c[] = {"", ".scm", NULL};
131 const char *d[] = {"", NULL};
132
133 fd = openguess(a, b, c, d, &name);
250static void
251load_scrnmap(const char *filename)
252{
253 FILE *fd;
254 int size;
255 char *name;
256 scrmap_t scrnmap;
257 const char *a[] = {"", SCRNMAP_PATH, NULL};
258 const char *b[] = {filename, NULL};
259 const char *c[] = {"", ".scm", NULL};
260 const char *d[] = {"", NULL};
261
262 fd = openguess(a, b, c, d, &name);
263
134 if (fd == NULL) {
264 if (fd == NULL) {
135 warn("screenmap file not found");
136 return;
265 revert();
266 errx(1, "screenmap file not found");
137 }
267 }
268
138 size = sizeof(scrnmap);
269 size = sizeof(scrnmap);
270
139 if (decode(fd, (char *)&scrnmap, size) != size) {
140 rewind(fd);
271 if (decode(fd, (char *)&scrnmap, size) != size) {
272 rewind(fd);
141 if (fread(&scrnmap, 1, size, fd) != (unsigned)size) {
273
274 if (fread(&scrnmap, 1, size, fd) != (size_t)size) {
142 warnx("bad screenmap file");
143 fclose(fd);
275 warnx("bad screenmap file");
276 fclose(fd);
144 return;
277 revert();
278 errx(1, "bad screenmap file");
145 }
146 }
279 }
280 }
147 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0)
148 warn("can't load screenmap");
281
282 if (ioctl(0, PIO_SCRNMAP, &scrnmap) == -1) {
283 revert();
284 errc(1, errno, "loading screenmap");
285 }
286
149 fclose(fd);
150}
151
287 fclose(fd);
288}
289
290
291/*
292 * Set the default screenmap.
293 */
294
152static void
153load_default_scrnmap(void)
154{
155 scrmap_t scrnmap;
156 int i;
157
158 for (i=0; i<256; i++)
159 *((char*)&scrnmap + i) = i;
295static void
296load_default_scrnmap(void)
297{
298 scrmap_t scrnmap;
299 int i;
300
301 for (i=0; i<256; i++)
302 *((char*)&scrnmap + i) = i;
160 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0)
161 warn("can't load default screenmap");
303
304 if (ioctl(0, PIO_SCRNMAP, &scrnmap) == -1) {
305 revert();
306 errc(1, errno, "loading default screenmap");
307 }
162}
163
308}
309
310
311/*
312 * Print the current screenmap to stdout.
313 */
314
164static void
165print_scrnmap(void)
166{
167 unsigned char map[256];
168 size_t i;
169
315static void
316print_scrnmap(void)
317{
318 unsigned char map[256];
319 size_t i;
320
170 if (ioctl(0, GIO_SCRNMAP, &map) < 0) {
171 warn("getting screenmap");
172 return;
321 if (ioctl(0, GIO_SCRNMAP, &map) == -1) {
322 revert();
323 errc(1, errno, "getting screenmap");
173 }
174 for (i=0; i<sizeof(map); i++) {
175 if (i != 0 && i % 16 == 0)
176 fprintf(stdout, "\n");
324 }
325 for (i=0; i<sizeof(map); i++) {
326 if (i != 0 && i % 16 == 0)
327 fprintf(stdout, "\n");
177 if (hex)
328
329 if (hex != 0)
178 fprintf(stdout, " %02x", map[i]);
179 else
180 fprintf(stdout, " %03d", map[i]);
181 }
182 fprintf(stdout, "\n");
183
184}
185
330 fprintf(stdout, " %02x", map[i]);
331 else
332 fprintf(stdout, " %03d", map[i]);
333 }
334 fprintf(stdout, "\n");
335
336}
337
338
339/*
340 * Determine a file's size.
341 */
342
186static int
187fsize(FILE *file)
188{
189 struct stat sb;
190
191 if (fstat(fileno(file), &sb) == 0)
192 return sb.st_size;
193 else
194 return -1;
195}
196
343static int
344fsize(FILE *file)
345{
346 struct stat sb;
347
348 if (fstat(fileno(file), &sb) == 0)
349 return sb.st_size;
350 else
351 return -1;
352}
353
197#define DATASIZE(x) ((x).w * (x).h * 256 / 8)
198
354
355/*
356 * Load a font from file and set it.
357 */
358
199static void
200load_font(const char *type, const char *filename)
201{
202 FILE *fd;
203 int h, i, size, w;
204 unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */
205 char *name, *fontmap, size_sufx[6];
206 const char *a[] = {"", FONT_PATH, NULL};

--- 8 unchanged lines hidden (view full) ---

215 unsigned long io;
216 } sizes[] = {{8, 16, PIO_FONT8x16},
217 {8, 14, PIO_FONT8x14},
218 {8, 8, PIO_FONT8x8},
219 {0, 0, 0}};
220
221 _info.size = sizeof(_info);
222 if (ioctl(0, CONS_GETINFO, &_info) == -1) {
359static void
360load_font(const char *type, const char *filename)
361{
362 FILE *fd;
363 int h, i, size, w;
364 unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */
365 char *name, *fontmap, size_sufx[6];
366 const char *a[] = {"", FONT_PATH, NULL};

--- 8 unchanged lines hidden (view full) ---

375 unsigned long io;
376 } sizes[] = {{8, 16, PIO_FONT8x16},
377 {8, 14, PIO_FONT8x14},
378 {8, 8, PIO_FONT8x8},
379 {0, 0, 0}};
380
381 _info.size = sizeof(_info);
382 if (ioctl(0, CONS_GETINFO, &_info) == -1) {
383 revert();
223 warn("failed to obtain current video mode parameters");
224 return;
225 }
384 warn("failed to obtain current video mode parameters");
385 return;
386 }
387
226 snprintf(size_sufx, sizeof(size_sufx), "-8x%d", _info.font_size);
227 fd = openguess(a, b, c, d, &name);
388 snprintf(size_sufx, sizeof(size_sufx), "-8x%d", _info.font_size);
389 fd = openguess(a, b, c, d, &name);
390
228 if (fd == NULL) {
391 if (fd == NULL) {
229 warn("%s: can't load font file", filename);
230 return;
392 revert();
393 errx(1, "%s: can't load font file", filename);
231 }
394 }
395
232 if (type != NULL) {
233 size = 0;
396 if (type != NULL) {
397 size = 0;
234 if (sscanf(type, "%dx%d", &w, &h) == 2)
235 for (i = 0; sizes[i].w != 0; i++)
398 if (sscanf(type, "%dx%d", &w, &h) == 2) {
399 for (i = 0; sizes[i].w != 0; i++) {
236 if (sizes[i].w == w && sizes[i].h == h) {
237 size = DATASIZE(sizes[i]);
238 io = sizes[i].io;
400 if (sizes[i].w == w && sizes[i].h == h) {
401 size = DATASIZE(sizes[i]);
402 io = sizes[i].io;
403 font_height = sizes[i].h;
239 }
404 }
240
405 }
406 }
241 if (size == 0) {
407 if (size == 0) {
242 warnx("%s: bad font size specification", type);
243 fclose(fd);
408 fclose(fd);
244 return;
409 revert();
410 errx(1, "%s: bad font size specification", type);
245 }
246 } else {
247 /* Apply heuristics */
411 }
412 } else {
413 /* Apply heuristics */
414
248 int j;
249 int dsize[2];
250
251 size = DATASIZE(sizes[0]);
252 fontmap = (char*) malloc(size);
253 dsize[0] = decode(fd, fontmap, size);
254 dsize[1] = fsize(fd);
255 free(fontmap);
256
257 size = 0;
415 int j;
416 int dsize[2];
417
418 size = DATASIZE(sizes[0]);
419 fontmap = (char*) malloc(size);
420 dsize[0] = decode(fd, fontmap, size);
421 dsize[1] = fsize(fd);
422 free(fontmap);
423
424 size = 0;
258 for (j = 0; j < 2; j++)
259 for (i = 0; sizes[i].w != 0; i++)
425 for (j = 0; j < 2; j++) {
426 for (i = 0; sizes[i].w != 0; i++) {
260 if (DATASIZE(sizes[i]) == dsize[j]) {
261 size = dsize[j];
262 io = sizes[i].io;
427 if (DATASIZE(sizes[i]) == dsize[j]) {
428 size = dsize[j];
429 io = sizes[i].io;
430 font_height = sizes[i].h;
263 j = 2; /* XXX */
264 break;
265 }
431 j = 2; /* XXX */
432 break;
433 }
434 }
435 }
266
267 if (size == 0) {
436
437 if (size == 0) {
268 warnx("%s: can't guess font size", filename);
269 fclose(fd);
438 fclose(fd);
270 return;
439 revert();
440 errx(1, "%s: can't guess font size", filename);
271 }
441 }
442
272 rewind(fd);
273 }
274
275 fontmap = (char*) malloc(size);
443 rewind(fd);
444 }
445
446 fontmap = (char*) malloc(size);
447
276 if (decode(fd, fontmap, size) != size) {
277 rewind(fd);
448 if (decode(fd, fontmap, size) != size) {
449 rewind(fd);
278 if (fsize(fd) != size || fread(fontmap, 1, size, fd) != (unsigned)size) {
450 if (fsize(fd) != size ||
451 fread(fontmap, 1, size, fd) != (size_t)size) {
279 warnx("%s: bad font file", filename);
280 fclose(fd);
281 free(fontmap);
452 warnx("%s: bad font file", filename);
453 fclose(fd);
454 free(fontmap);
282 return;
455 revert();
456 errx(1, "%s: bad font file", filename);
283 }
284 }
457 }
458 }
285 if (ioctl(0, io, fontmap) < 0)
286 warn("can't load font");
459
460 if (ioctl(0, io, fontmap) == -1) {
461 revert();
462 errc(1, errno, "loading font");
463 }
464
287 fclose(fd);
288 free(fontmap);
289}
290
465 fclose(fd);
466 free(fontmap);
467}
468
469
470/*
471 * Set the timeout for the screensaver.
472 */
473
291static void
292set_screensaver_timeout(char *arg)
293{
294 int nsec;
295
474static void
475set_screensaver_timeout(char *arg)
476{
477 int nsec;
478
296 if (!strcmp(arg, "off"))
479 if (!strcmp(arg, "off")) {
297 nsec = 0;
480 nsec = 0;
298 else {
481 } else {
299 nsec = atoi(arg);
482 nsec = atoi(arg);
483
300 if ((*arg == '\0') || (nsec < 1)) {
484 if ((*arg == '\0') || (nsec < 1)) {
301 warnx("argument must be a positive number");
302 return;
485 revert();
486 errx(1, "argument must be a positive number");
303 }
304 }
487 }
488 }
305 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1)
306 warn("setting screensaver period");
489
490 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) {
491 revert();
492 errc(1, errno, "setting screensaver period");
493 }
307}
308
494}
495
496
497/*
498 * Set the cursor's shape/type.
499 */
500
309static void
310set_cursor_type(char *appearence)
311{
312 int type;
313
314 if (!strcmp(appearence, "normal"))
315 type = 0;
316 else if (!strcmp(appearence, "blink"))
317 type = 1;
318 else if (!strcmp(appearence, "destructive"))
319 type = 3;
320 else {
501static void
502set_cursor_type(char *appearence)
503{
504 int type;
505
506 if (!strcmp(appearence, "normal"))
507 type = 0;
508 else if (!strcmp(appearence, "blink"))
509 type = 1;
510 else if (!strcmp(appearence, "destructive"))
511 type = 3;
512 else {
321 warnx("argument to -c must be normal, blink or destructive");
322 return;
513 revert();
514 errx(1, "argument to -c must be normal, blink or destructive");
323 }
515 }
324 ioctl(0, CONS_CURSORTYPE, &type);
516
517 if (ioctl(0, CONS_CURSORTYPE, &type) == -1) {
518 revert();
519 errc(1, errno, "setting cursor type");
520 }
325}
326
521}
522
523
524/*
525 * Set the video mode.
526 */
527
327static int
528static int
328video_mode(int argc, char **argv, int *_index)
529video_mode(int argc, char **argv, int *mode_index)
329{
330 static struct {
331 const char *name;
332 unsigned long mode;
530{
531 static struct {
532 const char *name;
533 unsigned long mode;
534 unsigned long mode_num;
333 } modes[] = {
535 } modes[] = {
334 { "80x25", SW_TEXT_80x25 },
335 { "80x30", SW_TEXT_80x30 },
336 { "80x43", SW_TEXT_80x43 },
337 { "80x50", SW_TEXT_80x50 },
338 { "80x60", SW_TEXT_80x60 },
339 { "132x25", SW_TEXT_132x25 },
340 { "132x30", SW_TEXT_132x30 },
341 { "132x43", SW_TEXT_132x43 },
342 { "132x50", SW_TEXT_132x50 },
343 { "132x60", SW_TEXT_132x60 },
344 { "VGA_40x25", SW_VGA_C40x25 },
345 { "VGA_80x25", SW_VGA_C80x25 },
346 { "VGA_80x30", SW_VGA_C80x30 },
347 { "VGA_80x50", SW_VGA_C80x50 },
348 { "VGA_80x60", SW_VGA_C80x60 },
536 { "80x25", SW_TEXT_80x25, M_TEXT_80x25 },
537 { "80x30", SW_TEXT_80x30, M_TEXT_80x30 },
538 { "80x43", SW_TEXT_80x43, M_TEXT_80x43 },
539 { "80x50", SW_TEXT_80x50, M_TEXT_80x50 },
540 { "80x60", SW_TEXT_80x60, M_TEXT_80x60 },
541 { "132x25", SW_TEXT_132x25, M_TEXT_132x25 },
542 { "132x30", SW_TEXT_132x30, M_TEXT_132x30 },
543 { "132x43", SW_TEXT_132x43, M_TEXT_132x43 },
544 { "132x50", SW_TEXT_132x50, M_TEXT_132x50 },
545 { "132x60", SW_TEXT_132x60, M_TEXT_132x60 },
546 { "VGA_40x25", SW_VGA_C40x25, M_VGA_C40x25 },
547 { "VGA_80x25", SW_VGA_C80x25, M_VGA_C80x25 },
548 { "VGA_80x30", SW_VGA_C80x30, M_VGA_C80x30 },
549 { "VGA_80x50", SW_VGA_C80x50, M_VGA_C80x50 },
550 { "VGA_80x60", SW_VGA_C80x60, M_VGA_C80x60 },
349#ifdef SW_VGA_C90x25
551#ifdef SW_VGA_C90x25
350 { "VGA_90x25", SW_VGA_C90x25 },
351 { "VGA_90x30", SW_VGA_C90x30 },
352 { "VGA_90x43", SW_VGA_C90x43 },
353 { "VGA_90x50", SW_VGA_C90x50 },
354 { "VGA_90x60", SW_VGA_C90x60 },
552 { "VGA_90x25", SW_VGA_C90x25, M_VGA_C90x25 },
553 { "VGA_90x30", SW_VGA_C90x30, M_VGA_C90x30 },
554 { "VGA_90x43", SW_VGA_C90x43, M_VGA_C90x43 },
555 { "VGA_90x50", SW_VGA_C90x50, M_VGA_C90x50 },
556 { "VGA_90x60", SW_VGA_C90x60, M_VGA_C90x60 },
355#endif
557#endif
356 { "VGA_320x200", SW_VGA_CG320 },
357 { "EGA_80x25", SW_ENH_C80x25 },
358 { "EGA_80x43", SW_ENH_C80x43 },
359 { "VESA_132x25", SW_VESA_C132x25 },
360 { "VESA_132x43", SW_VESA_C132x43 },
361 { "VESA_132x50", SW_VESA_C132x50 },
362 { "VESA_132x60", SW_VESA_C132x60 },
363 { "VESA_800x600", SW_VESA_800x600 },
364 { NULL, 0 },
558 { "VGA_320x200", SW_VGA_CG320, M_CG320 },
559 { "EGA_80x25", SW_ENH_C80x25, M_ENH_C80x25 },
560 { "EGA_80x43", SW_ENH_C80x43, M_ENH_C80x43 },
561 { "VESA_132x25", SW_VESA_C132x25,M_VESA_C132x25 },
562 { "VESA_132x43", SW_VESA_C132x43,M_VESA_C132x43 },
563 { "VESA_132x50", SW_VESA_C132x50,M_VESA_C132x50 },
564 { "VESA_132x60", SW_VESA_C132x60,M_VESA_C132x60 },
565 { "VESA_800x600", SW_VESA_800x600,M_VESA_800x600 },
566 { NULL, 0, 0 },
365 };
567 };
568
569 int new_mode_num = 0;
366 unsigned long mode = 0;
367 int cur_mode;
368 int ioerr;
369 int size[3];
370 int i;
371
372 if (ioctl(0, CONS_GET, &cur_mode) < 0)
373 err(1, "cannot get the current video mode");
570 unsigned long mode = 0;
571 int cur_mode;
572 int ioerr;
573 int size[3];
574 int i;
575
576 if (ioctl(0, CONS_GET, &cur_mode) < 0)
577 err(1, "cannot get the current video mode");
374 if (*_index < argc) {
375 for (i = 0; modes[i].name != NULL; ++i) {
376 if (!strcmp(argv[*_index], modes[i].name)) {
377 mode = modes[i].mode;
378 break;
578
579 /*
580 * Parse the video mode argument...
581 */
582
583 if (*mode_index < argc) {
584 if (!strncmp(argv[*mode_index], "MODE_", 5)) {
585 if (!isdigit(argv[*mode_index][5]))
586 errx(1, "invalid video mode number");
587
588 new_mode_num = atoi(&argv[*mode_index][5]);
589 } else {
590 for (i = 0; modes[i].name != NULL; ++i) {
591 if (!strcmp(argv[*mode_index], modes[i].name)) {
592 mode = modes[i].mode;
593 new_mode_num = modes[i].mode_num;
594 break;
595 }
379 }
596 }
597
598 if (modes[i].name == NULL)
599 return EXIT_FAILURE;
600 if (ioctl(0, mode, NULL) < 0) {
601 warn("cannot set videomode");
602 return EXIT_FAILURE;
603 }
380 }
604 }
381 if (modes[i].name == NULL)
382 return EXIT_FAILURE;
383 if (ioctl(0, mode, NULL) < 0) {
384 warn("cannot set videomode");
385 return EXIT_FAILURE;
605
606 /*
607 * Collect enough information about the new video mode...
608 */
609
610 new_mode_info.vi_mode = new_mode_num;
611
612 if (ioctl(0, CONS_MODEINFO, &new_mode_info) == -1) {
613 revert();
614 errc(1, errno, "obtaining new video mode parameters");
386 }
615 }
387 if (mode == SW_VESA_800x600) {
388 /* columns */
389 if ((vesa_cols * 8 > 800) || (vesa_cols <= 0)) {
390 warnx("incorrect number of columns: %d",
391 vesa_cols);
392 size[0] = _VESA_800x600_DFL_COLS;
616
617 if (mode == 0) {
618 if (new_mode_num >= M_VESA_BASE)
619 mode = _IO('V', new_mode_num - M_VESA_BASE);
620 else
621 mode = _IO('S', new_mode_num);
622 }
623
624 /*
625 * Try setting the new mode.
626 */
627
628 if (ioctl(0, mode, NULL) == -1) {
629 revert();
630 errc(1, errno, "setting video mode");
631 }
632
633 /*
634 * For raster modes it's not enough to just set the mode.
635 * We also need to explicitly set the raster mode.
636 */
637
638 if (new_mode_info.vi_flags & V_INFO_GRAPHICS) {
639 /* font size */
640
641 if (font_height == 0)
642 font_height = cur_info.console_info.font_size;
643
644 size[2] = font_height;
645
646 /* adjust columns */
647
648 if ((vesa_cols * 8 > new_mode_info.vi_width) ||
649 (vesa_cols <= 0)) {
650 size[0] = new_mode_info.vi_width / 8;
393 } else {
394 size[0] = vesa_cols;
395 }
651 } else {
652 size[0] = vesa_cols;
653 }
396 /* rows */
397 if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) ||
398 (vesa_rows <=0)) {
399 warnx("incorrect number of rows: %d",
400 vesa_rows);
401 size[1] = _VESA_800x600_DFL_ROWS;
654
655 /* adjust rows */
656
657 if ((vesa_rows * font_height > new_mode_info.vi_height) ||
658 (vesa_rows <= 0)) {
659 size[1] = new_mode_info.vi_height /
660 font_height;
402 } else {
403 size[1] = vesa_rows;
404 }
661 } else {
662 size[1] = vesa_rows;
663 }
405 /* font size */
406 size[2] = _VESA_800x600_DFL_FNSZ;
664
665 /* set raster mode */
666
407 if (ioctl(0, KDRASTER, size)) {
408 ioerr = errno;
409 if (cur_mode >= M_VESA_BASE)
410 ioctl(0,
411 _IO('V', cur_mode - M_VESA_BASE),
412 NULL);
413 else
414 ioctl(0, _IO('S', cur_mode), NULL);
667 if (ioctl(0, KDRASTER, size)) {
668 ioerr = errno;
669 if (cur_mode >= M_VESA_BASE)
670 ioctl(0,
671 _IO('V', cur_mode - M_VESA_BASE),
672 NULL);
673 else
674 ioctl(0, _IO('S', cur_mode), NULL);
675 revert();
415 warnc(ioerr, "cannot activate raster display");
416 return EXIT_FAILURE;
417 }
418 }
676 warnc(ioerr, "cannot activate raster display");
677 return EXIT_FAILURE;
678 }
679 }
419 (*_index)++;
680
681 video_mode_changed = 1;
682
683 (*mode_index)++;
420 }
421 return EXIT_SUCCESS;
422}
423
684 }
685 return EXIT_SUCCESS;
686}
687
688
689/*
690 * Return the number for a specified color name.
691 */
692
424static int
425get_color_number(char *color)
426{
427 int i;
428
693static int
694get_color_number(char *color)
695{
696 int i;
697
429 for (i=0; i<16; i++)
698 for (i=0; i<16; i++) {
430 if (!strcmp(color, legal_colors[i]))
431 return i;
699 if (!strcmp(color, legal_colors[i]))
700 return i;
701 }
432 return -1;
433}
434
702 return -1;
703}
704
705
706/*
707 * Get normal text and background colors.
708 */
709
435static void
710static void
436set_normal_colors(int argc, char **argv, int *_index)
711get_normal_colors(int argc, char **argv, int *_index)
437{
438 int color;
439
440 if (*_index < argc && (color = get_color_number(argv[*_index])) != -1) {
441 (*_index)++;
442 fprintf(stderr, "\033[=%dF", color);
443 if (*_index < argc
444 && (color = get_color_number(argv[*_index])) != -1
445 && color < 8) {
446 (*_index)++;
447 fprintf(stderr, "\033[=%dG", color);
448 }
449 }
450}
451
712{
713 int color;
714
715 if (*_index < argc && (color = get_color_number(argv[*_index])) != -1) {
716 (*_index)++;
717 fprintf(stderr, "\033[=%dF", color);
718 if (*_index < argc
719 && (color = get_color_number(argv[*_index])) != -1
720 && color < 8) {
721 (*_index)++;
722 fprintf(stderr, "\033[=%dG", color);
723 }
724 }
725}
726
727
728/*
729 * Get reverse text and background colors.
730 */
731
452static void
732static void
453set_reverse_colors(int argc, char **argv, int *_index)
733get_reverse_colors(int argc, char **argv, int *_index)
454{
455 int color;
456
457 if ((color = get_color_number(argv[*(_index)-1])) != -1) {
458 fprintf(stderr, "\033[=%dH", color);
459 if (*_index < argc
460 && (color = get_color_number(argv[*_index])) != -1
461 && color < 8) {
462 (*_index)++;
463 fprintf(stderr, "\033[=%dI", color);
464 }
465 }
466}
467
734{
735 int color;
736
737 if ((color = get_color_number(argv[*(_index)-1])) != -1) {
738 fprintf(stderr, "\033[=%dH", color);
739 if (*_index < argc
740 && (color = get_color_number(argv[*_index])) != -1
741 && color < 8) {
742 (*_index)++;
743 fprintf(stderr, "\033[=%dI", color);
744 }
745 }
746}
747
748
749/*
750 * Set normal and reverse foreground and background colors.
751 */
752
468static void
753static void
754set_colors(void)
755{
756 fprintf(stderr, "\033[=%dF", normal_fore_color);
757 fprintf(stderr, "\033[=%dG", normal_back_color);
758 fprintf(stderr, "\033[=%dH", revers_fore_color);
759 fprintf(stderr, "\033[=%dI", revers_back_color);
760}
761
762
763/*
764 * Switch to virtual terminal #arg.
765 */
766
767static void
469set_console(char *arg)
470{
471 int n;
472
768set_console(char *arg)
769{
770 int n;
771
473 if( !arg || strspn(arg,"0123456789") != strlen(arg)) {
474 warnx("bad console number");
475 return;
772 if(!arg || strspn(arg,"0123456789") != strlen(arg)) {
773 revert();
774 errx(1, "bad console number");
476 }
477
478 n = atoi(arg);
775 }
776
777 n = atoi(arg);
778
479 if (n < 1 || n > 16) {
779 if (n < 1 || n > 16) {
480 warnx("console number out of range");
481 } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1)
482 warn("ioctl(VT_ACTIVATE)");
780 revert();
781 errx(1, "console number out of range");
782 } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) {
783 revert();
784 errc(1, errno, "switching vty");
785 }
483}
484
786}
787
788
789/*
790 * Sets the border color.
791 */
792
485static void
486set_border_color(char *arg)
487{
488 int color;
489
490 if ((color = get_color_number(arg)) != -1) {
491 fprintf(stderr, "\033[=%dA", color);
492 }
493 else
494 usage();
495}
496
497static void
498set_mouse_char(char *arg)
499{
500 struct mouse_info mouse;
501 long l;
502
503 l = strtol(arg, NULL, 0);
793static void
794set_border_color(char *arg)
795{
796 int color;
797
798 if ((color = get_color_number(arg)) != -1) {
799 fprintf(stderr, "\033[=%dA", color);
800 }
801 else
802 usage();
803}
804
805static void
806set_mouse_char(char *arg)
807{
808 struct mouse_info mouse;
809 long l;
810
811 l = strtol(arg, NULL, 0);
812
504 if ((l < 0) || (l > UCHAR_MAX - 3)) {
813 if ((l < 0) || (l > UCHAR_MAX - 3)) {
814 revert();
505 warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3);
506 return;
507 }
815 warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3);
816 return;
817 }
818
508 mouse.operation = MOUSE_MOUSECHAR;
509 mouse.u.mouse_char = (int)l;
819 mouse.operation = MOUSE_MOUSECHAR;
820 mouse.u.mouse_char = (int)l;
510 ioctl(0, CONS_MOUSECTL, &mouse);
821
822 if (ioctl(0, CONS_MOUSECTL, &mouse) == -1) {
823 revert();
824 errc(1, errno, "setting mouse character");
825 }
511}
512
826}
827
828
829/*
830 * Show/hide the mouse.
831 */
832
513static void
514set_mouse(char *arg)
515{
516 struct mouse_info mouse;
517
833static void
834set_mouse(char *arg)
835{
836 struct mouse_info mouse;
837
518 if (!strcmp(arg, "on"))
838 if (!strcmp(arg, "on")) {
519 mouse.operation = MOUSE_SHOW;
839 mouse.operation = MOUSE_SHOW;
520 else if (!strcmp(arg, "off"))
840 } else if (!strcmp(arg, "off")) {
521 mouse.operation = MOUSE_HIDE;
841 mouse.operation = MOUSE_HIDE;
522 else {
523 warnx("argument to -m must be either on or off");
524 return;
842 } else {
843 revert();
844 errx(1, "argument to -m must be either on or off");
525 }
845 }
526 ioctl(0, CONS_MOUSECTL, &mouse);
846
847 if (ioctl(0, CONS_MOUSECTL, &mouse) == -1) {
848 revert();
849 errc(1, errno, "%sing the mouse",
850 mouse.operation == MOUSE_SHOW ? "show" : "hid");
851 }
527}
528
852}
853
854
529static void
530set_lockswitch(char *arg)
531{
532 int data;
533
855static void
856set_lockswitch(char *arg)
857{
858 int data;
859
534 if (!strcmp(arg, "off"))
860 if (!strcmp(arg, "off")) {
535 data = 0x01;
861 data = 0x01;
536 else if (!strcmp(arg, "on"))
862 } else if (!strcmp(arg, "on")) {
537 data = 0x02;
863 data = 0x02;
538 else {
539 warnx("argument to -S must be either on or off");
540 return;
864 } else {
865 revert();
866 errx(1, "argument to -S must be either on or off");
541 }
867 }
542 if (ioctl(0, VT_LOCKSWITCH, &data) == -1)
543 warn("ioctl(VT_LOCKSWITCH)");
868
869 if (ioctl(0, VT_LOCKSWITCH, &data) == -1) {
870 revert();
871 errc(1, errno, "turning %s vty switching",
872 data == 0x01 ? "off" : "on");
873 }
544}
545
874}
875
876
877/*
878 * Return the adapter name for a specified type.
879 */
880
546static const char
547*adapter_name(int type)
548{
549 static struct {
550 int type;
551 const char *name;
552 } names[] = {
553 { KD_MONO, "MDA" },
554 { KD_HERCULES, "Hercules" },
555 { KD_CGA, "CGA" },
556 { KD_EGA, "EGA" },
557 { KD_VGA, "VGA" },
558 { KD_PC98, "PC-98xx" },
559 { KD_TGA, "TGA" },
560 { -1, "Unknown" },
561 };
881static const char
882*adapter_name(int type)
883{
884 static struct {
885 int type;
886 const char *name;
887 } names[] = {
888 { KD_MONO, "MDA" },
889 { KD_HERCULES, "Hercules" },
890 { KD_CGA, "CGA" },
891 { KD_EGA, "EGA" },
892 { KD_VGA, "VGA" },
893 { KD_PC98, "PC-98xx" },
894 { KD_TGA, "TGA" },
895 { -1, "Unknown" },
896 };
897
562 int i;
563
564 for (i = 0; names[i].type != -1; ++i)
565 if (names[i].type == type)
566 break;
567 return names[i].name;
568}
569
898 int i;
899
900 for (i = 0; names[i].type != -1; ++i)
901 if (names[i].type == type)
902 break;
903 return names[i].name;
904}
905
906
907/*
908 * Show graphics adapter information.
909 */
910
570static void
571show_adapter_info(void)
572{
573 struct video_adapter_info ad;
574
575 ad.va_index = 0;
911static void
912show_adapter_info(void)
913{
914 struct video_adapter_info ad;
915
916 ad.va_index = 0;
576 if (ioctl(0, CONS_ADPINFO, &ad)) {
577 warn("failed to obtain adapter information");
578 return;
917
918 if (ioctl(0, CONS_ADPINFO, &ad) == -1) {
919 revert();
920 errc(1, errno, "obtaining adapter information");
579 }
580
581 printf("fb%d:\n", ad.va_index);
582 printf(" %.*s%d, type:%s%s (%d), flags:0x%x\n",
583 (int)sizeof(ad.va_name), ad.va_name, ad.va_unit,
584 (ad.va_flags & V_ADP_VESA) ? "VESA " : "",
585 adapter_name(ad.va_type), ad.va_type, ad.va_flags);
586 printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n",
587 ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode);
588 printf(" frame buffer window:0x%zx, buffer size:0x%zx\n",
589 ad.va_window, ad.va_buffer_size);
590 printf(" window size:0x%zx, origin:0x%x\n",
591 ad.va_window_size, ad.va_window_orig);
592 printf(" display start address (%d, %d), scan line width:%d\n",
593 ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width);
594 printf(" reserved:0x%zx\n", ad.va_unused0);
595}
596
921 }
922
923 printf("fb%d:\n", ad.va_index);
924 printf(" %.*s%d, type:%s%s (%d), flags:0x%x\n",
925 (int)sizeof(ad.va_name), ad.va_name, ad.va_unit,
926 (ad.va_flags & V_ADP_VESA) ? "VESA " : "",
927 adapter_name(ad.va_type), ad.va_type, ad.va_flags);
928 printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n",
929 ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode);
930 printf(" frame buffer window:0x%zx, buffer size:0x%zx\n",
931 ad.va_window, ad.va_buffer_size);
932 printf(" window size:0x%zx, origin:0x%x\n",
933 ad.va_window_size, ad.va_window_orig);
934 printf(" display start address (%d, %d), scan line width:%d\n",
935 ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width);
936 printf(" reserved:0x%zx\n", ad.va_unused0);
937}
938
939
940/*
941 * Show video mode information.
942 */
943
597static void
598show_mode_info(void)
599{
600 struct video_info _info;
601 char buf[80];
602 int mode;
603 int c;
604
605 printf(" mode# flags type size "
606 "font window linear buffer\n");
607 printf("---------------------------------------"
608 "---------------------------------------\n");
944static void
945show_mode_info(void)
946{
947 struct video_info _info;
948 char buf[80];
949 int mode;
950 int c;
951
952 printf(" mode# flags type size "
953 "font window linear buffer\n");
954 printf("---------------------------------------"
955 "---------------------------------------\n");
956
609 for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) {
610 _info.vi_mode = mode;
611 if (ioctl(0, CONS_MODEINFO, &_info))
612 continue;
613 if (_info.vi_mode != mode)
614 continue;
615
616 printf("%3d (0x%03x)", mode, mode);
617 printf(" 0x%08x", _info.vi_flags);
618 if (_info.vi_flags & V_INFO_GRAPHICS) {
619 c = 'G';
957 for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) {
958 _info.vi_mode = mode;
959 if (ioctl(0, CONS_MODEINFO, &_info))
960 continue;
961 if (_info.vi_mode != mode)
962 continue;
963
964 printf("%3d (0x%03x)", mode, mode);
965 printf(" 0x%08x", _info.vi_flags);
966 if (_info.vi_flags & V_INFO_GRAPHICS) {
967 c = 'G';
968
620 snprintf(buf, sizeof(buf), "%dx%dx%d %d",
621 _info.vi_width, _info.vi_height,
622 _info.vi_depth, _info.vi_planes);
623 } else {
624 c = 'T';
969 snprintf(buf, sizeof(buf), "%dx%dx%d %d",
970 _info.vi_width, _info.vi_height,
971 _info.vi_depth, _info.vi_planes);
972 } else {
973 c = 'T';
974
625 snprintf(buf, sizeof(buf), "%dx%d",
626 _info.vi_width, _info.vi_height);
627 }
975 snprintf(buf, sizeof(buf), "%dx%d",
976 _info.vi_width, _info.vi_height);
977 }
978
628 printf(" %c %-15s", c, buf);
629 snprintf(buf, sizeof(buf), "%dx%d",
630 _info.vi_cwidth, _info.vi_cheight);
631 printf(" %-5s", buf);
632 printf(" 0x%05zx %2dk %2dk",
633 _info.vi_window, (int)_info.vi_window_size/1024,
634 (int)_info.vi_window_gran/1024);
635 printf(" 0x%08zx %dk\n",
636 _info.vi_buffer, (int)_info.vi_buffer_size/1024);
637 }
638}
639
979 printf(" %c %-15s", c, buf);
980 snprintf(buf, sizeof(buf), "%dx%d",
981 _info.vi_cwidth, _info.vi_cheight);
982 printf(" %-5s", buf);
983 printf(" 0x%05zx %2dk %2dk",
984 _info.vi_window, (int)_info.vi_window_size/1024,
985 (int)_info.vi_window_gran/1024);
986 printf(" 0x%08zx %dk\n",
987 _info.vi_buffer, (int)_info.vi_buffer_size/1024);
988 }
989}
990
991
640static void
641show_info(char *arg)
642{
992static void
993show_info(char *arg)
994{
643 if (!strcmp(arg, "adapter"))
995 if (!strcmp(arg, "adapter")) {
644 show_adapter_info();
996 show_adapter_info();
645 else if (!strcmp(arg, "mode"))
997 } else if (!strcmp(arg, "mode")) {
646 show_mode_info();
998 show_mode_info();
647 else {
648 warnx("argument to -i must be either adapter or mode");
649 return;
999 } else {
1000 revert();
1001 errx(1, "argument to -i must be either adapter or mode");
650 }
651}
652
1002 }
1003}
1004
1005
653static void
654test_frame(void)
655{
656 int i, cur_mode, fore;
657
658 fore = 15;
659
660 if (ioctl(0, CONS_GET, &cur_mode) < 0)

--- 14 unchanged lines hidden (view full) ---

675 fore, i+8, i+8, legal_colors[i+8],
676 fore, i, i);
677 }
678 fprintf(stdout, "\033[=%dF\033[=%dG\033[=%dH\033[=%dI\n",
679 info.mv_norm.fore, info.mv_norm.back,
680 info.mv_rev.fore, info.mv_rev.back);
681}
682
1006static void
1007test_frame(void)
1008{
1009 int i, cur_mode, fore;
1010
1011 fore = 15;
1012
1013 if (ioctl(0, CONS_GET, &cur_mode) < 0)

--- 14 unchanged lines hidden (view full) ---

1028 fore, i+8, i+8, legal_colors[i+8],
1029 fore, i, i);
1030 }
1031 fprintf(stdout, "\033[=%dF\033[=%dG\033[=%dH\033[=%dI\n",
1032 info.mv_norm.fore, info.mv_norm.back,
1033 info.mv_rev.fore, info.mv_rev.back);
1034}
1035
1036
683/*
684 * Snapshot the video memory of that terminal, using the CONS_SCRSHOT
685 * ioctl, and writes the results to stdout either in the special
686 * binary format (see manual page for details), or in the plain
687 * text format.
688 */
1037/*
1038 * Snapshot the video memory of that terminal, using the CONS_SCRSHOT
1039 * ioctl, and writes the results to stdout either in the special
1040 * binary format (see manual page for details), or in the plain
1041 * text format.
1042 */
1043
689static void
690dump_screen(int mode, int opt)
691{
692 scrshot_t shot;
693 vid_info_t _info;
694
695 _info.size = sizeof(_info);
1044static void
1045dump_screen(int mode, int opt)
1046{
1047 scrshot_t shot;
1048 vid_info_t _info;
1049
1050 _info.size = sizeof(_info);
1051
696 if (ioctl(0, CONS_GETINFO, &_info) == -1) {
1052 if (ioctl(0, CONS_GETINFO, &_info) == -1) {
697 warn("failed to obtain current video mode parameters");
1053 revert();
1054 errc(1, errno, "obtaining current video mode parameters");
698 return;
699 }
700
701 shot.x = shot.y = 0;
702 shot.xsize = _info.mv_csz;
703 shot.ysize = _info.mv_rsz;
704 if (opt == DUMP_ALL)
705 shot.ysize += _info.mv_hsz;
706
707 shot.buf = alloca(shot.xsize * shot.ysize * sizeof(u_int16_t));
708 if (shot.buf == NULL) {
1055 return;
1056 }
1057
1058 shot.x = shot.y = 0;
1059 shot.xsize = _info.mv_csz;
1060 shot.ysize = _info.mv_rsz;
1061 if (opt == DUMP_ALL)
1062 shot.ysize += _info.mv_hsz;
1063
1064 shot.buf = alloca(shot.xsize * shot.ysize * sizeof(u_int16_t));
1065 if (shot.buf == NULL) {
709 warn("failed to allocate memory for dump");
710 return;
1066 revert();
1067 errx(1, "failed to allocate memory for dump");
711 }
712
713 if (ioctl(0, CONS_SCRSHOT, &shot) == -1) {
1068 }
1069
1070 if (ioctl(0, CONS_SCRSHOT, &shot) == -1) {
714 warn("failed to get dump of the screen");
715 return;
1071 revert();
1072 errc(1, errno, "dumping screen");
716 }
717
718 if (mode == DUMP_FMT_RAW) {
719 printf("SCRSHOT_%c%c%c%c", DUMP_FMT_REV, 2,
720 shot.xsize, shot.ysize);
1073 }
1074
1075 if (mode == DUMP_FMT_RAW) {
1076 printf("SCRSHOT_%c%c%c%c", DUMP_FMT_REV, 2,
1077 shot.xsize, shot.ysize);
1078
721 fflush(stdout);
722
1079 fflush(stdout);
1080
723 (void)write(STDOUT_FILENO, shot.buf,
724 shot.xsize * shot.ysize * sizeof(u_int16_t));
1081 write(STDOUT_FILENO, shot.buf,
1082 shot.xsize * shot.ysize * sizeof(u_int16_t));
725 } else {
726 char *line;
727 int x, y;
728 u_int16_t ch;
729
730 line = alloca(shot.xsize + 1);
1083 } else {
1084 char *line;
1085 int x, y;
1086 u_int16_t ch;
1087
1088 line = alloca(shot.xsize + 1);
1089
731 if (line == NULL) {
1090 if (line == NULL) {
732 warn("failed to allocate memory for line buffer");
733 return;
1091 revert();
1092 errx(1, "failed to allocate memory for line buffer");
734 }
735
736 for (y = 0; y < shot.ysize; y++) {
737 for (x = 0; x < shot.xsize; x++) {
738 ch = shot.buf[x + (y * shot.xsize)];
739 ch &= 0xff;
1093 }
1094
1095 for (y = 0; y < shot.ysize; y++) {
1096 for (x = 0; x < shot.xsize; x++) {
1097 ch = shot.buf[x + (y * shot.xsize)];
1098 ch &= 0xff;
1099
740 if (isprint(ch) == 0)
741 ch = ' ';
1100 if (isprint(ch) == 0)
1101 ch = ' ';
1102
742 line[x] = (char)ch;
743 }
744
745 /* Trim trailing spaces */
1103 line[x] = (char)ch;
1104 }
1105
1106 /* Trim trailing spaces */
1107
746 do {
747 line[x--] = '\0';
748 } while (line[x] == ' ' && x != 0);
749
750 puts(line);
751 }
1108 do {
1109 line[x--] = '\0';
1110 } while (line[x] == ' ' && x != 0);
1111
1112 puts(line);
1113 }
1114
752 fflush(stdout);
753 }
1115 fflush(stdout);
1116 }
754
755 return;
756}
757
1117}
1118
1119
1120/*
1121 * Set the console history buffer size.
1122 */
1123
758static void
759set_history(char *opt)
760{
761 int size;
762
763 size = atoi(opt);
1124static void
1125set_history(char *opt)
1126{
1127 int size;
1128
1129 size = atoi(opt);
1130
764 if ((*opt == '\0') || size < 0) {
1131 if ((*opt == '\0') || size < 0) {
765 warnx("argument must be a positive number");
766 return;
1132 revert();
1133 errx(1, "argument must be a positive number");
767 }
1134 }
768 if (ioctl(0, CONS_HISTORY, &size) == -1)
769 warn("setting history buffer size");
1135
1136 if (ioctl(0, CONS_HISTORY, &size) == -1) {
1137 revert();
1138 errc(1, errno, "setting history buffer size");
1139 }
770}
771
1140}
1141
1142
1143/*
1144 * Clear the console history buffer.
1145 */
1146
772static void
773clear_history(void)
774{
1147static void
1148clear_history(void)
1149{
775
776 if (ioctl(0, CONS_CLRHIST) == -1)
777 warn("clear history buffer");
1150 if (ioctl(0, CONS_CLRHIST) == -1) {
1151 revert();
1152 errc(1, errno, "clearing history buffer");
1153 }
778}
779
1154}
1155
1156
780int
781main(int argc, char **argv)
782{
783 char *font, *type;
784 int dumpmod, dumpopt, opt;
785 int reterr;
786
1157int
1158main(int argc, char **argv)
1159{
1160 char *font, *type;
1161 int dumpmod, dumpopt, opt;
1162 int reterr;
1163
1164 init();
1165
787 info.size = sizeof(info);
1166 info.size = sizeof(info);
788 if (argc == 1)
789 usage();
790 /* Not reached */
791 if (ioctl(0, CONS_GETINFO, &info) < 0)
1167
1168 if (ioctl(0, CONS_GETINFO, &info) == -1)
792 err(1, "must be on a virtual console");
793 dumpmod = 0;
794 dumpopt = DUMP_FBF;
795 while((opt = getopt(argc, argv, "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:t:x")) != -1)
796 switch(opt) {
797 case 'b':
798 set_border_color(optarg);
799 break;

--- 4 unchanged lines hidden (view full) ---

804 set_cursor_type(optarg);
805 break;
806 case 'd':
807 print_scrnmap();
808 break;
809 case 'f':
810 type = optarg;
811 font = nextarg(argc, argv, &optind, 'f', 0);
1169 err(1, "must be on a virtual console");
1170 dumpmod = 0;
1171 dumpopt = DUMP_FBF;
1172 while((opt = getopt(argc, argv, "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:t:x")) != -1)
1173 switch(opt) {
1174 case 'b':
1175 set_border_color(optarg);
1176 break;

--- 4 unchanged lines hidden (view full) ---

1181 set_cursor_type(optarg);
1182 break;
1183 case 'd':
1184 print_scrnmap();
1185 break;
1186 case 'f':
1187 type = optarg;
1188 font = nextarg(argc, argv, &optind, 'f', 0);
1189
812 if (font == NULL) {
813 type = NULL;
814 font = optarg;
815 }
1190 if (font == NULL) {
1191 type = NULL;
1192 font = optarg;
1193 }
1194
816 load_font(type, font);
817 break;
818 case 'g':
1195 load_font(type, font);
1196 break;
1197 case 'g':
819 if (sscanf(optarg, "%dx%d", &vesa_cols,
820 &vesa_rows) != 2) {
1198 if (sscanf(optarg, "%dx%d",
1199 &vesa_cols, &vesa_rows) != 2) {
1200 revert();
821 warnx("incorrect geometry: %s", optarg);
822 usage();
823 }
1201 warnx("incorrect geometry: %s", optarg);
1202 usage();
1203 }
824 break;
1204 break;
825 case 'h':
826 set_history(optarg);
827 break;
828 case 'H':
829 dumpopt = DUMP_ALL;
830 break;
831 case 'i':
832 show_info(optarg);

--- 12 unchanged lines hidden (view full) ---

845 break;
846 case 'p':
847 dumpmod = DUMP_FMT_RAW;
848 break;
849 case 'P':
850 dumpmod = DUMP_FMT_TXT;
851 break;
852 case 'r':
1205 case 'h':
1206 set_history(optarg);
1207 break;
1208 case 'H':
1209 dumpopt = DUMP_ALL;
1210 break;
1211 case 'i':
1212 show_info(optarg);

--- 12 unchanged lines hidden (view full) ---

1225 break;
1226 case 'p':
1227 dumpmod = DUMP_FMT_RAW;
1228 break;
1229 case 'P':
1230 dumpmod = DUMP_FMT_TXT;
1231 break;
1232 case 'r':
853 set_reverse_colors(argc, argv, &optind);
1233 get_reverse_colors(argc, argv, &optind);
854 break;
855 case 'S':
856 set_lockswitch(optarg);
857 break;
858 case 's':
859 set_console(optarg);
860 break;
861 case 't':
862 set_screensaver_timeout(optarg);
863 break;
864 case 'x':
865 hex = 1;
866 break;
867 default:
868 usage();
869 }
1234 break;
1235 case 'S':
1236 set_lockswitch(optarg);
1237 break;
1238 case 's':
1239 set_console(optarg);
1240 break;
1241 case 't':
1242 set_screensaver_timeout(optarg);
1243 break;
1244 case 'x':
1245 hex = 1;
1246 break;
1247 default:
1248 usage();
1249 }
1250
870 if (dumpmod != 0)
871 dump_screen(dumpmod, dumpopt);
872 reterr = video_mode(argc, argv, &optind);
1251 if (dumpmod != 0)
1252 dump_screen(dumpmod, dumpopt);
1253 reterr = video_mode(argc, argv, &optind);
873 set_normal_colors(argc, argv, &optind);
1254 get_normal_colors(argc, argv, &optind);
1255
874 if (optind < argc && !strcmp(argv[optind], "show")) {
875 test_frame();
876 optind++;
877 }
1256 if (optind < argc && !strcmp(argv[optind], "show")) {
1257 test_frame();
1258 optind++;
1259 }
1260
1261 video_mode(argc, argv, &optind);
1262
1263 get_normal_colors(argc, argv, &optind);
1264
1265 if (colors_changed || video_mode_changed) {
1266 if (!(new_mode_info.vi_flags & V_INFO_GRAPHICS)) {
1267 if ((normal_back_color < 8) && (revers_back_color < 8)) {
1268 set_colors();
1269 } else {
1270 revert();
1271 errx(1, "bg color for text modes must be < 8");
1272 }
1273 } else {
1274 set_colors();
1275 }
1276 }
1277
878 if ((optind != argc) || (argc == 1))
879 usage();
880 return reterr;
881}
882
1278 if ((optind != argc) || (argc == 1))
1279 usage();
1280 return reterr;
1281}
1282