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