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