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