vidcontrol.c revision 6862
1/*- 2 * Copyright (c) 1994-1995 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 * $Id: vidcontrol.c,v 1.9 1995/02/22 13:41:27 sos Exp $ 29 */ 30 31#include <ctype.h> 32#include <stdio.h> 33#include <machine/console.h> 34#include <sys/errno.h> 35#include "path.h" 36 37char legal_colors[16][16] = { 38 "black", "blue", "green", "cyan", 39 "red", "magenta", "brown", "white", 40 "grey", "lightblue", "lightgreen", "lightcyan", 41 "lightred", "lightmagenta", "yellow", "lightwhite" 42}; 43int hex = 0; 44int number; 45char letter; 46struct vid_info info; 47 48 49void 50usage() 51{ 52 fprintf(stderr, 53"Usage: vidcontrol mode (available modes: VGA_40x25, VGA_80x25,\n" 54" VGA_80x50, VGA_320x200,\n" 55" EGA_80x25, EGA_80x43)\n" 56" (experimental) VGA_80x30, VGA_80x60)\n" 57"\n" 58" show (show available colors)\n" 59" fgcol bgcol (set fore- & background colors)\n" 60" -r fgcol bgcol (set reverse fore- & background colors)\n" 61" -b color (set border color)\n" 62" -c normal (set cursor to inverting block)\n" 63" -c blink (set cursor to blinking inverted block)\n" 64" -c destructive (set cursor to blinking destructive char)\n" 65" -d (dump screenmap to stdout)\n" 66" -l filename (load srceenmap file filename)\n" 67" -L (load default screenmap)\n" 68" -f DxL filename (load font, D dots wide & L lines high)\n" 69" -t N (set screensaver timeout in seconds)\n" 70" -x (use hex numbers for output)\n" 71 ); 72} 73 74char * 75nextarg(int ac, char **av, int *indp, int oc) 76{ 77 if (*indp < ac) 78 return(av[(*indp)++]); 79 fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc); 80 usage(); 81 exit(1); 82 return(""); 83} 84 85char * 86mkfullname(const char *s1, const char *s2, const char *s3) 87{ 88 static char *buf = NULL; 89 static int bufl = 0; 90 int f; 91 92 f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 93 if (f > bufl) 94 if (buf) 95 buf = (char *)realloc(buf, f); 96 else 97 buf = (char *)malloc(f); 98 if (!buf) { 99 bufl = 0; 100 return(NULL); 101 } 102 103 bufl = f; 104 strcpy(buf, s1); 105 strcat(buf, s2); 106 strcat(buf, s3); 107 return(buf); 108} 109 110void 111load_scrnmap(char *filename) 112{ 113 FILE *fd; 114 int i, size; 115 char *name; 116 scrmap_t scrnmap; 117 char *prefix[] = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL}; 118 char *postfix[] = {"", ".scm", "", ".scm"}; 119 120 for (i=0; prefix[i]; i++) { 121 name = mkfullname(prefix[i], filename, postfix[i]); 122 if (fd = fopen(name, "r")) 123 break; 124 } 125 if (fd == NULL) { 126 perror("screenmap file not found"); 127 return; 128 } 129 size = sizeof(scrnmap); 130 if (decode(fd, &scrnmap) != size) { 131 rewind(fd); 132 if (fread(&scrnmap, 1, size, fd) != size) { 133 fprintf(stderr, "bad scrnmap file\n"); 134 close(fd); 135 return; 136 } 137 } 138 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 139 perror("can't load screenmap"); 140 close(fd); 141} 142 143void 144load_default_scrnmap() 145{ 146 scrmap_t scrnmap; 147 int i; 148 149 for (i=0; i<256; i++) 150 *((char*)&scrnmap + i) = i; 151 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 152 perror("can't load default screenmap"); 153} 154 155void 156print_scrnmap() 157{ 158 unsigned char map[256]; 159 int i; 160 161 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 162 perror("getting scrnmap"); 163 return; 164 } 165 for (i=0; i<sizeof(map); i++) { 166 if (i > 0 && i % 16 == 0) 167 fprintf(stdout, "\n"); 168 if (hex) 169 fprintf(stdout, " %02x", map[i]); 170 else 171 fprintf(stdout, " %03d", map[i]); 172 } 173 fprintf(stdout, "\n"); 174 175} 176 177void 178load_font(char *type, char *filename) 179{ 180 FILE *fd; 181 int i, io, size; 182 char *name, *fontmap; 183 char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL}; 184 char *postfix[] = {"", ".fnt", "", ".fnt"}; 185 186 for (i=0; prefix[i]; i++) { 187 name = mkfullname(prefix[i], filename, postfix[i]); 188 if (fd = fopen(name, "r")) 189 break; 190 } 191 if (fd == NULL) { 192 perror("font file not found"); 193 return; 194 } 195 if (!strcmp(type, "8x8")) { 196 size = 8*256; 197 io = PIO_FONT8x8; 198 } 199 else if (!strcmp(type, "8x14")) { 200 size = 14*256; 201 io = PIO_FONT8x14; 202 } 203 else if (!strcmp(type, "8x16")) { 204 size = 16*256; 205 io = PIO_FONT8x16; 206 } 207 else { 208 perror("bad font size specification"); 209 close(fd); 210 return; 211 } 212 fontmap = (char*) malloc(size); 213 if (decode(fd, fontmap) != size) { 214 rewind(fd); 215 if (fread(fontmap, 1, size, fd) != size) { 216 fprintf(stderr, "bad font file\n"); 217 close(fd); 218 free(fontmap); 219 return; 220 } 221 } 222 if (ioctl(0, io, fontmap) < 0) 223 perror("can't load font"); 224 close(fd); 225 free(fontmap); 226} 227 228void 229set_screensaver_timeout(char *arg) 230{ 231 int nsec; 232 233 if (!strcmp(arg, "off")) 234 nsec = 0; 235 else { 236 nsec = atoi(arg); 237 if ((*arg == '\0') || (nsec < 1)) { 238 fprintf(stderr, "argument must be a positive number\n"); 239 return; 240 } 241 } 242 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 243 perror("setting screensaver period"); 244} 245 246void 247set_cursor_type(char *appearence) 248{ 249 int type; 250 251 if (!strcmp(appearence, "normal")) 252 type = 0; 253 else if (!strcmp(appearence, "blink")) 254 type = 1; 255 else if (!strcmp(appearence, "destructive")) 256 type = 3; 257 else { 258 fprintf(stderr, 259 "argument to -c must be normal, blink or destructive\n"); 260 return; 261 } 262 ioctl(0, CONS_CURSORTYPE, &type); 263} 264 265int 266video_mode(int argc, char **argv, int *index) 267{ 268 int mode; 269 270 if (*index < argc) { 271 if (!strcmp(argv[*index], "VGA_40x25")) 272 mode = SW_VGA_C40x25; 273 else if (!strcmp(argv[*index], "VGA_80x25")) 274 mode = SW_VGA_C80x25; 275 else if (!strcmp(argv[*index], "VGA_80x30")) 276 mode = SW_VGA_C80x30; 277 else if (!strcmp(argv[*index], "VGA_80x50")) 278 mode = SW_VGA_C80x50; 279 else if (!strcmp(argv[*index], "VGA_80x60")) 280 mode = SW_VGA_C80x60; 281 else if (!strcmp(argv[*index], "VGA_320x200")) 282 mode = SW_VGA_CG320; 283 else if (!strcmp(argv[*index], "EGA_80x25")) 284 mode = SW_ENH_C80x25; 285 else if (!strcmp(argv[*index], "EGA_80x43")) 286 mode = SW_ENH_C80x43; 287 else 288 return; 289 if (ioctl(0, mode, NULL) < 0) 290 perror("Cannot set videomode"); 291 (*index)++; 292 } 293 return; 294} 295 296int 297get_color_number(char *color) 298{ 299 int i; 300 301 for (i=0; i<16; i++) 302 if (!strcmp(color, legal_colors[i])) 303 return i; 304 return -1; 305} 306 307int 308set_normal_colors(int argc, char **argv, int *index) 309{ 310 int color; 311 312 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 313 (*index)++; 314 fprintf(stderr, "[=%dF", color); 315 if (*index < argc 316 && (color = get_color_number(argv[*index])) != -1 317 && color < 8) { 318 (*index)++; 319 fprintf(stderr, "[=%dG", color); 320 } 321 } 322} 323 324set_reverse_colors(int argc, char **argv, int *index) 325{ 326 int color; 327 328 if ((color = get_color_number(argv[*(index)-1])) != -1) { 329 fprintf(stderr, "[=%dH", color); 330 if (*index < argc 331 && (color = get_color_number(argv[*index])) != -1 332 && color < 8) { 333 (*index)++; 334 fprintf(stderr, "[=%dI", color); 335 } 336 } 337} 338 339set_border_color(char *arg) 340{ 341 int color; 342 343 if ((color = get_color_number(arg)) != -1) { 344 fprintf(stderr, "[=%dA", color); 345 } 346 else 347 usage(); 348} 349 350test_frame() 351{ 352 int i; 353 354 fprintf(stdout, "[=0G\n\n"); 355 for (i=0; i<8; i++) { 356 fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 357 "[=15F[=0G %2d [=%dF%-16s " 358 "[=15F %2d [=%dGBACKGROUND[=0G\n", 359 i, i, legal_colors[i], i+8, i+8, 360 legal_colors[i+8], i, i); 361 } 362 fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 363 info.mv_norm.fore, info.mv_norm.back, 364 info.mv_rev.fore, info.mv_rev.back); 365} 366 367void 368main(int argc, char **argv) 369{ 370 extern char *optarg; 371 extern int optind; 372 int opt; 373 374 375 info.size = sizeof(info); 376 if (ioctl(0, CONS_GETINFO, &info) < 0) { 377 perror("Must be on a virtual console"); 378 exit(1); 379 } 380 while((opt = getopt(argc, argv, "b:c:df:l:Lr:t:x")) != -1) 381 switch(opt) { 382 case 'c': 383 set_cursor_type(optarg); 384 break; 385 case 'b': 386 set_border_color(optarg); 387 break; 388 case 'd': 389 print_scrnmap(); 390 break; 391 case 'f': 392 load_font(optarg, 393 nextarg(argc, argv, &optind, 'f')); 394 break; 395 case 'l': 396 load_scrnmap(optarg); 397 break; 398 case 'L': 399 load_default_scrnmap(); 400 break; 401 case 'r': 402 set_reverse_colors(argc, argv, &optind); 403 break; 404 case 't': 405 set_screensaver_timeout(optarg); 406 break; 407 case 'x': 408 hex = 1; 409 break; 410 default: 411 usage(); 412 exit(1); 413 } 414 if (video_mode(argc, argv, &optind)) ; 415 if (set_normal_colors(argc, argv, &optind)) ; 416 if (optind < argc && !strcmp(argv[optind], "show")) { 417 test_frame(); 418 optind++; 419 } 420 if ((optind != argc) || (argc == 1)) { 421 usage(); 422 exit(1); 423 } 424 exit(0); 425} 426 427