2 * Copyright (c) 1992,1993,1994 Hellmuth Michaelis and Joerg Wunsch
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by
17 * Hellmuth Michaelis and Joerg Wunsch
18 * 4. The name authors may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * $FreeBSD: src/usr.sbin/pcvt/scon/scon.c,v 1.5.6.1 2001/05/12 10:11:42 kris Exp $
36 "@(#)scon.c, 3.20, Last Edit-Date: [Sun Sep 25 12:33:21 1994]";
38 /*---------------------------------------------------------------------------*
42 * -hm moving fd for default device from 1 -> 0 for such things
43 * as "scon -p list | more" to be possible
44 * (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org)
45 * -hm adding option "a" for just returning the type of video adaptor
46 * -hm removing explicit HGC support, same as MDA ...
47 * -hm vga type/family/132col support info on -l
48 * -hm force 24 lines in DEC 25 lines mode and HP 28 lines mode
49 * -hm fixed bug with 132 column mode display status display
50 * -jw added 132/80 col mode switching
51 * -hm removed -h flag, use -? now ... ;-)
53 * -hm Cirrus chipsets support from Onno van der Linden
54 * -hm -m option, display monitor type
55 * -hm bugfix, scon -c <screen-num> cleared dest screen, fixed
57 *---------------------------------------------------------------------------*/
62 #include <machine/pcvt_ioctl.h>
83 struct screeninfo screeninfo;
92 static struct rgb palette[NVGAPEL] = {
93 { 0x00, 0x00, 0x00, 0}, /* 0 - black */
94 { 0x00, 0x00, 0x2a, 0}, /* 1 - blue */
95 { 0x00, 0x2a, 0x00, 0}, /* 2 - green */
96 { 0x00, 0x2a, 0x2a, 0}, /* 3 - cyan */
97 { 0x2a, 0x00, 0x00, 0}, /* 4 - red */
98 { 0x2a, 0x00, 0x2a, 0}, /* 5 - magenta */
99 { 0x2a, 0x2a, 0x00, 0}, /* 6 */
100 { 0x2a, 0x2a, 0x2a, 0}, /* 7 - lightgray */
101 { 0x00, 0x00, 0x15, 0}, /* 8 */
102 { 0x00, 0x00, 0x3f, 0}, /* 9 */
103 { 0x00, 0x2a, 0x15, 0}, /* 10 */
104 { 0x00, 0x2a, 0x3f, 0}, /* 11 */
105 { 0x2a, 0x00, 0x15, 0}, /* 12 */
106 { 0x2a, 0x00, 0x3f, 0}, /* 13 */
107 { 0x2a, 0x2a, 0x15, 0}, /* 14 */
108 { 0x2a, 0x2a, 0x3f, 0}, /* 15 */
109 { 0x00, 0x15, 0x00, 0}, /* 16 */
110 { 0x00, 0x15, 0x2a, 0}, /* 17 */
111 { 0x00, 0x3f, 0x00, 0}, /* 18 */
112 { 0x00, 0x3f, 0x2a, 0}, /* 19 */
113 { 0x2a, 0x15, 0x00, 0}, /* 20 - brown */
114 { 0x2a, 0x15, 0x2a, 0}, /* 21 */
115 { 0x2a, 0x3f, 0x00, 0}, /* 22 */
116 { 0x2a, 0x3f, 0x2a, 0}, /* 23 */
117 { 0x00, 0x15, 0x15, 0}, /* 24 */
118 { 0x00, 0x15, 0x3f, 0}, /* 25 */
119 { 0x00, 0x3f, 0x15, 0}, /* 26 */
120 { 0x00, 0x3f, 0x3f, 0}, /* 27 */
121 { 0x2a, 0x15, 0x15, 0}, /* 28 */
122 { 0x2a, 0x15, 0x3f, 0}, /* 29 */
123 { 0x2a, 0x3f, 0x15, 0}, /* 30 */
124 { 0x2a, 0x3f, 0x3f, 0}, /* 31 */
125 { 0x15, 0x00, 0x00, 0}, /* 32 */
126 { 0x15, 0x00, 0x2a, 0}, /* 33 */
127 { 0x15, 0x2a, 0x00, 0}, /* 34 */
128 { 0x15, 0x2a, 0x2a, 0}, /* 35 */
129 { 0x3f, 0x00, 0x00, 0}, /* 36 */
130 { 0x3f, 0x00, 0x2a, 0}, /* 37 */
131 { 0x3f, 0x2a, 0x00, 0}, /* 38 */
132 { 0x3f, 0x2a, 0x2a, 0}, /* 39 */
133 { 0x15, 0x00, 0x15, 0}, /* 40 */
134 { 0x15, 0x00, 0x3f, 0}, /* 41 */
135 { 0x15, 0x2a, 0x15, 0}, /* 42 */
136 { 0x15, 0x2a, 0x3f, 0}, /* 43 */
137 { 0x3f, 0x00, 0x15, 0}, /* 44 */
138 { 0x3f, 0x00, 0x3f, 0}, /* 45 */
139 { 0x3f, 0x2a, 0x15, 0}, /* 46 */
140 { 0x3f, 0x2a, 0x3f, 0}, /* 47 */
141 { 0x15, 0x15, 0x00, 0}, /* 48 */
142 { 0x15, 0x15, 0x2a, 0}, /* 49 */
143 { 0x15, 0x3f, 0x00, 0}, /* 50 */
144 { 0x15, 0x3f, 0x2a, 0}, /* 51 */
145 { 0x3f, 0x15, 0x00, 0}, /* 52 */
146 { 0x3f, 0x15, 0x2a, 0}, /* 53 */
147 { 0x3f, 0x3f, 0x00, 0}, /* 54 */
148 { 0x3f, 0x3f, 0x2a, 0}, /* 55 */
149 { 0x15, 0x15, 0x15, 0}, /* 56 - darkgray */
150 { 0x15, 0x15, 0x3f, 0}, /* 57 - lightblue */
151 { 0x15, 0x3f, 0x15, 0}, /* 58 - lightgreen */
152 { 0x15, 0x3f, 0x3f, 0}, /* 59 - lightcyan */
153 { 0x3f, 0x15, 0x15, 0}, /* 60 - lightred */
154 { 0x3f, 0x15, 0x3f, 0}, /* 61 - lightmagenta */
155 { 0x3f, 0x3f, 0x15, 0}, /* 62 - yellow */
156 { 0x3f, 0x3f, 0x3f, 0}, /* 63 - white */
157 { 0x00, 0x00, 0x00, 0} /* 64 ... - empty */
160 static struct colname {
179 {"lightmagenta", 61},
182 /* must be terminator: */ {(const char *)NULL, 0}
186 static void parsepopt(char *arg, unsigned *idx,
187 unsigned *r, unsigned *g, unsigned *b);
188 static void printpalette(int fd);
201 while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != -1)
218 current = atoi(optarg);
240 if (!strncmp(optarg, "25", 2))
242 else if(!strncmp(optarg, "28", 2))
244 else if(!strncmp(optarg, "35", 2))
246 else if(!strncmp(optarg, "40", 2))
248 else if(!strncmp(optarg, "43", 2))
250 else if(!strncmp(optarg, "50", 2))
259 if(!strcmp(optarg, "list"))
262 errx(2, "-p list is mutual exclusive with other -p options");
265 else if(!strcmp(optarg, "default"))
268 errx(2, "multiple -p default not allowed");
271 unsigned idx, r, g, b;
274 errx(2, "-p default and -p i,r,g,b ambiguous");
276 parsepopt(optarg, &idx, &r, &g, &b);
278 errx(2, "index %u in -p option out of range", idx);
282 palette[idx].dothis = 1;
288 timeout = atoi(optarg);
306 if((pflag == 1) && (hflag == 1))
309 if(dflag == -1 && lflag == -1 && current == -1 && pflag == -1 &&
310 hflag == -1 && res == -1 && Pflag == 0 && tflag == 0 && fflag == -1
311 && colms == 0 && mflag == -1)
319 printf("using current device\n");
320 fd = DEFAULTFD; /* -hm, Feb 12 1993 */
324 if((fd = open(device, O_RDWR)) == -1)
325 err(1, "ERROR opening %s", device);
327 printf("using device %s\n",device);
330 if(aflag == 1) /* return adaptor type */
336 if(mflag == 1) /* return monitor type */
342 if(lflag == 1) /* list information */
345 printf("processing option -l, listing screen info\n");
350 if(tflag) /* set screen saver timeout */
355 "processing option -t, setting screen saver timeout: "
358 printf("new timeout = %d s\n", timeout);
360 printf("turned off\n");
363 if(ioctl(fd, VGASCREENSAVER, &timeout) < 0)
365 warn("ioctl(VGASCREENSAVER)");
366 fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n");
375 printf("Setting number of columns to %d\n", colms);
376 if(ioctl(fd, VGASETCOLMS, &colms) < 0)
377 err(2, "ioctl(VGASETCOLMS)");
383 /* listing VGA palette */
385 printf("processing option -p list, "
386 "listing VGA palette\n");
396 /* setting VGA palette */
398 printf("processing option -p, setting VGA palette%s\n",
399 Pflag == 2? " to default": "");
401 for(idx = 0; idx < NVGAPEL; idx++)
402 if(Pflag == 2 || palette[idx].dothis)
406 p.r = palette[idx].r;
407 p.g = palette[idx].g;
408 p.b = palette[idx].b;
409 if(ioctl(fd, VGAWRITEPEL, (caddr_t)&p) < 0)
410 err(2, "ioctl(fd, VGAWRITEPEL)");
415 screeninfo.screen_no = -1; /* We are using fd */
416 screeninfo.current_screen = current;
417 screeninfo.pure_vt_mode = -1;
418 screeninfo.screen_size = res;
419 screeninfo.force_24lines = -1;
421 if(current != -1) /* set current screen */
424 printf("processing option -c, setting current screen to %d\n",current);
426 if(ioctl(1, VGASETSCREEN, &screeninfo) == -1)
427 err(1, "ioctl VGASETSCREEN failed");
434 printf("processing option -V, setting emulation to pure VT220\n");
435 screeninfo.pure_vt_mode = M_PUREVT;
440 printf("processing option -H, setting emulation to VT220 + HP Labels\n");
441 screeninfo.pure_vt_mode = M_HPVT;
446 printf("no change in terminal emulation\n");
452 printf("no change in screen resolution\n");
453 else if(res == SIZ_25ROWS)
454 printf("change screen resolution to 25 lines\n");
455 else if(res == SIZ_28ROWS)
456 printf("change screen resolution to 28 lines\n");
457 else if(res == SIZ_35ROWS)
458 printf("change screen resolution to 35 lines\n");
459 else if(res == SIZ_40ROWS)
460 printf("change screen resolution to 40 lines\n");
461 else if(res == SIZ_43ROWS)
462 printf("change screen resolution to 43 lines\n");
463 else if(res == SIZ_50ROWS)
464 printf("change screen resolution to 50 lines\n");
467 if(fflag == 1) /* force 24 lines on/off */
469 if(!strcmp(onoff, "on"))
473 else if(!strcmp(onoff, "off"))
479 fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n");
483 screeninfo.force_24lines = fflag;
485 if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1)
486 err(1, "ioctl VGASETSCREEN failed");
489 printf("successful execution of ioctl VGASETSCREEN!\n");
495 fprintf(stderr,"\nscon - screen control utility for the pcvt video driver\n");
496 fprintf(stderr,"usage: scon -a -l -m -v -c [n] -d [dev] -f [on|off] -V -H -s [n]\n");
497 fprintf(stderr,"usage: scon -p [default | list | i,r,g,b] | -t [sec] | -1 | -8\n");
498 fprintf(stderr," -a list video adaptor type (MDA,CGA,EGA or VGA)\n");
499 fprintf(stderr," -c <screen no> switch current virtual screen to <screen no>\n");
500 fprintf(stderr," -d <device> set parameters(-V|-H|-s) for virtual device\n");
501 fprintf(stderr," -f <on|off> force 24 lines in VT 25 lines and HP 28 lines mode\n");
502 fprintf(stderr," -H set VT220/HP emulation mode for a virtual screen\n");
503 fprintf(stderr," -l list current parameters for a virtual screen\n");
504 fprintf(stderr," -m report monitor type (MONO/COLOR)\n");
505 fprintf(stderr," -p default set default VGA palette\n");
506 fprintf(stderr," -p list list current VGA palette\n");
507 fprintf(stderr," -p <i,r,g,b> set VGA palette entry i to r/g/b\n");
508 fprintf(stderr," -p <name,r,g,b> set VGA palette entry for color name to r/g/b\n");
509 fprintf(stderr," -s <lines> set 25, 28, 35, 40, 43 or 50 lines for a virtual screen\n");
510 fprintf(stderr," -t <timeout> set screen saver timeout [seconds]\n");
511 fprintf(stderr," -1 set 132 columns mode\n");
512 fprintf(stderr," -8 set 80 columns mode\n");
513 fprintf(stderr," -v verbose mode\n");
514 fprintf(stderr," -V set pure VT220 emulation for a virtual screen\n");
515 fprintf(stderr," -? display help (this message)\n\n");
522 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
523 err(1, "ioctl VGAGETSCREEN failed");
524 switch(screeninfo.adaptor_type)
527 case UNKNOWN_ADAPTOR:
552 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
553 err(1, "ioctl VGAGETSCREEN failed");
554 switch(screeninfo.monitor_type)
570 char *vga_type(int number)
572 static char *vga_tab[] = {
609 return(vga_tab[number]);
612 char *vga_family(int number)
614 static char *vga_tab[] = {
623 return(vga_tab[number]);
629 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
630 err(1, "ioctl VGAGETSCREEN failed");
632 printf( "\nVideo Adaptor Type = ");
634 switch(screeninfo.adaptor_type)
637 case UNKNOWN_ADAPTOR:
638 printf("UNKNOWN Video Adaptor\n");
642 printf("MDA - Monochrome Display Adaptor\n");
646 printf("CGA - Color Graphics Adaptor\n");
650 printf("EGA - Enhanced Graphics Adaptor\n");
654 printf("VGA - Video Graphics Adaptor/Array\n");
655 printf(" VGA Chipset Manufacturer = %s\n",
656 vga_family(screeninfo.vga_family));
657 printf(" VGA Chipset Type = %s\n",
658 vga_type(screeninfo.vga_type));
659 printf(" Support for 132 Column Mode = %s\n",
660 screeninfo.vga_132 ? "Yes" : "No");
664 printf( "Display Monitor Type = ");
666 switch(screeninfo.monitor_type)
669 printf("UNKNOWN Monitor Type\n");
673 printf("Monochrome Monitor\n");
677 printf("Color Monitor\n");
681 printf( "Number of Downloadable Fonts = %d\n",screeninfo.totalfonts);
682 printf( "Number of Virtual Screens = %d\n",screeninfo.totalscreens);
683 printf( "Info Request Screen Number = %d\n",screeninfo.screen_no);
684 printf( "Current Displayed Screen = %d\n",screeninfo.current_screen);
686 if(screeninfo.pure_vt_mode == M_PUREVT)
687 printf( "Terminal Emulation Mode = VT220\n");
689 printf( "Terminal Emulation Mode = VT220 with HP Features\n");
693 switch(screeninfo.screen_size)
720 printf( "UNKNOWN\n");
723 printf( "Force 24 Lines = %s",
724 screeninfo.force_24lines ? "Yes" : "No");
729 static const char *findname(unsigned idx)
731 /* try to find a name for palette entry idx */
732 /* if multiple names exist, returns first matching */
733 register struct colname *cnp;
735 for(cnp = colnames; cnp->name; cnp++)
740 return (const char *)NULL;
743 static void printpalette(int fd)
745 register unsigned idx, last;
747 for(idx = 0; idx < NVGAPEL; idx++)
751 if(ioctl(fd, VGAREADPEL, &p) < 0)
752 err(2, "ioctl(VGAREADPEL)");
753 palette[idx].r = p.r;
754 palette[idx].g = p.g;
755 palette[idx].b = p.b;
758 /* find last non-empty entry */
759 for(last = NVGAPEL - 1; last; last--)
760 if(palette[last].r || palette[last].g || palette[last].b)
763 if(last != NVGAPEL - 1)
766 /* now, everything's collected. print out table */
767 printf("VGA palette status\n");
768 printf("index red green blue name\n");
769 for(idx = 0; idx < last; idx++)
772 printf("%5d %5d %5d %5d",
773 idx, palette[idx].r, palette[idx].g, palette[idx].b);
774 if(cp = findname(idx))
783 static void parsepopt(char *arg, unsigned *idx,
784 unsigned *r, unsigned *g, unsigned *b)
789 if(sscanf(arg, "%20[a-zA-Z0-9]%*[,:]%u,%u,%u", firstarg, r, g, b) < 4
790 || strlen(firstarg) == 0)
791 errx(2, "too few args in -p i,r,g,b");
793 if(firstarg[0] >= '0' && firstarg[0] <= '9') {
794 *idx = strtoul(firstarg, NULL, 10);
798 for(i = 0; colnames[i].name; i++)
799 if(strcasecmp(colnames[i].name, firstarg) == 0) {
800 *idx = colnames[i].idx;
803 errx(2, "arg ``%s'' in -p option not recognized", firstarg);