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, _IO('V', cur_mode), 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