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