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