vidcontrol.c revision 6628
12089Ssos/*- 25536Ssos * Copyright (c) 1994-1995 S�ren Schmidt 32089Ssos * All rights reserved. 42089Ssos * 52089Ssos * Redistribution and use in source and binary forms, with or without 62089Ssos * modification, are permitted provided that the following conditions 72089Ssos * are met: 82089Ssos * 1. Redistributions of source code must retain the above copyright 95994Ssos * notice, this list of conditions and the following disclaimer, 105994Ssos * in this position and unchanged. 112089Ssos * 2. Redistributions in binary form must reproduce the above copyright 122089Ssos * notice, this list of conditions and the following disclaimer in the 132089Ssos * documentation and/or other materials provided with the distribution. 142089Ssos * 3. The name of the author may not be used to endorse or promote products 152089Ssos * derived from this software withough specific prior written permission 162089Ssos * 172089Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 182089Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 192089Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 202089Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 212089Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 222089Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232089Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242089Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252089Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 262089Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272089Ssos * 286628Ssos * $Id: vidcontrol.c,v 1.8 1995/02/08 01:07:16 dima Exp $ 292089Ssos */ 302089Ssos 312089Ssos#include <ctype.h> 322089Ssos#include <stdio.h> 332089Ssos#include <machine/console.h> 342089Ssos#include <sys/errno.h> 352089Ssos#include "path.h" 362089Ssos 372089Ssoschar legal_colors[16][16] = { 382089Ssos "black", "blue", "green", "cyan", 392089Ssos "red", "magenta", "brown", "white", 402089Ssos "grey", "lightblue", "lightgreen", "lightcyan", 412089Ssos "lightred", "lightmagenta", "yellow", "lightwhite" 426628Ssos}; 432089Ssosint hex = 0; 446047Ssosint number; 452089Ssoschar letter; 462089Ssosstruct vid_info info; 472089Ssos 482089Ssos 496628Ssosvoid 506628Ssosusage() 516628Ssos{ 526628Ssos fprintf(stderr, 536628Ssos"Usage: vidcontrol mode (available modes: VGA_40x25, VGA_80x25,\n" 546628Ssos" VGA_80x50, VGA_320x200,\n" 556628Ssos" EGA_80x25, EGA_80x43)\n" 566628Ssos" (experimental) VGA_80x30, VGA_80x60)\n" 576628Ssos"\n" 586628Ssos" show (show available colors)\n" 596628Ssos" fgcol bgcol (set fore- & background colors)\n" 606628Ssos" -r fgcol bgcol (set reverse fore- & background colors)\n" 616628Ssos" -b color (set border color)\n" 626628Ssos" -c normal (set cursor to inverting block)\n" 636628Ssos" -c blink (set cursor to blinking inverted block)\n" 646628Ssos" -c destructive (set cursor to blinking destructive char)\n" 656628Ssos" -d (dump screenmap to stdout)\n" 666628Ssos" -l filename (load srceenmap file filename)\n" 676628Ssos" -L (load default screenmap)\n" 686628Ssos" -f DxL filename (load font, D dots wide & L lines high)\n" 696628Ssos" -s saver | help (set screensaver type or help for a list)\n" 706628Ssos" -t N (set screensaver timeout in seconds)\n" 716628Ssos" -x (use hex numbers for output)\n" 726628Ssos ); 736628Ssos} 746628Ssos 752089Ssoschar * 762089Ssosnextarg(int ac, char **av, int *indp, int oc) 772089Ssos{ 782089Ssos if (*indp < ac) 792089Ssos return(av[(*indp)++]); 802089Ssos fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc); 812089Ssos usage(); 822089Ssos exit(1); 832089Ssos return(""); 842089Ssos} 852089Ssos 862089Ssoschar * 872089Ssosmkfullname(const char *s1, const char *s2, const char *s3) 882089Ssos{ 896628Ssos static char *buf = NULL; 906628Ssos static int bufl = 0; 916628Ssos int f; 922089Ssos 932089Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 942089Ssos if (f > bufl) 952089Ssos if (buf) 962089Ssos buf = (char *)realloc(buf, f); 972089Ssos else 982089Ssos buf = (char *)malloc(f); 992089Ssos if (!buf) { 1002089Ssos bufl = 0; 1012089Ssos return(NULL); 1022089Ssos } 1032089Ssos 1042089Ssos bufl = f; 1052089Ssos strcpy(buf, s1); 1062089Ssos strcat(buf, s2); 1072089Ssos strcat(buf, s3); 1082089Ssos return(buf); 1092089Ssos} 1102089Ssos 1112089Ssosvoid 1122089Ssosload_scrnmap(char *filename) 1132089Ssos{ 1142089Ssos FILE *fd; 1152089Ssos int i, size; 1162089Ssos char *name; 1172089Ssos scrmap_t scrnmap; 1182089Ssos char *prefix[] = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL}; 1192089Ssos char *postfix[] = {"", ".scm", "", ".scm"}; 1202089Ssos 1212089Ssos for (i=0; prefix[i]; i++) { 1222089Ssos name = mkfullname(prefix[i], filename, postfix[i]); 1232089Ssos if (fd = fopen(name, "r")) 1242089Ssos break; 1252089Ssos } 1262089Ssos if (fd == NULL) { 1272089Ssos perror("screenmap file not found"); 1282089Ssos return; 1292089Ssos } 1302089Ssos size = sizeof(scrnmap); 1312089Ssos if (decode(fd, &scrnmap) != size) { 1322089Ssos rewind(fd); 1332089Ssos if (fread(&scrnmap, 1, size, fd) != size) { 1342089Ssos fprintf(stderr, "bad scrnmap file\n"); 1352089Ssos close(fd); 1362089Ssos return; 1372089Ssos } 1382089Ssos } 1392089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 1402089Ssos perror("can't load screenmap"); 1412089Ssos close(fd); 1422089Ssos} 1432089Ssos 1442089Ssosvoid 1452089Ssosload_default_scrnmap() 1462089Ssos{ 1476628Ssos scrmap_t scrnmap; 1482089Ssos int i; 1492089Ssos 1502089Ssos for (i=0; i<256; i++) 1512089Ssos *((char*)&scrnmap + i) = i; 1522089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 1532089Ssos perror("can't load default screenmap"); 1542089Ssos} 1552089Ssos 1562089Ssosvoid 1572089Ssosprint_scrnmap() 1582089Ssos{ 1592089Ssos unsigned char map[256]; 1602089Ssos int i; 1612089Ssos 1622089Ssos if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 1632089Ssos perror("getting scrnmap"); 1642089Ssos return; 1652089Ssos } 1662089Ssos for (i=0; i<sizeof(map); i++) { 1672089Ssos if (i > 0 && i % 16 == 0) 1682089Ssos fprintf(stdout, "\n"); 1692089Ssos if (hex) 1702089Ssos fprintf(stdout, " %02x", map[i]); 1712089Ssos else 1722089Ssos fprintf(stdout, " %03d", map[i]); 1732089Ssos } 1742089Ssos fprintf(stdout, "\n"); 1752089Ssos 1762089Ssos} 1772089Ssos 1782089Ssosvoid 1792089Ssosload_font(char *type, char *filename) 1802089Ssos{ 1812089Ssos FILE *fd; 1822089Ssos int i, io, size; 1832089Ssos char *name, *fontmap; 1842089Ssos char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL}; 1852089Ssos char *postfix[] = {"", ".fnt", "", ".fnt"}; 1862089Ssos 1872089Ssos for (i=0; prefix[i]; i++) { 1882089Ssos name = mkfullname(prefix[i], filename, postfix[i]); 1892089Ssos if (fd = fopen(name, "r")) 1902089Ssos break; 1912089Ssos } 1922089Ssos if (fd == NULL) { 1932089Ssos perror("font file not found"); 1942089Ssos return; 1952089Ssos } 1962089Ssos if (!strcmp(type, "8x8")) { 1972089Ssos size = 8*256; 1982089Ssos io = PIO_FONT8x8; 1992089Ssos } 2002089Ssos else if (!strcmp(type, "8x14")) { 2012089Ssos size = 14*256; 2022089Ssos io = PIO_FONT8x14; 2032089Ssos } 2042089Ssos else if (!strcmp(type, "8x16")) { 2052089Ssos size = 16*256; 2062089Ssos io = PIO_FONT8x16; 2072089Ssos } 2082089Ssos else { 2092089Ssos perror("bad font size specification"); 2102089Ssos close(fd); 2112089Ssos return; 2122089Ssos } 2132089Ssos fontmap = (char*) malloc(size); 2142089Ssos if (decode(fd, fontmap) != size) { 2152089Ssos rewind(fd); 2162089Ssos if (fread(fontmap, 1, size, fd) != size) { 2172089Ssos fprintf(stderr, "bad font file\n"); 2182089Ssos close(fd); 2192089Ssos free(fontmap); 2202089Ssos return; 2212089Ssos } 2222089Ssos } 2232089Ssos if (ioctl(0, io, fontmap) < 0) 2242089Ssos perror("can't load font"); 2252089Ssos close(fd); 2262089Ssos free(fontmap); 2272089Ssos} 2282089Ssos 2292089Ssosvoid 2302089Ssosset_screensaver_timeout(char *arg) 2312089Ssos{ 2322089Ssos int nsec; 2332089Ssos 2342089Ssos if (!strcmp(arg, "off")) 2352089Ssos nsec = 0; 2362089Ssos else { 2372089Ssos nsec = atoi(arg); 2382089Ssos if ((*arg == '\0') || (nsec < 1)) { 2392089Ssos fprintf(stderr, "argument must be a positive number\n"); 2402089Ssos return; 2412089Ssos } 2422089Ssos } 2432089Ssos if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 2442089Ssos perror("setting screensaver period"); 2452089Ssos} 2462089Ssos 2472089Ssosvoid 2485536Ssosset_cursor_type(char *appearence) 2492089Ssos{ 2505536Ssos int type; 2512089Ssos 2526230Ssos if (!strcmp(appearence, "normal")) 2536230Ssos type = 0; 2546230Ssos else if (!strcmp(appearence, "blink")) 2555536Ssos type = 1; 2566230Ssos else if (!strcmp(appearence, "destructive")) 2576230Ssos type = 3; 2585536Ssos else { 2596230Ssos fprintf(stderr, 2606230Ssos "argument to -c must be normal, blink or destructive\n"); 2612089Ssos return; 2622089Ssos } 2635536Ssos ioctl(0, CONS_CURSORTYPE, &type); 2642089Ssos} 2652089Ssos 2662089Ssosint 2672089Ssosvideo_mode(int argc, char **argv, int *index) 2682089Ssos{ 2692089Ssos int mode; 2702089Ssos 2712089Ssos if (*index < argc) { 2722784Ssos if (!strcmp(argv[*index], "VGA_40x25")) 2732784Ssos mode = SW_VGA_C40x25; 2742784Ssos else if (!strcmp(argv[*index], "VGA_80x25")) 2752784Ssos mode = SW_VGA_C80x25; 2765536Ssos else if (!strcmp(argv[*index], "VGA_80x30")) 2775536Ssos mode = SW_VGA_C80x30; 2782784Ssos else if (!strcmp(argv[*index], "VGA_80x50")) 2792784Ssos mode = SW_VGA_C80x50; 2805536Ssos else if (!strcmp(argv[*index], "VGA_80x60")) 2815536Ssos mode = SW_VGA_C80x60; 2822784Ssos else if (!strcmp(argv[*index], "VGA_320x200")) 2832784Ssos mode = SW_VGA_CG320; 2842784Ssos else if (!strcmp(argv[*index], "EGA_80x25")) 2852784Ssos mode = SW_ENH_C80x25; 2862784Ssos else if (!strcmp(argv[*index], "EGA_80x43")) 2872784Ssos mode = SW_ENH_C80x43; 2882089Ssos else 2892089Ssos return; 2902089Ssos if (ioctl(0, mode, NULL) < 0) 2912089Ssos perror("Cannot set videomode"); 2922089Ssos (*index)++; 2932089Ssos } 2942089Ssos return; 2952089Ssos} 2962089Ssos 2972089Ssosint 2982089Ssosget_color_number(char *color) 2992089Ssos{ 3002089Ssos int i; 3012089Ssos 3022089Ssos for (i=0; i<16; i++) 3032089Ssos if (!strcmp(color, legal_colors[i])) 3042089Ssos return i; 3052089Ssos return -1; 3062089Ssos} 3072089Ssos 3082089Ssosint 3092089Ssosset_normal_colors(int argc, char **argv, int *index) 3102089Ssos{ 3112089Ssos int color; 3122089Ssos 3132089Ssos if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 3142089Ssos (*index)++; 3152089Ssos fprintf(stderr, "[=%dF", color); 3162089Ssos if (*index < argc 3172089Ssos && (color = get_color_number(argv[*index])) != -1 3182089Ssos && color < 8) { 3192089Ssos (*index)++; 3202089Ssos fprintf(stderr, "[=%dG", color); 3212089Ssos } 3222089Ssos } 3232089Ssos} 3242089Ssos 3252089Ssosset_reverse_colors(int argc, char **argv, int *index) 3262089Ssos{ 3272089Ssos int color; 3282089Ssos 3292089Ssos if ((color = get_color_number(argv[*(index)-1])) != -1) { 3302089Ssos fprintf(stderr, "[=%dH", color); 3312089Ssos if (*index < argc 3322089Ssos && (color = get_color_number(argv[*index])) != -1 3332089Ssos && color < 8) { 3342089Ssos (*index)++; 3352089Ssos fprintf(stderr, "[=%dI", color); 3362089Ssos } 3372089Ssos } 3382089Ssos} 3392089Ssos 3402089Ssosset_border_color(char *arg) 3412089Ssos{ 3422089Ssos int color; 3432089Ssos 3442089Ssos if ((color = get_color_number(arg)) != -1) { 3452089Ssos fprintf(stderr, "[=%dA", color); 3462089Ssos } 3472089Ssos else 3482089Ssos usage(); 3492089Ssos} 3502089Ssos 3512089Ssostest_frame() 3522089Ssos{ 3532089Ssos int i; 3542089Ssos 3552089Ssos fprintf(stdout, "[=0G\n\n"); 3562089Ssos for (i=0; i<8; i++) { 3572089Ssos fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 3582089Ssos "[=15F[=0G %2d [=%dF%-16s " 3592089Ssos "[=15F %2d [=%dGBACKGROUND[=0G\n", 3602089Ssos i, i, legal_colors[i], i+8, i+8, 3612089Ssos legal_colors[i+8], i, i); 3622089Ssos } 3632089Ssos fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 3642089Ssos info.mv_norm.fore, info.mv_norm.back, 3652089Ssos info.mv_rev.fore, info.mv_rev.back); 3662089Ssos} 3672089Ssos 3682089Ssosvoid 3692089Ssosmain(int argc, char **argv) 3702089Ssos{ 3712089Ssos extern char *optarg; 3722089Ssos extern int optind; 3732089Ssos int opt; 3742089Ssos 3752089Ssos 3762089Ssos info.size = sizeof(info); 3772089Ssos if (ioctl(0, CONS_GETINFO, &info) < 0) { 3786628Ssos perror("Must be on a virtual console"); 3792089Ssos exit(1); 3802089Ssos } 3816628Ssos while((opt = getopt(argc, argv, "b:c:df:l:Lr:t:x")) != -1) 3822089Ssos switch(opt) { 3832089Ssos case 'c': 3845536Ssos set_cursor_type(optarg); 3852089Ssos break; 3862089Ssos case 'b': 3872089Ssos set_border_color(optarg); 3882089Ssos break; 3892089Ssos case 'd': 3902089Ssos print_scrnmap(); 3912089Ssos break; 3922089Ssos case 'f': 3932089Ssos load_font(optarg, 3942089Ssos nextarg(argc, argv, &optind, 'f')); 3952089Ssos break; 3962089Ssos case 'l': 3972089Ssos load_scrnmap(optarg); 3982089Ssos break; 3992089Ssos case 'L': 4002089Ssos load_default_scrnmap(); 4012089Ssos break; 4022089Ssos case 'r': 4032089Ssos set_reverse_colors(argc, argv, &optind); 4042089Ssos break; 4052089Ssos case 't': 4062089Ssos set_screensaver_timeout(optarg); 4072089Ssos break; 4082089Ssos case 'x': 4092089Ssos hex = 1; 4102089Ssos break; 4112089Ssos default: 4122089Ssos usage(); 4132089Ssos exit(1); 4142089Ssos } 4152089Ssos if (video_mode(argc, argv, &optind)) ; 4162089Ssos if (set_normal_colors(argc, argv, &optind)) ; 4172089Ssos if (optind < argc && !strcmp(argv[optind], "show")) { 4182089Ssos test_frame(); 4192089Ssos optind++; 4202089Ssos } 4212089Ssos if ((optind != argc) || (argc == 1)) { 4222089Ssos usage(); 4232089Ssos exit(1); 4242089Ssos } 4252089Ssos exit(0); 4262089Ssos} 4272089Ssos 428