1 /*- 2 * Copyright (c) 1994 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.2 1994/09/15 07:28:06 sos 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_values(char *size) 268 { 269 int start, end; 270 int n; 271 char *v1; 272 273 start = strtol(size, &v1, 0); 274 if ((start < 0) || (*v1 != '.')) 275 goto badopt; 276 size = ++v1; 277 end = strtol(size, &v1, 0); 278 if ((end < 0) || (*size == '\0') || (*v1 != '\0')) { 279 badopt: 280 fprintf(stderr, 281 "argument to -c must be start.end\n"); 282 return; 283 } 284 if (verbose) 285 fprintf(stderr, "setting cursor to %d.%d\n", start, end); 286 fprintf(stdout, "[=%d;%dC", start, end); 287 } 288 289 290 int 291 video_mode(int argc, char **argv, int *index) 292 { 293 int mode; 294 295 if (*index < argc) { 296 if (!strcmp(argv[*index], "VGA_40x25")) 297 mode = SW_VGA_C40x25; 298 else if (!strcmp(argv[*index], "VGA_80x25")) 299 mode = SW_VGA_C80x25; 300 else if (!strcmp(argv[*index], "VGA_80x50")) 301 mode = SW_VGA_C80x50; 302 else if (!strcmp(argv[*index], "VGA_320x200")) 303 mode = SW_VGA_CG320; 304 else if (!strcmp(argv[*index], "EGA_80x25")) 305 mode = SW_ENH_C80x25; 306 else if (!strcmp(argv[*index], "EGA_80x43")) 307 mode = SW_ENH_C80x43; 308 else 309 return; 310 if (ioctl(0, mode, NULL) < 0) 311 perror("Cannot set videomode"); 312 (*index)++; 313 } 314 return; 315 } 316 317 318 int 319 get_color_number(char *color) 320 { 321 int i; 322 323 for (i=0; i<16; i++) 324 if (!strcmp(color, legal_colors[i])) 325 return i; 326 return -1; 327 } 328 329 330 int 331 set_normal_colors(int argc, char **argv, int *index) 332 { 333 int color; 334 335 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 336 (*index)++; 337 fprintf(stderr, "[=%dF", color); 338 if (*index < argc 339 && (color = get_color_number(argv[*index])) != -1 340 && color < 8) { 341 (*index)++; 342 fprintf(stderr, "[=%dG", color); 343 } 344 } 345 } 346 347 348 set_reverse_colors(int argc, char **argv, int *index) 349 { 350 int color; 351 352 if ((color = get_color_number(argv[*(index)-1])) != -1) { 353 fprintf(stderr, "[=%dH", color); 354 if (*index < argc 355 && (color = get_color_number(argv[*index])) != -1 356 && color < 8) { 357 (*index)++; 358 fprintf(stderr, "[=%dI", color); 359 } 360 } 361 } 362 363 364 set_border_color(char *arg) 365 { 366 int color; 367 368 if ((color = get_color_number(arg)) != -1) { 369 fprintf(stderr, "[=%dA", color); 370 } 371 else 372 usage(); 373 } 374 375 376 test_frame() 377 { 378 int i; 379 380 fprintf(stdout, "[=0G\n\n"); 381 for (i=0; i<8; i++) { 382 fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 383 "[=15F[=0G %2d [=%dF%-16s " 384 "[=15F %2d [=%dGBACKGROUND[=0G\n", 385 i, i, legal_colors[i], i+8, i+8, 386 legal_colors[i+8], i, i); 387 } 388 fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 389 info.mv_norm.fore, info.mv_norm.back, 390 info.mv_rev.fore, info.mv_rev.back); 391 } 392 393 394 usage() 395 { 396 fprintf(stderr, 397 "Usage: vidcontrol mode (available modes: VGA_40x25, VGA_80x25,\n" 398 " VGA_80x50, VGA_320x200,\n" 399 " EGA_80x25, EGA_80x43)\n" 400 " show (show available colors)\n" 401 " fgcol bgcol (set fore- & background colors)\n" 402 " -r fgcol bgcol (set reverse fore- & background colors)\n" 403 " -b color (set border color)\n" 404 " -c n.m (set cursor start line n & end line m)\n" 405 " -d (dump screenmap to stdout)\n" 406 " -l filename (load srceenmap file filename)\n" 407 " -L (load default screenmap)\n" 408 " -f DxL filename (load font, D dots wide & L lines high)\n" 409 " -s saver | help (set screensaver type or help for a list)\n" 410 " -t N (set screensaver timeout in seconds)\n" 411 " -x (use hex numbers for output)\n" 412 ); 413 } 414 415 416 void 417 main(int argc, char **argv) 418 { 419 extern char *optarg; 420 extern int optind; 421 int opt; 422 423 424 info.size = sizeof(info); 425 if (ioctl(0, CONS_GETINFO, &info) < 0) { 426 perror("Must be on a vty"); 427 exit(1); 428 } 429 while((opt = getopt(argc, argv, "b:c:df:l:Lr:s:t:vx")) != -1) 430 switch(opt) { 431 case 'c': 432 set_cursor_values(optarg); 433 break; 434 case 'b': 435 set_border_color(optarg); 436 break; 437 case 'd': 438 print_scrnmap(); 439 break; 440 case 'f': 441 load_font(optarg, 442 nextarg(argc, argv, &optind, 'f')); 443 break; 444 case 'l': 445 load_scrnmap(optarg); 446 break; 447 case 'L': 448 load_default_scrnmap(); 449 break; 450 case 'r': 451 set_reverse_colors(argc, argv, &optind); 452 break; 453 case 's': 454 set_screensaver_type(optarg); 455 break; 456 case 't': 457 set_screensaver_timeout(optarg); 458 break; 459 case 'v': 460 verbose = 1; 461 break; 462 case 'x': 463 hex = 1; 464 break; 465 default: 466 usage(); 467 exit(1); 468 } 469 if (video_mode(argc, argv, &optind)) ; 470 if (set_normal_colors(argc, argv, &optind)) ; 471 if (optind < argc && !strcmp(argv[optind], "show")) { 472 test_frame(); 473 optind++; 474 } 475 if ((optind != argc) || (argc == 1)) { 476 usage(); 477 exit(1); 478 } 479 exit(0); 480 } 481 482