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 #define DUMP_RAW 0 54 #define DUMP_TXT 1 55 56 #define DUMP_FMT_REV 1 57 58 char legal_colors[16][16] = { 59 "black", "blue", "green", "cyan", 60 "red", "magenta", "brown", "white", 61 "grey", "lightblue", "lightgreen", "lightcyan", 62 "lightred", "lightmagenta", "yellow", "lightwhite" 63 }; 64 int hex = 0; 65 int number; 66 int vesa_cols = _VESA_800x600_DFL_COLS; 67 int vesa_rows = _VESA_800x600_DFL_ROWS; 68 char letter; 69 struct vid_info info; 70 71 72 static void 73 usage() 74 { 75 fprintf(stderr, "%s\n%s\n%s\n%s\n", 76 "usage: vidcontrol [-CdLPpx] [-b color] [-c appearance] [-f [size] file]", 77 " [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]", 78 " [-m on | off] [-M char] [-r foreground background] [-s num]", 79 " [-t N | off] [mode] [foreground [background]] [show]"); 80 exit(1); 81 } 82 83 char * 84 nextarg(int ac, char **av, int *indp, int oc, int strict) 85 { 86 if (*indp < ac) 87 return(av[(*indp)++]); 88 if (strict != 0) 89 errx(1, "option requires two arguments -- %c", oc); 90 return(NULL); 91 } 92 93 FILE * 94 openguess(char *a[], char *b[], char *c[], char *d[], char **name) 95 { 96 FILE *f; 97 int i, j, k, l; 98 99 for (i = 0; a[i] != NULL; i++) { 100 for (j = 0; b[j] != NULL; j++) { 101 for (k = 0; c[k] != NULL; k++) { 102 for (l = 0; d[l] != NULL; l++) { 103 asprintf(name, "%s%s%s%s", a[i], b[j], 104 c[k], d[l]); 105 f = fopen(*name, "r"); 106 if (f != NULL) 107 return (f); 108 free(*name); 109 } 110 } 111 } 112 } 113 return (NULL); 114 } 115 116 void 117 load_scrnmap(char *filename) 118 { 119 FILE *fd; 120 int size; 121 char *name; 122 scrmap_t scrnmap; 123 char *a[] = {"", SCRNMAP_PATH, NULL}; 124 char *b[] = {filename, NULL}; 125 char *c[] = {"", ".scm", NULL}; 126 char *d[] = {"", NULL}; 127 128 fd = openguess(a, b, c, d, &name); 129 if (fd == NULL) { 130 warn("screenmap file not found"); 131 return; 132 } 133 size = sizeof(scrnmap); 134 if (decode(fd, (char *)&scrnmap, size) != size) { 135 rewind(fd); 136 if (fread(&scrnmap, 1, size, fd) != size) { 137 warnx("bad screenmap file"); 138 fclose(fd); 139 return; 140 } 141 } 142 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 143 warn("can't load screenmap"); 144 fclose(fd); 145 } 146 147 void 148 load_default_scrnmap() 149 { 150 scrmap_t scrnmap; 151 int i; 152 153 for (i=0; i<256; i++) 154 *((char*)&scrnmap + i) = i; 155 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 156 warn("can't load default screenmap"); 157 } 158 159 void 160 print_scrnmap() 161 { 162 unsigned char map[256]; 163 int i; 164 165 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 166 warn("getting screenmap"); 167 return; 168 } 169 for (i=0; i<sizeof(map); i++) { 170 if (i > 0 && i % 16 == 0) 171 fprintf(stdout, "\n"); 172 if (hex) 173 fprintf(stdout, " %02x", map[i]); 174 else 175 fprintf(stdout, " %03d", map[i]); 176 } 177 fprintf(stdout, "\n"); 178 179 } 180 181 int 182 fsize(FILE *file) 183 { 184 struct stat sb; 185 186 if (fstat(fileno(file), &sb) == 0) 187 return sb.st_size; 188 else 189 return -1; 190 } 191 192 #define DATASIZE(x) ((x).w * (x).h * 256 / 8) 193 194 void 195 load_font(char *type, char *filename) 196 { 197 FILE *fd; 198 int h, i, size, w; 199 unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */ 200 char *name, *fontmap, size_sufx[6]; 201 char *a[] = {"", FONT_PATH, NULL}; 202 char *b[] = {filename, NULL}; 203 char *c[] = {"", size_sufx, NULL}; 204 char *d[] = {"", ".fnt", NULL}; 205 vid_info_t info; 206 207 struct sizeinfo { 208 int w; 209 int h; 210 unsigned long io; 211 } sizes[] = {{8, 16, PIO_FONT8x16}, 212 {8, 14, PIO_FONT8x14}, 213 {8, 8, PIO_FONT8x8}, 214 {0, 0, 0}}; 215 216 info.size = sizeof(info); 217 if (ioctl(0, CONS_GETINFO, &info) == -1) { 218 warn("failed to obtain current video mode parameters"); 219 return; 220 } 221 snprintf(size_sufx, sizeof(size_sufx), "-8x%d", info.font_size); 222 fd = openguess(a, b, c, d, &name); 223 if (fd == NULL) { 224 warn("%s: can't load font file", filename); 225 return; 226 } 227 if (type != NULL) { 228 size = 0; 229 if (sscanf(type, "%dx%d", &w, &h) == 2) 230 for (i = 0; sizes[i].w != 0; i++) 231 if (sizes[i].w == w && sizes[i].h == h) { 232 size = DATASIZE(sizes[i]); 233 io = sizes[i].io; 234 } 235 236 if (size == 0) { 237 warnx("%s: bad font size specification", type); 238 fclose(fd); 239 return; 240 } 241 } else { 242 /* Apply heuristics */ 243 int j; 244 int dsize[2]; 245 246 size = DATASIZE(sizes[0]); 247 fontmap = (char*) malloc(size); 248 dsize[0] = decode(fd, fontmap, size); 249 dsize[1] = fsize(fd); 250 free(fontmap); 251 252 size = 0; 253 for (j = 0; j < 2; j++) 254 for (i = 0; sizes[i].w != 0; i++) 255 if (DATASIZE(sizes[i]) == dsize[j]) { 256 size = dsize[j]; 257 io = sizes[i].io; 258 j = 2; /* XXX */ 259 break; 260 } 261 262 if (size == 0) { 263 warnx("%s: can't guess font size", filename); 264 fclose(fd); 265 return; 266 } 267 rewind(fd); 268 } 269 270 fontmap = (char*) malloc(size); 271 if (decode(fd, fontmap, size) != size) { 272 rewind(fd); 273 if (fsize(fd) != size || fread(fontmap, 1, size, fd) != size) { 274 warnx("%s: bad font file", filename); 275 fclose(fd); 276 free(fontmap); 277 return; 278 } 279 } 280 if (ioctl(0, io, fontmap) < 0) 281 warn("can't load font"); 282 fclose(fd); 283 free(fontmap); 284 } 285 286 void 287 set_screensaver_timeout(char *arg) 288 { 289 int nsec; 290 291 if (!strcmp(arg, "off")) 292 nsec = 0; 293 else { 294 nsec = atoi(arg); 295 if ((*arg == '\0') || (nsec < 1)) { 296 warnx("argument must be a positive number"); 297 return; 298 } 299 } 300 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 301 warn("setting screensaver period"); 302 } 303 304 void 305 set_cursor_type(char *appearence) 306 { 307 int type; 308 309 if (!strcmp(appearence, "normal")) 310 type = 0; 311 else if (!strcmp(appearence, "blink")) 312 type = 1; 313 else if (!strcmp(appearence, "destructive")) 314 type = 3; 315 else { 316 warnx("argument to -c must be normal, blink or destructive"); 317 return; 318 } 319 ioctl(0, CONS_CURSORTYPE, &type); 320 } 321 322 void 323 video_mode(int argc, char **argv, int *index) 324 { 325 static struct { 326 char *name; 327 unsigned long mode; 328 } modes[] = { 329 { "80x25", SW_TEXT_80x25 }, 330 { "80x30", SW_TEXT_80x30 }, 331 { "80x43", SW_TEXT_80x43 }, 332 { "80x50", SW_TEXT_80x50 }, 333 { "80x60", SW_TEXT_80x60 }, 334 { "132x25", SW_TEXT_132x25 }, 335 { "132x30", SW_TEXT_132x30 }, 336 { "132x43", SW_TEXT_132x43 }, 337 { "132x50", SW_TEXT_132x50 }, 338 { "132x60", SW_TEXT_132x60 }, 339 { "VGA_40x25", SW_VGA_C40x25 }, 340 { "VGA_80x25", SW_VGA_C80x25 }, 341 { "VGA_80x30", SW_VGA_C80x30 }, 342 { "VGA_80x50", SW_VGA_C80x50 }, 343 { "VGA_80x60", SW_VGA_C80x60 }, 344 #ifdef SW_VGA_C90x25 345 { "VGA_90x25", SW_VGA_C90x25 }, 346 { "VGA_90x30", SW_VGA_C90x30 }, 347 { "VGA_90x43", SW_VGA_C90x43 }, 348 { "VGA_90x50", SW_VGA_C90x50 }, 349 { "VGA_90x60", SW_VGA_C90x60 }, 350 #endif 351 { "VGA_320x200", SW_VGA_CG320 }, 352 { "EGA_80x25", SW_ENH_C80x25 }, 353 { "EGA_80x43", SW_ENH_C80x43 }, 354 { "VESA_132x25", SW_VESA_C132x25 }, 355 { "VESA_132x43", SW_VESA_C132x43 }, 356 { "VESA_132x50", SW_VESA_C132x50 }, 357 { "VESA_132x60", SW_VESA_C132x60 }, 358 { "VESA_800x600", SW_VESA_800x600 }, 359 { NULL }, 360 }; 361 unsigned long mode = 0; 362 int cur_mode; 363 int ioerr; 364 int size[3]; 365 int i; 366 367 if (ioctl(0, CONS_GET, &cur_mode) < 0) 368 err(1, "cannot get the current video mode"); 369 if (*index < argc) { 370 for (i = 0; modes[i].name != NULL; ++i) { 371 if (!strcmp(argv[*index], modes[i].name)) { 372 mode = modes[i].mode; 373 break; 374 } 375 } 376 if (modes[i].name == NULL) 377 return; 378 if (ioctl(0, mode, NULL) < 0) 379 warn("cannot set videomode"); 380 if (mode == SW_VESA_800x600) { 381 /* columns */ 382 if ((vesa_cols * 8 > 800) || (vesa_cols <= 0)) { 383 warnx("incorrect number of columns: %d", 384 vesa_cols); 385 size[0] = _VESA_800x600_DFL_COLS; 386 } else { 387 size[0] = vesa_cols; 388 } 389 /* rows */ 390 if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) || 391 (vesa_rows <=0)) { 392 warnx("incorrect number of rows: %d", 393 vesa_rows); 394 size[1] = _VESA_800x600_DFL_ROWS; 395 } else { 396 size[1] = vesa_rows; 397 } 398 /* font size */ 399 size[2] = _VESA_800x600_DFL_FNSZ; 400 if (ioctl(0, KDRASTER, size)) { 401 ioerr = errno; 402 if (cur_mode >= M_VESA_BASE) 403 ioctl(0, 404 _IO('V', cur_mode - M_VESA_BASE), 405 NULL); 406 else 407 ioctl(0, _IO('S', cur_mode), NULL); 408 warnc(ioerr, "cannot activate raster display"); 409 } 410 } 411 (*index)++; 412 } 413 return; 414 } 415 416 int 417 get_color_number(char *color) 418 { 419 int i; 420 421 for (i=0; i<16; i++) 422 if (!strcmp(color, legal_colors[i])) 423 return i; 424 return -1; 425 } 426 427 void 428 set_normal_colors(int argc, char **argv, int *index) 429 { 430 int color; 431 432 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 433 (*index)++; 434 fprintf(stderr, "[=%dF", color); 435 if (*index < argc 436 && (color = get_color_number(argv[*index])) != -1 437 && color < 8) { 438 (*index)++; 439 fprintf(stderr, "[=%dG", color); 440 } 441 } 442 } 443 444 void 445 set_reverse_colors(int argc, char **argv, int *index) 446 { 447 int color; 448 449 if ((color = get_color_number(argv[*(index)-1])) != -1) { 450 fprintf(stderr, "[=%dH", color); 451 if (*index < argc 452 && (color = get_color_number(argv[*index])) != -1 453 && color < 8) { 454 (*index)++; 455 fprintf(stderr, "[=%dI", color); 456 } 457 } 458 } 459 460 void 461 set_console(char *arg) 462 { 463 int n; 464 465 if( !arg || strspn(arg,"0123456789") != strlen(arg)) { 466 warnx("bad console number"); 467 return; 468 } 469 470 n = atoi(arg); 471 if (n < 1 || n > 16) { 472 warnx("console number out of range"); 473 } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) 474 warn("ioctl(VT_ACTIVATE)"); 475 } 476 477 void 478 set_border_color(char *arg) 479 { 480 int color; 481 482 if ((color = get_color_number(arg)) != -1) { 483 fprintf(stderr, "[=%dA", color); 484 } 485 else 486 usage(); 487 } 488 489 void 490 set_mouse_char(char *arg) 491 { 492 struct mouse_info mouse; 493 long l; 494 495 l = strtol(arg, NULL, 0); 496 if ((l < 0) || (l > UCHAR_MAX - 3)) { 497 warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3); 498 return; 499 } 500 mouse.operation = MOUSE_MOUSECHAR; 501 mouse.u.mouse_char = (int)l; 502 ioctl(0, CONS_MOUSECTL, &mouse); 503 } 504 505 void 506 set_mouse(char *arg) 507 { 508 struct mouse_info mouse; 509 510 if (!strcmp(arg, "on")) 511 mouse.operation = MOUSE_SHOW; 512 else if (!strcmp(arg, "off")) 513 mouse.operation = MOUSE_HIDE; 514 else { 515 warnx("argument to -m must either on or off"); 516 return; 517 } 518 ioctl(0, CONS_MOUSECTL, &mouse); 519 } 520 521 static char 522 *adapter_name(int type) 523 { 524 static struct { 525 int type; 526 char *name; 527 } names[] = { 528 { KD_MONO, "MDA" }, 529 { KD_HERCULES, "Hercules" }, 530 { KD_CGA, "CGA" }, 531 { KD_EGA, "EGA" }, 532 { KD_VGA, "VGA" }, 533 { KD_PC98, "PC-98xx" }, 534 { KD_TGA, "TGA" }, 535 { -1, "Unknown" }, 536 }; 537 int i; 538 539 for (i = 0; names[i].type != -1; ++i) 540 if (names[i].type == type) 541 break; 542 return names[i].name; 543 } 544 545 void 546 show_adapter_info(void) 547 { 548 struct video_adapter_info ad; 549 550 ad.va_index = 0; 551 if (ioctl(0, CONS_ADPINFO, &ad)) { 552 warn("failed to obtain adapter information"); 553 return; 554 } 555 556 printf("fb%d:\n", ad.va_index); 557 printf(" %.*s%d, type:%s%s (%d), flags:0x%x\n", 558 (int)sizeof(ad.va_name), ad.va_name, ad.va_unit, 559 (ad.va_flags & V_ADP_VESA) ? "VESA " : "", 560 adapter_name(ad.va_type), ad.va_type, ad.va_flags); 561 printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n", 562 ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode); 563 printf(" frame buffer window:0x%x, buffer size:0x%x\n", 564 ad.va_window, ad.va_buffer_size); 565 printf(" window size:0x%x, origin:0x%x\n", 566 ad.va_window_size, ad.va_window_orig); 567 printf(" display start address (%d, %d), scan line width:%d\n", 568 ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width); 569 printf(" reserved:0x%x\n", ad.va_unused0); 570 } 571 572 void 573 show_mode_info(void) 574 { 575 struct video_info info; 576 char buf[80]; 577 int mode; 578 int c; 579 580 printf(" mode# flags type size " 581 "font window linear buffer\n"); 582 printf("---------------------------------------" 583 "---------------------------------------\n"); 584 for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) { 585 info.vi_mode = mode; 586 if (ioctl(0, CONS_MODEINFO, &info)) 587 continue; 588 if (info.vi_mode != mode) 589 continue; 590 591 printf("%3d (0x%03x)", mode, mode); 592 printf(" 0x%08x", info.vi_flags); 593 if (info.vi_flags & V_INFO_GRAPHICS) { 594 c = 'G'; 595 snprintf(buf, sizeof(buf), "%dx%dx%d %d", 596 info.vi_width, info.vi_height, 597 info.vi_depth, info.vi_planes); 598 } else { 599 c = 'T'; 600 snprintf(buf, sizeof(buf), "%dx%d", 601 info.vi_width, info.vi_height); 602 } 603 printf(" %c %-15s", c, buf); 604 snprintf(buf, sizeof(buf), "%dx%d", 605 info.vi_cwidth, info.vi_cheight); 606 printf(" %-5s", buf); 607 printf(" 0x%05x %2dk %2dk", 608 info.vi_window, (int)info.vi_window_size/1024, 609 (int)info.vi_window_gran/1024); 610 printf(" 0x%08x %dk\n", 611 info.vi_buffer, (int)info.vi_buffer_size/1024); 612 } 613 } 614 615 void 616 show_info(char *arg) 617 { 618 if (!strcmp(arg, "adapter")) 619 show_adapter_info(); 620 else if (!strcmp(arg, "mode")) 621 show_mode_info(); 622 else { 623 warnx("argument to -i must either adapter or mode"); 624 return; 625 } 626 } 627 628 void 629 test_frame() 630 { 631 int i; 632 633 fprintf(stdout, "[=0G\n\n"); 634 for (i=0; i<8; i++) { 635 fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 636 "[=15F[=0G %2d [=%dF%-16s " 637 "[=15F %2d [=%dGBACKGROUND[=0G\n", 638 i, i, legal_colors[i], i+8, i+8, 639 legal_colors[i+8], i, i); 640 } 641 fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 642 info.mv_norm.fore, info.mv_norm.back, 643 info.mv_rev.fore, info.mv_rev.back); 644 } 645 646 /* 647 * Snapshot the video memory of that terminal, using the CONS_SCRSHOT 648 * ioctl, and writes the results to stdout either in the special 649 * binary format (see manual page for details), or in the plain 650 * text format. 651 */ 652 void 653 dump_screen(int mode) 654 { 655 scrshot_t shot; 656 vid_info_t info; 657 658 info.size = sizeof(info); 659 if (ioctl(0, CONS_GETINFO, &info) == -1) { 660 warn("failed to obtain current video mode parameters"); 661 return; 662 } 663 664 shot.buf = alloca(info.mv_csz * info.mv_rsz * sizeof(u_int16_t)); 665 if (shot.buf == NULL) { 666 warn("failed to allocate memory for dump"); 667 return; 668 } 669 670 shot.xsize = info.mv_csz; 671 shot.ysize = info.mv_rsz; 672 if (ioctl(0, CONS_SCRSHOT, &shot) == -1) { 673 warn("failed to get dump of the screen"); 674 return; 675 } 676 677 if (mode == DUMP_RAW) { 678 printf("SCRSHOT_%c%c%c%c", DUMP_FMT_REV, 2, 679 shot.xsize, shot.ysize); 680 fflush(stdout); 681 682 (void)write(STDOUT_FILENO, shot.buf, 683 shot.xsize * shot.ysize * sizeof(u_int16_t)); 684 } else { 685 char *line; 686 int x, y; 687 u_int16_t ch; 688 689 line = alloca(shot.xsize + 1); 690 if (line == NULL) { 691 warn("failed to allocate memory for line buffer"); 692 return; 693 } 694 695 for (y = 0; y < shot.ysize; y++) { 696 for (x = 0; x < shot.xsize; x++) { 697 ch = shot.buf[x + (y * shot.xsize)]; 698 ch &= 0xff; 699 if (isprint(ch) == 0) 700 ch = ' '; 701 line[x] = (char)ch; 702 } 703 704 /* Trim trailing spaces */ 705 do { 706 line[x--] = '\0'; 707 } while (line[x] == ' ' && x != 0); 708 709 puts(line); 710 } 711 fflush(stdout); 712 } 713 714 return; 715 } 716 717 void 718 set_history(char *opt) 719 { 720 int size; 721 722 size = atoi(opt); 723 if ((*opt == '\0') || size < 0) { 724 warnx("argument must be a positive number"); 725 return; 726 } 727 if (ioctl(0, CONS_HISTORY, &size) == -1) 728 warn("setting history buffer size"); 729 } 730 731 void 732 clear_history() 733 { 734 735 if (ioctl(0, CONS_CLRHIST) == -1) 736 warn("clear history buffer"); 737 } 738 739 int 740 main(int argc, char **argv) 741 { 742 char *font, *type; 743 int opt; 744 745 746 info.size = sizeof(info); 747 if (argc == 1) 748 usage(); 749 /* Not reached */ 750 if (ioctl(0, CONS_GETINFO, &info) < 0) 751 err(1, "must be on a virtual console"); 752 while((opt = getopt(argc, argv, "b:Cc:df:g:h:i:l:LM:m:pPr:s:t:x")) != -1) 753 switch(opt) { 754 case 'b': 755 set_border_color(optarg); 756 break; 757 case 'C': 758 clear_history(); 759 break; 760 case 'c': 761 set_cursor_type(optarg); 762 break; 763 case 'd': 764 print_scrnmap(); 765 break; 766 case 'f': 767 type = optarg; 768 font = nextarg(argc, argv, &optind, 'f', 0); 769 if (font == NULL) { 770 type = NULL; 771 font = optarg; 772 } 773 load_font(type, font); 774 break; 775 case 'g': 776 if (sscanf(optarg, "%dx%d", &vesa_cols, 777 &vesa_rows) != 2) { 778 warnx("incorrect geometry: %s", optarg); 779 usage(); 780 } 781 break; 782 case 'h': 783 set_history(optarg); 784 break; 785 case 'i': 786 show_info(optarg); 787 break; 788 case 'l': 789 load_scrnmap(optarg); 790 break; 791 case 'L': 792 load_default_scrnmap(); 793 break; 794 case 'M': 795 set_mouse_char(optarg); 796 break; 797 case 'm': 798 set_mouse(optarg); 799 break; 800 case 'p': 801 dump_screen(DUMP_RAW); 802 break; 803 case 'P': 804 dump_screen(DUMP_TXT); 805 break; 806 case 'r': 807 set_reverse_colors(argc, argv, &optind); 808 break; 809 case 's': 810 set_console(optarg); 811 break; 812 case 't': 813 set_screensaver_timeout(optarg); 814 break; 815 case 'x': 816 hex = 1; 817 break; 818 default: 819 usage(); 820 } 821 video_mode(argc, argv, &optind); 822 set_normal_colors(argc, argv, &optind); 823 if (optind < argc && !strcmp(argv[optind], "show")) { 824 test_frame(); 825 optind++; 826 } 827 if ((optind != argc) || (argc == 1)) 828 usage(); 829 return 0; 830 } 831 832