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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software withough specific prior written permission 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * $Id: vidcontrol.c,v 1.3 1994/09/26 20:20:44 ache Exp $ 28 */ 29 30 #include <ctype.h> 31 #include <stdio.h> 32 #include <machine/console.h> 33 #include <sys/errno.h> 34 #include "path.h" 35 36 37 char 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 }; 43 int hex = 0; 44 int number, verbose = 0; 45 char letter; 46 struct vid_info info; 47 48 49 char * 50 nextarg(int ac, char **av, int *indp, int oc) 51 { 52 if (*indp < ac) 53 return(av[(*indp)++]); 54 fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc); 55 usage(); 56 exit(1); 57 return(""); 58 } 59 60 61 char * 62 mkfullname(const char *s1, const char *s2, const char *s3) 63 { 64 static char *buf = NULL; 65 static int bufl = 0; 66 int f; 67 68 69 f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 70 if (f > bufl) 71 if (buf) 72 buf = (char *)realloc(buf, f); 73 else 74 buf = (char *)malloc(f); 75 if (!buf) { 76 bufl = 0; 77 return(NULL); 78 } 79 80 bufl = f; 81 strcpy(buf, s1); 82 strcat(buf, s2); 83 strcat(buf, s3); 84 return(buf); 85 } 86 87 88 void 89 load_scrnmap(char *filename) 90 { 91 FILE *fd; 92 int i, size; 93 char *name; 94 scrmap_t scrnmap; 95 char *prefix[] = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL}; 96 char *postfix[] = {"", ".scm", "", ".scm"}; 97 98 for (i=0; prefix[i]; i++) { 99 name = mkfullname(prefix[i], filename, postfix[i]); 100 if (fd = fopen(name, "r")) 101 break; 102 } 103 if (fd == NULL) { 104 perror("screenmap file not found"); 105 return; 106 } 107 size = sizeof(scrnmap); 108 if (decode(fd, &scrnmap) != size) { 109 rewind(fd); 110 if (fread(&scrnmap, 1, size, fd) != size) { 111 fprintf(stderr, "bad scrnmap file\n"); 112 close(fd); 113 return; 114 } 115 } 116 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 117 perror("can't load screenmap"); 118 close(fd); 119 } 120 121 122 void 123 load_default_scrnmap() 124 { 125 int i; 126 scrmap_t scrnmap; 127 128 for (i=0; i<256; i++) 129 *((char*)&scrnmap + i) = i; 130 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 131 perror("can't load default screenmap"); 132 } 133 134 135 void 136 print_scrnmap() 137 { 138 unsigned char map[256]; 139 int i; 140 141 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 142 perror("getting scrnmap"); 143 return; 144 } 145 for (i=0; i<sizeof(map); i++) { 146 if (i > 0 && i % 16 == 0) 147 fprintf(stdout, "\n"); 148 if (hex) 149 fprintf(stdout, " %02x", map[i]); 150 else 151 fprintf(stdout, " %03d", map[i]); 152 } 153 fprintf(stdout, "\n"); 154 155 } 156 157 158 void 159 load_font(char *type, char *filename) 160 { 161 FILE *fd; 162 int i, io, size; 163 char *name, *fontmap; 164 char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL}; 165 char *postfix[] = {"", ".fnt", "", ".fnt"}; 166 167 for (i=0; prefix[i]; i++) { 168 name = mkfullname(prefix[i], filename, postfix[i]); 169 if (fd = fopen(name, "r")) 170 break; 171 } 172 if (fd == NULL) { 173 perror("font file not found"); 174 return; 175 } 176 if (!strcmp(type, "8x8")) { 177 size = 8*256; 178 io = PIO_FONT8x8; 179 } 180 else if (!strcmp(type, "8x14")) { 181 size = 14*256; 182 io = PIO_FONT8x14; 183 } 184 else if (!strcmp(type, "8x16")) { 185 size = 16*256; 186 io = PIO_FONT8x16; 187 } 188 else { 189 perror("bad font size specification"); 190 close(fd); 191 return; 192 } 193 fontmap = (char*) malloc(size); 194 if (decode(fd, fontmap) != size) { 195 rewind(fd); 196 if (fread(fontmap, 1, size, fd) != size) { 197 fprintf(stderr, "bad font file\n"); 198 close(fd); 199 free(fontmap); 200 return; 201 } 202 } 203 if (ioctl(0, io, fontmap) < 0) 204 perror("can't load font"); 205 close(fd); 206 free(fontmap); 207 } 208 209 210 void 211 set_screensaver_timeout(char *arg) 212 { 213 int nsec; 214 215 if (!strcmp(arg, "off")) 216 nsec = 0; 217 else { 218 nsec = atoi(arg); 219 if ((*arg == '\0') || (nsec < 1)) { 220 fprintf(stderr, "argument must be a positive number\n"); 221 return; 222 } 223 } 224 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 225 perror("setting screensaver period"); 226 } 227 228 229 void 230 set_screensaver_type(char *type) 231 { 232 ssaver_t saver; 233 int i, e; 234 235 if (!strcmp(type, "help")) { 236 i = 0; 237 printf("available screen saver types:\n"); 238 do { 239 saver.num = i; 240 e = ioctl(0, CONS_GSAVER, &saver); 241 i ++; 242 if (e == 0) 243 printf("\t%s\n", saver.name); 244 } while (e == 0); 245 if (e == -1 && errno != EIO) 246 perror("getting screensaver info"); 247 } else { 248 i = 0; 249 do { 250 saver.num = i; 251 e = ioctl(0, CONS_GSAVER, &saver); 252 i ++; 253 if (e == 0 && !strcmp(type, saver.name)) { 254 if (ioctl(0, CONS_SSAVER, &saver) == -1) 255 perror("setting screensaver type"); 256 return; 257 } 258 } while (e == 0); 259 if (e == -1 && errno != EIO) 260 perror("getting screensaver info"); 261 else 262 fprintf(stderr, "%s: No such screensaver\n", type); 263 } 264 } 265 266 void 267 set_cursor_type(char *appearence) 268 { 269 int type; 270 271 if (!strcmp(appearence, "blink")) 272 type = 1; 273 else if (!strcmp(appearence, "noblink")) 274 type = 0; 275 else { 276 fprintf(stderr, "argument to -c must be blink or noblink\n"); 277 return; 278 } 279 ioctl(0, CONS_CURSORTYPE, &type); 280 } 281 282 283 int 284 video_mode(int argc, char **argv, int *index) 285 { 286 int mode; 287 288 if (*index < argc) { 289 if (!strcmp(argv[*index], "VGA_40x25")) 290 mode = SW_VGA_C40x25; 291 else if (!strcmp(argv[*index], "VGA_80x25")) 292 mode = SW_VGA_C80x25; 293 else if (!strcmp(argv[*index], "VGA_80x30")) 294 mode = SW_VGA_C80x30; 295 else if (!strcmp(argv[*index], "VGA_80x50")) 296 mode = SW_VGA_C80x50; 297 else if (!strcmp(argv[*index], "VGA_80x60")) 298 mode = SW_VGA_C80x60; 299 else if (!strcmp(argv[*index], "VGA_320x200")) 300 mode = SW_VGA_CG320; 301 else if (!strcmp(argv[*index], "EGA_80x25")) 302 mode = SW_ENH_C80x25; 303 else if (!strcmp(argv[*index], "EGA_80x43")) 304 mode = SW_ENH_C80x43; 305 else 306 return; 307 if (ioctl(0, mode, NULL) < 0) 308 perror("Cannot set videomode"); 309 (*index)++; 310 } 311 return; 312 } 313 314 315 int 316 get_color_number(char *color) 317 { 318 int i; 319 320 for (i=0; i<16; i++) 321 if (!strcmp(color, legal_colors[i])) 322 return i; 323 return -1; 324 } 325 326 327 int 328 set_normal_colors(int argc, char **argv, int *index) 329 { 330 int color; 331 332 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 333 (*index)++; 334 fprintf(stderr, "[=%dF", color); 335 if (*index < argc 336 && (color = get_color_number(argv[*index])) != -1 337 && color < 8) { 338 (*index)++; 339 fprintf(stderr, "[=%dG", color); 340 } 341 } 342 } 343 344 345 set_reverse_colors(int argc, char **argv, int *index) 346 { 347 int color; 348 349 if ((color = get_color_number(argv[*(index)-1])) != -1) { 350 fprintf(stderr, "[=%dH", color); 351 if (*index < argc 352 && (color = get_color_number(argv[*index])) != -1 353 && color < 8) { 354 (*index)++; 355 fprintf(stderr, "[=%dI", color); 356 } 357 } 358 } 359 360 361 set_border_color(char *arg) 362 { 363 int color; 364 365 if ((color = get_color_number(arg)) != -1) { 366 fprintf(stderr, "[=%dA", color); 367 } 368 else 369 usage(); 370 } 371 372 373 test_frame() 374 { 375 int i; 376 377 fprintf(stdout, "[=0G\n\n"); 378 for (i=0; i<8; i++) { 379 fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 380 "[=15F[=0G %2d [=%dF%-16s " 381 "[=15F %2d [=%dGBACKGROUND[=0G\n", 382 i, i, legal_colors[i], i+8, i+8, 383 legal_colors[i+8], i, i); 384 } 385 fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 386 info.mv_norm.fore, info.mv_norm.back, 387 info.mv_rev.fore, info.mv_rev.back); 388 } 389 390 391 usage() 392 { 393 fprintf(stderr, 394 "Usage: vidcontrol mode (available modes: VGA_40x25, VGA_80x25,\n" 395 " VGA_80x50, VGA_320x200,\n" 396 " EGA_80x25, EGA_80x43)\n" 397 " show (show available colors)\n" 398 " fgcol bgcol (set fore- & background colors)\n" 399 " -r fgcol bgcol (set reverse fore- & background colors)\n" 400 " -b color (set border color)\n" 401 " -c blink | noblink (set cursor type)\n" 402 " -d (dump screenmap to stdout)\n" 403 " -l filename (load srceenmap file filename)\n" 404 " -L (load default screenmap)\n" 405 " -f DxL filename (load font, D dots wide & L lines high)\n" 406 " -s saver | help (set screensaver type or help for a list)\n" 407 " -t N (set screensaver timeout in seconds)\n" 408 " -x (use hex numbers for output)\n" 409 ); 410 } 411 412 413 void 414 main(int argc, char **argv) 415 { 416 extern char *optarg; 417 extern int optind; 418 int opt; 419 420 421 info.size = sizeof(info); 422 if (ioctl(0, CONS_GETINFO, &info) < 0) { 423 perror("Must be on a vrtual console"); 424 exit(1); 425 } 426 while((opt = getopt(argc, argv, "b:c:df:l:Lr:s:t:vx")) != -1) 427 switch(opt) { 428 case 'c': 429 set_cursor_type(optarg); 430 break; 431 case 'b': 432 set_border_color(optarg); 433 break; 434 case 'd': 435 print_scrnmap(); 436 break; 437 case 'f': 438 load_font(optarg, 439 nextarg(argc, argv, &optind, 'f')); 440 break; 441 case 'l': 442 load_scrnmap(optarg); 443 break; 444 case 'L': 445 load_default_scrnmap(); 446 break; 447 case 'r': 448 set_reverse_colors(argc, argv, &optind); 449 break; 450 case 's': 451 set_screensaver_type(optarg); 452 break; 453 case 't': 454 set_screensaver_timeout(optarg); 455 break; 456 case 'v': 457 verbose = 1; 458 break; 459 case 'x': 460 hex = 1; 461 break; 462 default: 463 usage(); 464 exit(1); 465 } 466 if (video_mode(argc, argv, &optind)) ; 467 if (set_normal_colors(argc, argv, &optind)) ; 468 if (optind < argc && !strcmp(argv[optind], "show")) { 469 test_frame(); 470 optind++; 471 } 472 if ((optind != argc) || (argc == 1)) { 473 usage(); 474 exit(1); 475 } 476 exit(0); 477 } 478 479