1 /*- 2 * Copyright (c) 1994-1996 S�ren Schmidt 3 * All rights reserved. 4 * 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 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 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. 27 */ 28 29 #ifndef lint 30 static const char rcsid[] = 31 "$FreeBSD$"; 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 49 #define _VESA_800x600_DFL_COLS 80 50 #define _VESA_800x600_DFL_ROWS 25 51 #define _VESA_800x600_DFL_FNSZ 16 52 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 62 char 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 }; 68 int hex = 0; 69 int number; 70 int vesa_cols = _VESA_800x600_DFL_COLS; 71 int vesa_rows = _VESA_800x600_DFL_ROWS; 72 char letter; 73 struct vid_info info; 74 75 76 static void 77 usage() 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 88 char * 89 nextarg(int ac, char **av, int *indp, int oc, int strict) 90 { 91 if (*indp < ac) 92 return(av[(*indp)++]); 93 if (strict != 0) 94 errx(1, "option requires two arguments -- %c", oc); 95 return(NULL); 96 } 97 98 FILE * 99 openguess(char *a[], char *b[], char *c[], 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++) { 108 asprintf(name, "%s%s%s%s", a[i], b[j], 109 c[k], d[l]); 110 f = fopen(*name, "r"); 111 if (f != NULL) 112 return (f); 113 free(*name); 114 } 115 } 116 } 117 } 118 return (NULL); 119 } 120 121 void 122 load_scrnmap(char *filename) 123 { 124 FILE *fd; 125 int size; 126 char *name; 127 scrmap_t scrnmap; 128 char *a[] = {"", SCRNMAP_PATH, NULL}; 129 char *b[] = {filename, NULL}; 130 char *c[] = {"", ".scm", NULL}; 131 char *d[] = {"", NULL}; 132 133 fd = openguess(a, b, c, d, &name); 134 if (fd == NULL) { 135 warn("screenmap file not found"); 136 return; 137 } 138 size = sizeof(scrnmap); 139 if (decode(fd, (char *)&scrnmap, size) != size) { 140 rewind(fd); 141 if (fread(&scrnmap, 1, size, fd) != size) { 142 warnx("bad screenmap file"); 143 fclose(fd); 144 return; 145 } 146 } 147 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 148 warn("can't load screenmap"); 149 fclose(fd); 150 } 151 152 void 153 load_default_scrnmap() 154 { 155 scrmap_t scrnmap; 156 int i; 157 158 for (i=0; i<256; i++) 159 *((char*)&scrnmap + i) = i; 160 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 161 warn("can't load default screenmap"); 162 } 163 164 void 165 print_scrnmap() 166 { 167 unsigned char map[256]; 168 int i; 169 170 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 171 warn("getting screenmap"); 172 return; 173 } 174 for (i=0; i<sizeof(map); i++) { 175 if (i > 0 && i % 16 == 0) 176 fprintf(stdout, "\n"); 177 if (hex) 178 fprintf(stdout, " %02x", map[i]); 179 else 180 fprintf(stdout, " %03d", map[i]); 181 } 182 fprintf(stdout, "\n"); 183 184 } 185 186 int 187 fsize(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 197 #define DATASIZE(x) ((x).w * (x).h * 256 / 8) 198 199 void 200 load_font(char *type, 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 char *a[] = {"", FONT_PATH, NULL}; 207 char *b[] = {filename, NULL}; 208 char *c[] = {"", size_sufx, NULL}; 209 char *d[] = {"", ".fnt", NULL}; 210 vid_info_t info; 211 212 struct sizeinfo { 213 int w; 214 int h; 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) { 223 warn("failed to obtain current video mode parameters"); 224 return; 225 } 226 snprintf(size_sufx, sizeof(size_sufx), "-8x%d", info.font_size); 227 fd = openguess(a, b, c, d, &name); 228 if (fd == NULL) { 229 warn("%s: can't load font file", filename); 230 return; 231 } 232 if (type != NULL) { 233 size = 0; 234 if (sscanf(type, "%dx%d", &w, &h) == 2) 235 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; 239 } 240 241 if (size == 0) { 242 warnx("%s: bad font size specification", type); 243 fclose(fd); 244 return; 245 } 246 } else { 247 /* Apply heuristics */ 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; 258 for (j = 0; j < 2; j++) 259 for (i = 0; sizes[i].w != 0; i++) 260 if (DATASIZE(sizes[i]) == dsize[j]) { 261 size = dsize[j]; 262 io = sizes[i].io; 263 j = 2; /* XXX */ 264 break; 265 } 266 267 if (size == 0) { 268 warnx("%s: can't guess font size", filename); 269 fclose(fd); 270 return; 271 } 272 rewind(fd); 273 } 274 275 fontmap = (char*) malloc(size); 276 if (decode(fd, fontmap, size) != size) { 277 rewind(fd); 278 if (fsize(fd) != size || fread(fontmap, 1, size, fd) != size) { 279 warnx("%s: bad font file", filename); 280 fclose(fd); 281 free(fontmap); 282 return; 283 } 284 } 285 if (ioctl(0, io, fontmap) < 0) 286 warn("can't load font"); 287 fclose(fd); 288 free(fontmap); 289 } 290 291 void 292 set_screensaver_timeout(char *arg) 293 { 294 int nsec; 295 296 if (!strcmp(arg, "off")) 297 nsec = 0; 298 else { 299 nsec = atoi(arg); 300 if ((*arg == '\0') || (nsec < 1)) { 301 warnx("argument must be a positive number"); 302 return; 303 } 304 } 305 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 306 warn("setting screensaver period"); 307 } 308 309 void 310 set_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 { 321 warnx("argument to -c must be normal, blink or destructive"); 322 return; 323 } 324 ioctl(0, CONS_CURSORTYPE, &type); 325 } 326 327 void 328 video_mode(int argc, char **argv, int *index) 329 { 330 static struct { 331 char *name; 332 unsigned long mode; 333 } 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 }, 349 #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 }, 355 #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 }, 365 }; 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"); 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; 379 } 380 } 381 if (modes[i].name == NULL) 382 return; 383 if (ioctl(0, mode, NULL) < 0) 384 warn("cannot set videomode"); 385 if (mode == SW_VESA_800x600) { 386 /* columns */ 387 if ((vesa_cols * 8 > 800) || (vesa_cols <= 0)) { 388 warnx("incorrect number of columns: %d", 389 vesa_cols); 390 size[0] = _VESA_800x600_DFL_COLS; 391 } else { 392 size[0] = vesa_cols; 393 } 394 /* rows */ 395 if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) || 396 (vesa_rows <=0)) { 397 warnx("incorrect number of rows: %d", 398 vesa_rows); 399 size[1] = _VESA_800x600_DFL_ROWS; 400 } else { 401 size[1] = vesa_rows; 402 } 403 /* font size */ 404 size[2] = _VESA_800x600_DFL_FNSZ; 405 if (ioctl(0, KDRASTER, size)) { 406 ioerr = errno; 407 if (cur_mode >= M_VESA_BASE) 408 ioctl(0, 409 _IO('V', cur_mode - M_VESA_BASE), 410 NULL); 411 else 412 ioctl(0, _IO('S', cur_mode), NULL); 413 warnc(ioerr, "cannot activate raster display"); 414 } 415 } 416 (*index)++; 417 } 418 return; 419 } 420 421 int 422 get_color_number(char *color) 423 { 424 int i; 425 426 for (i=0; i<16; i++) 427 if (!strcmp(color, legal_colors[i])) 428 return i; 429 return -1; 430 } 431 432 void 433 set_normal_colors(int argc, char **argv, int *index) 434 { 435 int color; 436 437 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 438 (*index)++; 439 fprintf(stderr, "[=%dF", color); 440 if (*index < argc 441 && (color = get_color_number(argv[*index])) != -1 442 && color < 8) { 443 (*index)++; 444 fprintf(stderr, "[=%dG", color); 445 } 446 } 447 } 448 449 void 450 set_reverse_colors(int argc, char **argv, int *index) 451 { 452 int color; 453 454 if ((color = get_color_number(argv[*(index)-1])) != -1) { 455 fprintf(stderr, "[=%dH", color); 456 if (*index < argc 457 && (color = get_color_number(argv[*index])) != -1 458 && color < 8) { 459 (*index)++; 460 fprintf(stderr, "[=%dI", color); 461 } 462 } 463 } 464 465 void 466 set_console(char *arg) 467 { 468 int n; 469 470 if( !arg || strspn(arg,"0123456789") != strlen(arg)) { 471 warnx("bad console number"); 472 return; 473 } 474 475 n = atoi(arg); 476 if (n < 1 || n > 16) { 477 warnx("console number out of range"); 478 } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) 479 warn("ioctl(VT_ACTIVATE)"); 480 } 481 482 void 483 set_border_color(char *arg) 484 { 485 int color; 486 487 if ((color = get_color_number(arg)) != -1) { 488 fprintf(stderr, "[=%dA", color); 489 } 490 else 491 usage(); 492 } 493 494 void 495 set_mouse_char(char *arg) 496 { 497 struct mouse_info mouse; 498 long l; 499 500 l = strtol(arg, NULL, 0); 501 if ((l < 0) || (l > UCHAR_MAX - 3)) { 502 warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3); 503 return; 504 } 505 mouse.operation = MOUSE_MOUSECHAR; 506 mouse.u.mouse_char = (int)l; 507 ioctl(0, CONS_MOUSECTL, &mouse); 508 } 509 510 void 511 set_mouse(char *arg) 512 { 513 struct mouse_info mouse; 514 515 if (!strcmp(arg, "on")) 516 mouse.operation = MOUSE_SHOW; 517 else if (!strcmp(arg, "off")) 518 mouse.operation = MOUSE_HIDE; 519 else { 520 warnx("argument to -m must be either on or off"); 521 return; 522 } 523 ioctl(0, CONS_MOUSECTL, &mouse); 524 } 525 526 void 527 set_lockswitch(char *arg) 528 { 529 int data; 530 531 if (!strcmp(arg, "off")) 532 data = 0x01; 533 else if (!strcmp(arg, "on")) 534 data = 0x02; 535 else { 536 warnx("argument to -S must be either on or off"); 537 return; 538 } 539 if (ioctl(0, VT_LOCKSWITCH, &data) == -1) 540 warn("ioctl(VT_LOCKSWITCH)"); 541 } 542 543 static char 544 *adapter_name(int type) 545 { 546 static struct { 547 int type; 548 char *name; 549 } names[] = { 550 { KD_MONO, "MDA" }, 551 { KD_HERCULES, "Hercules" }, 552 { KD_CGA, "CGA" }, 553 { KD_EGA, "EGA" }, 554 { KD_VGA, "VGA" }, 555 { KD_PC98, "PC-98xx" }, 556 { KD_TGA, "TGA" }, 557 { -1, "Unknown" }, 558 }; 559 int i; 560 561 for (i = 0; names[i].type != -1; ++i) 562 if (names[i].type == type) 563 break; 564 return names[i].name; 565 } 566 567 void 568 show_adapter_info(void) 569 { 570 struct video_adapter_info ad; 571 572 ad.va_index = 0; 573 if (ioctl(0, CONS_ADPINFO, &ad)) { 574 warn("failed to obtain adapter information"); 575 return; 576 } 577 578 printf("fb%d:\n", ad.va_index); 579 printf(" %.*s%d, type:%s%s (%d), flags:0x%x\n", 580 (int)sizeof(ad.va_name), ad.va_name, ad.va_unit, 581 (ad.va_flags & V_ADP_VESA) ? "VESA " : "", 582 adapter_name(ad.va_type), ad.va_type, ad.va_flags); 583 printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n", 584 ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode); 585 printf(" frame buffer window:0x%x, buffer size:0x%x\n", 586 ad.va_window, ad.va_buffer_size); 587 printf(" window size:0x%x, origin:0x%x\n", 588 ad.va_window_size, ad.va_window_orig); 589 printf(" display start address (%d, %d), scan line width:%d\n", 590 ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width); 591 printf(" reserved:0x%x\n", ad.va_unused0); 592 } 593 594 void 595 show_mode_info(void) 596 { 597 struct video_info info; 598 char buf[80]; 599 int mode; 600 int c; 601 602 printf(" mode# flags type size " 603 "font window linear buffer\n"); 604 printf("---------------------------------------" 605 "---------------------------------------\n"); 606 for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) { 607 info.vi_mode = mode; 608 if (ioctl(0, CONS_MODEINFO, &info)) 609 continue; 610 if (info.vi_mode != mode) 611 continue; 612 613 printf("%3d (0x%03x)", mode, mode); 614 printf(" 0x%08x", info.vi_flags); 615 if (info.vi_flags & V_INFO_GRAPHICS) { 616 c = 'G'; 617 snprintf(buf, sizeof(buf), "%dx%dx%d %d", 618 info.vi_width, info.vi_height, 619 info.vi_depth, info.vi_planes); 620 } else { 621 c = 'T'; 622 snprintf(buf, sizeof(buf), "%dx%d", 623 info.vi_width, info.vi_height); 624 } 625 printf(" %c %-15s", c, buf); 626 snprintf(buf, sizeof(buf), "%dx%d", 627 info.vi_cwidth, info.vi_cheight); 628 printf(" %-5s", buf); 629 printf(" 0x%05x %2dk %2dk", 630 info.vi_window, (int)info.vi_window_size/1024, 631 (int)info.vi_window_gran/1024); 632 printf(" 0x%08x %dk\n", 633 info.vi_buffer, (int)info.vi_buffer_size/1024); 634 } 635 } 636 637 void 638 show_info(char *arg) 639 { 640 if (!strcmp(arg, "adapter")) 641 show_adapter_info(); 642 else if (!strcmp(arg, "mode")) 643 show_mode_info(); 644 else { 645 warnx("argument to -i must be either adapter or mode"); 646 return; 647 } 648 } 649 650 void 651 test_frame() 652 { 653 int i; 654 655 fprintf(stdout, "[=0G\n\n"); 656 for (i=0; i<8; i++) { 657 fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 658 "[=15F[=0G %2d [=%dF%-16s " 659 "[=15F %2d [=%dGBACKGROUND[=0G\n", 660 i, i, legal_colors[i], i+8, i+8, 661 legal_colors[i+8], i, i); 662 } 663 fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 664 info.mv_norm.fore, info.mv_norm.back, 665 info.mv_rev.fore, info.mv_rev.back); 666 } 667 668 /* 669 * Snapshot the video memory of that terminal, using the CONS_SCRSHOT 670 * ioctl, and writes the results to stdout either in the special 671 * binary format (see manual page for details), or in the plain 672 * text format. 673 */ 674 void 675 dump_screen(int mode, int opt) 676 { 677 scrshot_t shot; 678 vid_info_t info; 679 680 info.size = sizeof(info); 681 if (ioctl(0, CONS_GETINFO, &info) == -1) { 682 warn("failed to obtain current video mode parameters"); 683 return; 684 } 685 686 shot.x = shot.y = 0; 687 shot.xsize = info.mv_csz; 688 shot.ysize = info.mv_rsz; 689 if (opt == DUMP_ALL) 690 shot.ysize += info.mv_hsz; 691 692 shot.buf = alloca(shot.xsize * shot.ysize * sizeof(u_int16_t)); 693 if (shot.buf == NULL) { 694 warn("failed to allocate memory for dump"); 695 return; 696 } 697 698 if (ioctl(0, CONS_SCRSHOT, &shot) == -1) { 699 warn("failed to get dump of the screen"); 700 return; 701 } 702 703 if (mode == DUMP_FMT_RAW) { 704 printf("SCRSHOT_%c%c%c%c", DUMP_FMT_REV, 2, 705 shot.xsize, shot.ysize); 706 fflush(stdout); 707 708 (void)write(STDOUT_FILENO, shot.buf, 709 shot.xsize * shot.ysize * sizeof(u_int16_t)); 710 } else { 711 char *line; 712 int x, y; 713 u_int16_t ch; 714 715 line = alloca(shot.xsize + 1); 716 if (line == NULL) { 717 warn("failed to allocate memory for line buffer"); 718 return; 719 } 720 721 for (y = 0; y < shot.ysize; y++) { 722 for (x = 0; x < shot.xsize; x++) { 723 ch = shot.buf[x + (y * shot.xsize)]; 724 ch &= 0xff; 725 if (isprint(ch) == 0) 726 ch = ' '; 727 line[x] = (char)ch; 728 } 729 730 /* Trim trailing spaces */ 731 do { 732 line[x--] = '\0'; 733 } while (line[x] == ' ' && x != 0); 734 735 puts(line); 736 } 737 fflush(stdout); 738 } 739 740 return; 741 } 742 743 void 744 set_history(char *opt) 745 { 746 int size; 747 748 size = atoi(opt); 749 if ((*opt == '\0') || size < 0) { 750 warnx("argument must be a positive number"); 751 return; 752 } 753 if (ioctl(0, CONS_HISTORY, &size) == -1) 754 warn("setting history buffer size"); 755 } 756 757 void 758 clear_history() 759 { 760 761 if (ioctl(0, CONS_CLRHIST) == -1) 762 warn("clear history buffer"); 763 } 764 765 int 766 main(int argc, char **argv) 767 { 768 char *font, *type; 769 int dumpmod, dumpopt, opt; 770 771 772 info.size = sizeof(info); 773 if (argc == 1) 774 usage(); 775 /* Not reached */ 776 if (ioctl(0, CONS_GETINFO, &info) < 0) 777 err(1, "must be on a virtual console"); 778 dumpmod = 0; 779 dumpopt = DUMP_FBF; 780 while((opt = getopt(argc, argv, "b:Cc:df:g:h:Hi:l:LM:m:pPr:S:s:t:x")) != -1) 781 switch(opt) { 782 case 'b': 783 set_border_color(optarg); 784 break; 785 case 'C': 786 clear_history(); 787 break; 788 case 'c': 789 set_cursor_type(optarg); 790 break; 791 case 'd': 792 print_scrnmap(); 793 break; 794 case 'f': 795 type = optarg; 796 font = nextarg(argc, argv, &optind, 'f', 0); 797 if (font == NULL) { 798 type = NULL; 799 font = optarg; 800 } 801 load_font(type, font); 802 break; 803 case 'g': 804 if (sscanf(optarg, "%dx%d", &vesa_cols, 805 &vesa_rows) != 2) { 806 warnx("incorrect geometry: %s", optarg); 807 usage(); 808 } 809 break; 810 case 'h': 811 set_history(optarg); 812 break; 813 case 'H': 814 dumpopt = DUMP_ALL; 815 break; 816 case 'i': 817 show_info(optarg); 818 break; 819 case 'l': 820 load_scrnmap(optarg); 821 break; 822 case 'L': 823 load_default_scrnmap(); 824 break; 825 case 'M': 826 set_mouse_char(optarg); 827 break; 828 case 'm': 829 set_mouse(optarg); 830 break; 831 case 'p': 832 dumpmod = DUMP_FMT_RAW; 833 break; 834 case 'P': 835 dumpmod = DUMP_FMT_TXT; 836 break; 837 case 'r': 838 set_reverse_colors(argc, argv, &optind); 839 break; 840 case 'S': 841 set_lockswitch(optarg); 842 break; 843 case 's': 844 set_console(optarg); 845 break; 846 case 't': 847 set_screensaver_timeout(optarg); 848 break; 849 case 'x': 850 hex = 1; 851 break; 852 default: 853 usage(); 854 } 855 if (dumpmod != 0) 856 dump_screen(dumpmod, dumpopt); 857 video_mode(argc, argv, &optind); 858 set_normal_colors(argc, argv, &optind); 859 if (optind < argc && !strcmp(argv[optind], "show")) { 860 test_frame(); 861 optind++; 862 } 863 if ((optind != argc) || (argc == 1)) 864 usage(); 865 return 0; 866 } 867 868