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 |