1 /*- 2 * Copyright (c) 1994-1996 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.12 1996/06/21 07:20:13 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 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; 45 char letter; 46 struct vid_info info; 47 48 49 void 50 usage() 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 screenmap file filename)\n" 67 " -m on|off (switch mousepointer support on or off)\n" 68 " -L (load default screenmap)\n" 69 " -f DxL filename (load font, D dots wide & L lines high)\n" 70 " -t N (set screensaver timeout in seconds)\n" 71 " -x (use hex numbers for output)\n" 72 ); 73 } 74 75 char * 76 nextarg(int ac, char **av, int *indp, int oc) 77 { 78 if (*indp < ac) 79 return(av[(*indp)++]); 80 fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc); 81 usage(); 82 exit(1); 83 return(""); 84 } 85 86 char * 87 mkfullname(const char *s1, const char *s2, const char *s3) 88 { 89 static char *buf = NULL; 90 static int bufl = 0; 91 int f; 92 93 f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 94 if (f > bufl) 95 if (buf) 96 buf = (char *)realloc(buf, f); 97 else 98 buf = (char *)malloc(f); 99 if (!buf) { 100 bufl = 0; 101 return(NULL); 102 } 103 104 bufl = f; 105 strcpy(buf, s1); 106 strcat(buf, s2); 107 strcat(buf, s3); 108 return(buf); 109 } 110 111 void 112 load_scrnmap(char *filename) 113 { 114 FILE *fd; 115 int i, size; 116 char *name; 117 scrmap_t scrnmap; 118 char *prefix[] = {"", "", SCRNMAP_PATH, SCRNMAP_PATH, NULL}; 119 char *postfix[] = {"", ".scm", "", ".scm"}; 120 121 for (i=0; prefix[i]; i++) { 122 name = mkfullname(prefix[i], filename, postfix[i]); 123 if (fd = fopen(name, "r")) 124 break; 125 } 126 if (fd == NULL) { 127 perror("screenmap file not found"); 128 return; 129 } 130 size = sizeof(scrnmap); 131 if (decode(fd, &scrnmap) != size) { 132 rewind(fd); 133 if (fread(&scrnmap, 1, size, fd) != size) { 134 fprintf(stderr, "bad scrnmap file\n"); 135 close(fd); 136 return; 137 } 138 } 139 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 140 perror("can't load screenmap"); 141 close(fd); 142 } 143 144 void 145 load_default_scrnmap() 146 { 147 scrmap_t scrnmap; 148 int i; 149 150 for (i=0; i<256; i++) 151 *((char*)&scrnmap + i) = i; 152 if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 153 perror("can't load default screenmap"); 154 } 155 156 void 157 print_scrnmap() 158 { 159 unsigned char map[256]; 160 int i; 161 162 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 163 perror("getting scrnmap"); 164 return; 165 } 166 for (i=0; i<sizeof(map); i++) { 167 if (i > 0 && i % 16 == 0) 168 fprintf(stdout, "\n"); 169 if (hex) 170 fprintf(stdout, " %02x", map[i]); 171 else 172 fprintf(stdout, " %03d", map[i]); 173 } 174 fprintf(stdout, "\n"); 175 176 } 177 178 void 179 load_font(char *type, char *filename) 180 { 181 FILE *fd; 182 int i, io, size; 183 char *name, *fontmap; 184 char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL}; 185 char *postfix[] = {"", ".fnt", "", ".fnt"}; 186 187 for (i=0; prefix[i]; i++) { 188 name = mkfullname(prefix[i], filename, postfix[i]); 189 if (fd = fopen(name, "r")) 190 break; 191 } 192 if (fd == NULL) { 193 perror("font file not found"); 194 return; 195 } 196 if (!strcmp(type, "8x8")) { 197 size = 8*256; 198 io = PIO_FONT8x8; 199 } 200 else if (!strcmp(type, "8x14")) { 201 size = 14*256; 202 io = PIO_FONT8x14; 203 } 204 else if (!strcmp(type, "8x16")) { 205 size = 16*256; 206 io = PIO_FONT8x16; 207 } 208 else { 209 perror("bad font size specification"); 210 close(fd); 211 return; 212 } 213 fontmap = (char*) malloc(size); 214 if (decode(fd, fontmap) != size) { 215 rewind(fd); 216 if (fread(fontmap, 1, size, fd) != size) { 217 fprintf(stderr, "bad font file\n"); 218 close(fd); 219 free(fontmap); 220 return; 221 } 222 } 223 if (ioctl(0, io, fontmap) < 0) 224 perror("can't load font"); 225 close(fd); 226 free(fontmap); 227 } 228 229 void 230 set_screensaver_timeout(char *arg) 231 { 232 int nsec; 233 234 if (!strcmp(arg, "off")) 235 nsec = 0; 236 else { 237 nsec = atoi(arg); 238 if ((*arg == '\0') || (nsec < 1)) { 239 fprintf(stderr, "argument must be a positive number\n"); 240 return; 241 } 242 } 243 if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 244 perror("setting screensaver period"); 245 } 246 247 void 248 set_cursor_type(char *appearence) 249 { 250 int type; 251 252 if (!strcmp(appearence, "normal")) 253 type = 0; 254 else if (!strcmp(appearence, "blink")) 255 type = 1; 256 else if (!strcmp(appearence, "destructive")) 257 type = 3; 258 else { 259 fprintf(stderr, 260 "argument to -c must be normal, blink or destructive\n"); 261 return; 262 } 263 ioctl(0, CONS_CURSORTYPE, &type); 264 } 265 266 int 267 video_mode(int argc, char **argv, int *index) 268 { 269 int mode; 270 271 if (*index < argc) { 272 if (!strcmp(argv[*index], "VGA_40x25")) 273 mode = SW_VGA_C40x25; 274 else if (!strcmp(argv[*index], "VGA_80x25")) 275 mode = SW_VGA_C80x25; 276 else if (!strcmp(argv[*index], "VGA_80x30")) 277 mode = SW_VGA_C80x30; 278 else if (!strcmp(argv[*index], "VGA_80x50")) 279 mode = SW_VGA_C80x50; 280 else if (!strcmp(argv[*index], "VGA_80x60")) 281 mode = SW_VGA_C80x60; 282 else if (!strcmp(argv[*index], "VGA_320x200")) 283 mode = SW_VGA_CG320; 284 else if (!strcmp(argv[*index], "EGA_80x25")) 285 mode = SW_ENH_C80x25; 286 else if (!strcmp(argv[*index], "EGA_80x43")) 287 mode = SW_ENH_C80x43; 288 else 289 return; 290 if (ioctl(0, mode, NULL) < 0) 291 perror("Cannot set videomode"); 292 (*index)++; 293 } 294 return; 295 } 296 297 int 298 get_color_number(char *color) 299 { 300 int i; 301 302 for (i=0; i<16; i++) 303 if (!strcmp(color, legal_colors[i])) 304 return i; 305 return -1; 306 } 307 308 int 309 set_normal_colors(int argc, char **argv, int *index) 310 { 311 int color; 312 313 if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 314 (*index)++; 315 fprintf(stderr, "[=%dF", color); 316 if (*index < argc 317 && (color = get_color_number(argv[*index])) != -1 318 && color < 8) { 319 (*index)++; 320 fprintf(stderr, "[=%dG", color); 321 } 322 } 323 } 324 325 set_reverse_colors(int argc, char **argv, int *index) 326 { 327 int color; 328 329 if ((color = get_color_number(argv[*(index)-1])) != -1) { 330 fprintf(stderr, "[=%dH", color); 331 if (*index < argc 332 && (color = get_color_number(argv[*index])) != -1 333 && color < 8) { 334 (*index)++; 335 fprintf(stderr, "[=%dI", color); 336 } 337 } 338 } 339 340 set_border_color(char *arg) 341 { 342 int color; 343 344 if ((color = get_color_number(arg)) != -1) { 345 fprintf(stderr, "[=%dA", color); 346 } 347 else 348 usage(); 349 } 350 351 void 352 set_mouse(char *arg) 353 { 354 struct mouse_info mouse; 355 356 if (!strcmp(arg, "on")) 357 mouse.operation = MOUSE_SHOW; 358 else if (!strcmp(arg, "off")) 359 mouse.operation = MOUSE_HIDE; 360 else { 361 fprintf(stderr, 362 "argument to -m must either on or off\n"); 363 return; 364 } 365 ioctl(0, CONS_MOUSECTL, &mouse); 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 void 386 main(int argc, char **argv) 387 { 388 extern char *optarg; 389 extern int optind; 390 int opt; 391 392 393 info.size = sizeof(info); 394 if (ioctl(0, CONS_GETINFO, &info) < 0) { 395 perror("Must be on a virtual console"); 396 exit(1); 397 } 398 while((opt = getopt(argc, argv, "b:c:df:l:Lm:r:t:x")) != -1) 399 switch(opt) { 400 case 'b': 401 set_border_color(optarg); 402 break; 403 case 'c': 404 set_cursor_type(optarg); 405 break; 406 case 'd': 407 print_scrnmap(); 408 break; 409 case 'f': 410 load_font(optarg, 411 nextarg(argc, argv, &optind, 'f')); 412 break; 413 case 'l': 414 load_scrnmap(optarg); 415 break; 416 case 'L': 417 load_default_scrnmap(); 418 break; 419 case 'm': 420 set_mouse(optarg); 421 break; 422 case 'r': 423 set_reverse_colors(argc, argv, &optind); 424 break; 425 case 't': 426 set_screensaver_timeout(optarg); 427 break; 428 case 'x': 429 hex = 1; 430 break; 431 default: 432 usage(); 433 exit(1); 434 } 435 if (video_mode(argc, argv, &optind)) ; 436 if (set_normal_colors(argc, argv, &optind)) ; 437 if (optind < argc && !strcmp(argv[optind], "show")) { 438 test_frame(); 439 optind++; 440 } 441 if ((optind != argc) || (argc == 1)) { 442 usage(); 443 exit(1); 444 } 445 exit(0); 446 } 447 448