vidcontrol.c revision 23702
12089Ssos/*- 216565Ssos * Copyright (c) 1994-1996 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 * 2823702Speter * $Id: vidcontrol.c,v 1.16 1997/03/07 01:34:47 brian Exp $ 292089Ssos */ 302089Ssos 312089Ssos#include <ctype.h> 322089Ssos#include <stdio.h> 3323457Sbrian#include <stdlib.h> 3423702Speter#include <unistd.h> 3523457Sbrian#include <string.h> 362089Ssos#include <machine/console.h> 372089Ssos#include <sys/errno.h> 382089Ssos#include "path.h" 3923457Sbrian#include "decode.h" 402089Ssos 412089Ssoschar legal_colors[16][16] = { 422089Ssos "black", "blue", "green", "cyan", 432089Ssos "red", "magenta", "brown", "white", 442089Ssos "grey", "lightblue", "lightgreen", "lightcyan", 452089Ssos "lightred", "lightmagenta", "yellow", "lightwhite" 466628Ssos}; 472089Ssosint hex = 0; 486047Ssosint number; 492089Ssoschar letter; 502089Ssosstruct vid_info info; 512089Ssos 522089Ssos 536628Ssosvoid 546628Ssosusage() 556628Ssos{ 566628Ssos fprintf(stderr, 576628Ssos"Usage: vidcontrol mode (available modes: VGA_40x25, VGA_80x25,\n" 586628Ssos" VGA_80x50, VGA_320x200,\n" 596628Ssos" EGA_80x25, EGA_80x43)\n" 606628Ssos" (experimental) VGA_80x30, VGA_80x60)\n" 616628Ssos"\n" 626628Ssos" show (show available colors)\n" 636628Ssos" fgcol bgcol (set fore- & background colors)\n" 646628Ssos" -r fgcol bgcol (set reverse fore- & background colors)\n" 656628Ssos" -b color (set border color)\n" 666628Ssos" -c normal (set cursor to inverting block)\n" 676628Ssos" -c blink (set cursor to blinking inverted block)\n" 686628Ssos" -c destructive (set cursor to blinking destructive char)\n" 696628Ssos" -d (dump screenmap to stdout)\n" 7016947Sgpalmer" -l filename (load screenmap file filename)\n" 7116565Ssos" -m on|off (switch mousepointer support on or off)\n" 726628Ssos" -L (load default screenmap)\n" 736628Ssos" -f DxL filename (load font, D dots wide & L lines high)\n" 746628Ssos" -t N (set screensaver timeout in seconds)\n" 756628Ssos" -x (use hex numbers for output)\n" 766628Ssos ); 776628Ssos} 786628Ssos 792089Ssoschar * 802089Ssosnextarg(int ac, char **av, int *indp, int oc) 812089Ssos{ 822089Ssos if (*indp < ac) 832089Ssos return(av[(*indp)++]); 842089Ssos fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc); 852089Ssos usage(); 862089Ssos exit(1); 872089Ssos return(""); 882089Ssos} 892089Ssos 902089Ssoschar * 912089Ssosmkfullname(const char *s1, const char *s2, const char *s3) 922089Ssos{ 936628Ssos static char *buf = NULL; 946628Ssos static int bufl = 0; 956628Ssos int f; 962089Ssos 972089Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 982089Ssos if (f > bufl) 992089Ssos if (buf) 1002089Ssos buf = (char *)realloc(buf, f); 1012089Ssos else 1022089Ssos buf = (char *)malloc(f); 1032089Ssos if (!buf) { 1042089Ssos bufl = 0; 1052089Ssos return(NULL); 1062089Ssos } 1072089Ssos 1082089Ssos bufl = f; 1092089Ssos strcpy(buf, s1); 1102089Ssos strcat(buf, s2); 1112089Ssos strcat(buf, s3); 1122089Ssos return(buf); 1132089Ssos} 1142089Ssos 1152089Ssosvoid 1162089Ssosload_scrnmap(char *filename) 1172089Ssos{ 11823457Sbrian FILE *fd = 0; 1192089Ssos int i, size; 1202089Ssos char *name; 1212089Ssos scrmap_t scrnmap; 1222089Ssos char *prefix[] = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL}; 1232089Ssos char *postfix[] = {"", ".scm", "", ".scm"}; 1242089Ssos 1252089Ssos for (i=0; prefix[i]; i++) { 1262089Ssos name = mkfullname(prefix[i], filename, postfix[i]); 12723457Sbrian fd = fopen(name, "r"); 12823457Sbrian if (fd) 1292089Ssos break; 1302089Ssos } 1312089Ssos if (fd == NULL) { 1322089Ssos perror("screenmap file not found"); 1332089Ssos return; 1342089Ssos } 1352089Ssos size = sizeof(scrnmap); 13623457Sbrian if (decode(fd, (char *)&scrnmap) != size) { 1372089Ssos rewind(fd); 1382089Ssos if (fread(&scrnmap, 1, size, fd) != size) { 1392089Ssos fprintf(stderr, "bad scrnmap file\n"); 14023457Sbrian fclose(fd); 1412089Ssos return; 1422089Ssos } 1432089Ssos } 1442089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 1452089Ssos perror("can't load screenmap"); 14623457Sbrian fclose(fd); 1472089Ssos} 1482089Ssos 1492089Ssosvoid 1502089Ssosload_default_scrnmap() 1512089Ssos{ 1526628Ssos scrmap_t scrnmap; 1532089Ssos int i; 1542089Ssos 1552089Ssos for (i=0; i<256; i++) 1562089Ssos *((char*)&scrnmap + i) = i; 1572089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 1582089Ssos perror("can't load default screenmap"); 1592089Ssos} 1602089Ssos 1612089Ssosvoid 1622089Ssosprint_scrnmap() 1632089Ssos{ 1642089Ssos unsigned char map[256]; 1652089Ssos int i; 1662089Ssos 1672089Ssos if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 1682089Ssos perror("getting scrnmap"); 1692089Ssos return; 1702089Ssos } 1712089Ssos for (i=0; i<sizeof(map); i++) { 1722089Ssos if (i > 0 && i % 16 == 0) 1732089Ssos fprintf(stdout, "\n"); 1742089Ssos if (hex) 1758857Srgrimes fprintf(stdout, " %02x", map[i]); 1762089Ssos else 1772089Ssos fprintf(stdout, " %03d", map[i]); 1782089Ssos } 1792089Ssos fprintf(stdout, "\n"); 1802089Ssos 1812089Ssos} 1822089Ssos 1838857Srgrimesvoid 1842089Ssosload_font(char *type, char *filename) 1852089Ssos{ 18623457Sbrian FILE *fd = 0; 1872089Ssos int i, io, size; 1882089Ssos char *name, *fontmap; 1892089Ssos char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL}; 1902089Ssos char *postfix[] = {"", ".fnt", "", ".fnt"}; 1912089Ssos 1922089Ssos for (i=0; prefix[i]; i++) { 1932089Ssos name = mkfullname(prefix[i], filename, postfix[i]); 19423457Sbrian fd = fopen(name, "r"); 19523457Sbrian if (fd) 1962089Ssos break; 1972089Ssos } 1982089Ssos if (fd == NULL) { 1992089Ssos perror("font file not found"); 2002089Ssos return; 2012089Ssos } 2022089Ssos if (!strcmp(type, "8x8")) { 2032089Ssos size = 8*256; 2042089Ssos io = PIO_FONT8x8; 2052089Ssos } 2062089Ssos else if (!strcmp(type, "8x14")) { 2072089Ssos size = 14*256; 2082089Ssos io = PIO_FONT8x14; 2092089Ssos } 2102089Ssos else if (!strcmp(type, "8x16")) { 2112089Ssos size = 16*256; 2122089Ssos io = PIO_FONT8x16; 2132089Ssos } 2142089Ssos else { 2152089Ssos perror("bad font size specification"); 21623457Sbrian fclose(fd); 2172089Ssos return; 2182089Ssos } 2192089Ssos fontmap = (char*) malloc(size); 2202089Ssos if (decode(fd, fontmap) != size) { 2212089Ssos rewind(fd); 2222089Ssos if (fread(fontmap, 1, size, fd) != size) { 2232089Ssos fprintf(stderr, "bad font file\n"); 22423457Sbrian fclose(fd); 2252089Ssos free(fontmap); 2262089Ssos return; 2272089Ssos } 2282089Ssos } 2292089Ssos if (ioctl(0, io, fontmap) < 0) 2302089Ssos perror("can't load font"); 23123457Sbrian fclose(fd); 2322089Ssos free(fontmap); 2332089Ssos} 2342089Ssos 2352089Ssosvoid 2362089Ssosset_screensaver_timeout(char *arg) 2372089Ssos{ 2382089Ssos int nsec; 2392089Ssos 2402089Ssos if (!strcmp(arg, "off")) 2412089Ssos nsec = 0; 2422089Ssos else { 2432089Ssos nsec = atoi(arg); 2442089Ssos if ((*arg == '\0') || (nsec < 1)) { 2452089Ssos fprintf(stderr, "argument must be a positive number\n"); 2462089Ssos return; 2472089Ssos } 2482089Ssos } 2492089Ssos if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 2502089Ssos perror("setting screensaver period"); 2512089Ssos} 2522089Ssos 2532089Ssosvoid 2545536Ssosset_cursor_type(char *appearence) 2552089Ssos{ 2565536Ssos int type; 2572089Ssos 2586230Ssos if (!strcmp(appearence, "normal")) 2596230Ssos type = 0; 2606230Ssos else if (!strcmp(appearence, "blink")) 2615536Ssos type = 1; 2626230Ssos else if (!strcmp(appearence, "destructive")) 2636230Ssos type = 3; 2645536Ssos else { 2658857Srgrimes fprintf(stderr, 2666230Ssos "argument to -c must be normal, blink or destructive\n"); 2672089Ssos return; 2682089Ssos } 2695536Ssos ioctl(0, CONS_CURSORTYPE, &type); 2702089Ssos} 2712089Ssos 27223457Sbrianvoid 2732089Ssosvideo_mode(int argc, char **argv, int *index) 2742089Ssos{ 2752089Ssos int mode; 2762089Ssos 2772089Ssos if (*index < argc) { 2782784Ssos if (!strcmp(argv[*index], "VGA_40x25")) 2792784Ssos mode = SW_VGA_C40x25; 2802784Ssos else if (!strcmp(argv[*index], "VGA_80x25")) 2812784Ssos mode = SW_VGA_C80x25; 2825536Ssos else if (!strcmp(argv[*index], "VGA_80x30")) 2835536Ssos mode = SW_VGA_C80x30; 2842784Ssos else if (!strcmp(argv[*index], "VGA_80x50")) 2852784Ssos mode = SW_VGA_C80x50; 2865536Ssos else if (!strcmp(argv[*index], "VGA_80x60")) 2875536Ssos mode = SW_VGA_C80x60; 2882784Ssos else if (!strcmp(argv[*index], "VGA_320x200")) 2892784Ssos mode = SW_VGA_CG320; 2902784Ssos else if (!strcmp(argv[*index], "EGA_80x25")) 2912784Ssos mode = SW_ENH_C80x25; 2922784Ssos else if (!strcmp(argv[*index], "EGA_80x43")) 2932784Ssos mode = SW_ENH_C80x43; 2942089Ssos else 2952089Ssos return; 2962089Ssos if (ioctl(0, mode, NULL) < 0) 2972089Ssos perror("Cannot set videomode"); 2982089Ssos (*index)++; 2992089Ssos } 3002089Ssos return; 3012089Ssos} 3028857Srgrimes 3032089Ssosint 3042089Ssosget_color_number(char *color) 3052089Ssos{ 3062089Ssos int i; 3072089Ssos 3082089Ssos for (i=0; i<16; i++) 3092089Ssos if (!strcmp(color, legal_colors[i])) 3102089Ssos return i; 3112089Ssos return -1; 3122089Ssos} 3132089Ssos 31423457Sbrianvoid 3152089Ssosset_normal_colors(int argc, char **argv, int *index) 3162089Ssos{ 3172089Ssos int color; 3182089Ssos 3192089Ssos if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 3202089Ssos (*index)++; 3212089Ssos fprintf(stderr, "[=%dF", color); 3228857Srgrimes if (*index < argc 3238857Srgrimes && (color = get_color_number(argv[*index])) != -1 3242089Ssos && color < 8) { 3252089Ssos (*index)++; 3262089Ssos fprintf(stderr, "[=%dG", color); 3272089Ssos } 3282089Ssos } 3292089Ssos} 3302089Ssos 33123457Sbrianvoid 3322089Ssosset_reverse_colors(int argc, char **argv, int *index) 3332089Ssos{ 3342089Ssos int color; 3352089Ssos 3362089Ssos if ((color = get_color_number(argv[*(index)-1])) != -1) { 3372089Ssos fprintf(stderr, "[=%dH", color); 3388857Srgrimes if (*index < argc 3398857Srgrimes && (color = get_color_number(argv[*index])) != -1 3402089Ssos && color < 8) { 3412089Ssos (*index)++; 3422089Ssos fprintf(stderr, "[=%dI", color); 3432089Ssos } 3442089Ssos } 3452089Ssos} 3462089Ssos 34723457Sbrianvoid 34823457Sbrianset_console(char *arg) 34923457Sbrian{ 35023457Sbrian int n; 35123457Sbrian 35223457Sbrian if( !arg || strspn(arg,"0123456789") != strlen(arg)) { 35323457Sbrian fprintf(stderr,"vidcontrol: Bad console number\n"); 35423457Sbrian usage(); 35523457Sbrian return; 35623457Sbrian } 35723457Sbrian 35823457Sbrian n = atoi(arg); 35923457Sbrian if (n < 1 || n > 12) { 36023457Sbrian fprintf(stderr,"vidcontrol: Console number out of range\n"); 36123457Sbrian usage(); 36223457Sbrian } else if (ioctl(0,VT_ACTIVATE,(char *)n) == -1) 36323457Sbrian perror("ioctl(VT_ACTIVATE)"); 36423457Sbrian} 36523457Sbrian 36623457Sbrianvoid 3672089Ssosset_border_color(char *arg) 3682089Ssos{ 3692089Ssos int color; 3702089Ssos 3712089Ssos if ((color = get_color_number(arg)) != -1) { 3722089Ssos fprintf(stderr, "[=%dA", color); 3732089Ssos } 3742089Ssos else 3758857Srgrimes usage(); 3762089Ssos} 3772089Ssos 37816565Ssosvoid 37916565Ssosset_mouse(char *arg) 38016565Ssos{ 38116565Ssos struct mouse_info mouse; 38216565Ssos 38316565Ssos if (!strcmp(arg, "on")) 38416565Ssos mouse.operation = MOUSE_SHOW; 38516565Ssos else if (!strcmp(arg, "off")) 38616565Ssos mouse.operation = MOUSE_HIDE; 38716565Ssos else { 38816565Ssos fprintf(stderr, 38916565Ssos "argument to -m must either on or off\n"); 39016565Ssos return; 39116565Ssos } 39216565Ssos ioctl(0, CONS_MOUSECTL, &mouse); 39316565Ssos} 39416565Ssos 39523457Sbrianvoid 3962089Ssostest_frame() 3972089Ssos{ 3982089Ssos int i; 3992089Ssos 4002089Ssos fprintf(stdout, "[=0G\n\n"); 4012089Ssos for (i=0; i<8; i++) { 4022089Ssos fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 4032089Ssos "[=15F[=0G %2d [=%dF%-16s " 4042089Ssos "[=15F %2d [=%dGBACKGROUND[=0G\n", 4058857Srgrimes i, i, legal_colors[i], i+8, i+8, 4068857Srgrimes legal_colors[i+8], i, i); 4072089Ssos } 4082089Ssos fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 4098857Srgrimes info.mv_norm.fore, info.mv_norm.back, 4102089Ssos info.mv_rev.fore, info.mv_rev.back); 4112089Ssos} 4122089Ssos 41323457Sbrianint 4142089Ssosmain(int argc, char **argv) 4152089Ssos{ 4162089Ssos extern char *optarg; 4172089Ssos extern int optind; 4182089Ssos int opt; 4192089Ssos 4208857Srgrimes 4212089Ssos info.size = sizeof(info); 4222089Ssos if (ioctl(0, CONS_GETINFO, &info) < 0) { 4236628Ssos perror("Must be on a virtual console"); 42423457Sbrian return 1; 4252089Ssos } 42623457Sbrian while((opt = getopt(argc, argv, "b:c:df:l:Lm:r:s:t:x")) != -1) 4272089Ssos switch(opt) { 42816565Ssos case 'b': 42916565Ssos set_border_color(optarg); 43016565Ssos break; 4312089Ssos case 'c': 4325536Ssos set_cursor_type(optarg); 4332089Ssos break; 4342089Ssos case 'd': 4352089Ssos print_scrnmap(); 4362089Ssos break; 4372089Ssos case 'f': 4382089Ssos load_font(optarg, 4392089Ssos nextarg(argc, argv, &optind, 'f')); 4402089Ssos break; 4412089Ssos case 'l': 4422089Ssos load_scrnmap(optarg); 4432089Ssos break; 4442089Ssos case 'L': 4452089Ssos load_default_scrnmap(); 4462089Ssos break; 44716565Ssos case 'm': 44816565Ssos set_mouse(optarg); 44916565Ssos break; 4502089Ssos case 'r': 4512089Ssos set_reverse_colors(argc, argv, &optind); 4522089Ssos break; 45323457Sbrian case 's': 45423457Sbrian set_console(optarg); 45523457Sbrian break; 4562089Ssos case 't': 4572089Ssos set_screensaver_timeout(optarg); 4582089Ssos break; 4592089Ssos case 'x': 4602089Ssos hex = 1; 4612089Ssos break; 4622089Ssos default: 4632089Ssos usage(); 46423457Sbrian return 1; 4652089Ssos } 46623457Sbrian video_mode(argc, argv, &optind); 46723457Sbrian set_normal_colors(argc, argv, &optind); 4682089Ssos if (optind < argc && !strcmp(argv[optind], "show")) { 4692089Ssos test_frame(); 4702089Ssos optind++; 4712089Ssos } 4722089Ssos if ((optind != argc) || (argc == 1)) { 4732089Ssos usage(); 47423457Sbrian return 1; 4752089Ssos } 47623457Sbrian return 0; 4772089Ssos} 4782089Ssos 479