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 $
33 * $DragonFly: src/usr.sbin/pcvt/scon/Attic/scon.c,v 1.2 2003/06/17 04:29:59 dillon Exp $
37 "@(#)scon.c, 3.20, Last Edit-Date: [Sun Sep 25 12:33:21 1994]";
39 /*---------------------------------------------------------------------------*
43 * -hm moving fd for default device from 1 -> 0 for such things
44 * as "scon -p list | more" to be possible
45 * (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org)
46 * -hm adding option "a" for just returning the type of video adaptor
47 * -hm removing explicit HGC support, same as MDA ...
48 * -hm vga type/family/132col support info on -l
49 * -hm force 24 lines in DEC 25 lines mode and HP 28 lines mode
50 * -hm fixed bug with 132 column mode display status display
51 * -jw added 132/80 col mode switching
52 * -hm removed -h flag, use -? now ... ;-)
54 * -hm Cirrus chipsets support from Onno van der Linden
55 * -hm -m option, display monitor type
56 * -hm bugfix, scon -c <screen-num> cleared dest screen, fixed
58 *---------------------------------------------------------------------------*/
63 #include <machine/pcvt_ioctl.h>
84 struct screeninfo screeninfo;
93 static struct rgb palette[NVGAPEL] = {
94 { 0x00, 0x00, 0x00, 0}, /* 0 - black */
95 { 0x00, 0x00, 0x2a, 0}, /* 1 - blue */
96 { 0x00, 0x2a, 0x00, 0}, /* 2 - green */
97 { 0x00, 0x2a, 0x2a, 0}, /* 3 - cyan */
98 { 0x2a, 0x00, 0x00, 0}, /* 4 - red */
99 { 0x2a, 0x00, 0x2a, 0}, /* 5 - magenta */
100 { 0x2a, 0x2a, 0x00, 0}, /* 6 */
101 { 0x2a, 0x2a, 0x2a, 0}, /* 7 - lightgray */
102 { 0x00, 0x00, 0x15, 0}, /* 8 */
103 { 0x00, 0x00, 0x3f, 0}, /* 9 */
104 { 0x00, 0x2a, 0x15, 0}, /* 10 */
105 { 0x00, 0x2a, 0x3f, 0}, /* 11 */
106 { 0x2a, 0x00, 0x15, 0}, /* 12 */
107 { 0x2a, 0x00, 0x3f, 0}, /* 13 */
108 { 0x2a, 0x2a, 0x15, 0}, /* 14 */
109 { 0x2a, 0x2a, 0x3f, 0}, /* 15 */
110 { 0x00, 0x15, 0x00, 0}, /* 16 */
111 { 0x00, 0x15, 0x2a, 0}, /* 17 */
112 { 0x00, 0x3f, 0x00, 0}, /* 18 */
113 { 0x00, 0x3f, 0x2a, 0}, /* 19 */
114 { 0x2a, 0x15, 0x00, 0}, /* 20 - brown */
115 { 0x2a, 0x15, 0x2a, 0}, /* 21 */
116 { 0x2a, 0x3f, 0x00, 0}, /* 22 */
117 { 0x2a, 0x3f, 0x2a, 0}, /* 23 */
118 { 0x00, 0x15, 0x15, 0}, /* 24 */
119 { 0x00, 0x15, 0x3f, 0}, /* 25 */
120 { 0x00, 0x3f, 0x15, 0}, /* 26 */
121 { 0x00, 0x3f, 0x3f, 0}, /* 27 */
122 { 0x2a, 0x15, 0x15, 0}, /* 28 */
123 { 0x2a, 0x15, 0x3f, 0}, /* 29 */
124 { 0x2a, 0x3f, 0x15, 0}, /* 30 */
125 { 0x2a, 0x3f, 0x3f, 0}, /* 31 */
126 { 0x15, 0x00, 0x00, 0}, /* 32 */
127 { 0x15, 0x00, 0x2a, 0}, /* 33 */
128 { 0x15, 0x2a, 0x00, 0}, /* 34 */
129 { 0x15, 0x2a, 0x2a, 0}, /* 35 */
130 { 0x3f, 0x00, 0x00, 0}, /* 36 */
131 { 0x3f, 0x00, 0x2a, 0}, /* 37 */
132 { 0x3f, 0x2a, 0x00, 0}, /* 38 */
133 { 0x3f, 0x2a, 0x2a, 0}, /* 39 */
134 { 0x15, 0x00, 0x15, 0}, /* 40 */
135 { 0x15, 0x00, 0x3f, 0}, /* 41 */
136 { 0x15, 0x2a, 0x15, 0}, /* 42 */
137 { 0x15, 0x2a, 0x3f, 0}, /* 43 */
138 { 0x3f, 0x00, 0x15, 0}, /* 44 */
139 { 0x3f, 0x00, 0x3f, 0}, /* 45 */
140 { 0x3f, 0x2a, 0x15, 0}, /* 46 */
141 { 0x3f, 0x2a, 0x3f, 0}, /* 47 */
142 { 0x15, 0x15, 0x00, 0}, /* 48 */
143 { 0x15, 0x15, 0x2a, 0}, /* 49 */
144 { 0x15, 0x3f, 0x00, 0}, /* 50 */
145 { 0x15, 0x3f, 0x2a, 0}, /* 51 */
146 { 0x3f, 0x15, 0x00, 0}, /* 52 */
147 { 0x3f, 0x15, 0x2a, 0}, /* 53 */
148 { 0x3f, 0x3f, 0x00, 0}, /* 54 */
149 { 0x3f, 0x3f, 0x2a, 0}, /* 55 */
150 { 0x15, 0x15, 0x15, 0}, /* 56 - darkgray */
151 { 0x15, 0x15, 0x3f, 0}, /* 57 - lightblue */
152 { 0x15, 0x3f, 0x15, 0}, /* 58 - lightgreen */
153 { 0x15, 0x3f, 0x3f, 0}, /* 59 - lightcyan */
154 { 0x3f, 0x15, 0x15, 0}, /* 60 - lightred */
155 { 0x3f, 0x15, 0x3f, 0}, /* 61 - lightmagenta */
156 { 0x3f, 0x3f, 0x15, 0}, /* 62 - yellow */
157 { 0x3f, 0x3f, 0x3f, 0}, /* 63 - white */
158 { 0x00, 0x00, 0x00, 0} /* 64 ... - empty */
161 static struct colname {
180 {"lightmagenta", 61},
183 /* must be terminator: */ {(const char *)NULL, 0}
187 static void parsepopt(char *arg, unsigned *idx,
188 unsigned *r, unsigned *g, unsigned *b);
189 static void printpalette(int fd);
202 while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != -1)
219 current = atoi(optarg);
241 if (!strncmp(optarg, "25", 2))
243 else if(!strncmp(optarg, "28", 2))
245 else if(!strncmp(optarg, "35", 2))
247 else if(!strncmp(optarg, "40", 2))
249 else if(!strncmp(optarg, "43", 2))
251 else if(!strncmp(optarg, "50", 2))
260 if(!strcmp(optarg, "list"))
263 errx(2, "-p list is mutual exclusive with other -p options");
266 else if(!strcmp(optarg, "default"))
269 errx(2, "multiple -p default not allowed");
272 unsigned idx, r, g, b;
275 errx(2, "-p default and -p i,r,g,b ambiguous");
277 parsepopt(optarg, &idx, &r, &g, &b);
279 errx(2, "index %u in -p option out of range", idx);
283 palette[idx].dothis = 1;
289 timeout = atoi(optarg);
307 if((pflag == 1) && (hflag == 1))
310 if(dflag == -1 && lflag == -1 && current == -1 && pflag == -1 &&
311 hflag == -1 && res == -1 && Pflag == 0 && tflag == 0 && fflag == -1
312 && colms == 0 && mflag == -1)
320 printf("using current device\n");
321 fd = DEFAULTFD; /* -hm, Feb 12 1993 */
325 if((fd = open(device, O_RDWR)) == -1)
326 err(1, "ERROR opening %s", device);
328 printf("using device %s\n",device);
331 if(aflag == 1) /* return adaptor type */
337 if(mflag == 1) /* return monitor type */
343 if(lflag == 1) /* list information */
346 printf("processing option -l, listing screen info\n");
351 if(tflag) /* set screen saver timeout */
356 "processing option -t, setting screen saver timeout: "
359 printf("new timeout = %d s\n", timeout);
361 printf("turned off\n");
364 if(ioctl(fd, VGASCREENSAVER, &timeout) < 0)
366 warn("ioctl(VGASCREENSAVER)");
367 fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n");
376 printf("Setting number of columns to %d\n", colms);
377 if(ioctl(fd, VGASETCOLMS, &colms) < 0)
378 err(2, "ioctl(VGASETCOLMS)");
384 /* listing VGA palette */
386 printf("processing option -p list, "
387 "listing VGA palette\n");
397 /* setting VGA palette */
399 printf("processing option -p, setting VGA palette%s\n",
400 Pflag == 2? " to default": "");
402 for(idx = 0; idx < NVGAPEL; idx++)
403 if(Pflag == 2 || palette[idx].dothis)
407 p.r = palette[idx].r;
408 p.g = palette[idx].g;
409 p.b = palette[idx].b;
410 if(ioctl(fd, VGAWRITEPEL, (caddr_t)&p) < 0)
411 err(2, "ioctl(fd, VGAWRITEPEL)");
416 screeninfo.screen_no = -1; /* We are using fd */
417 screeninfo.current_screen = current;
418 screeninfo.pure_vt_mode = -1;
419 screeninfo.screen_size = res;
420 screeninfo.force_24lines = -1;
422 if(current != -1) /* set current screen */
425 printf("processing option -c, setting current screen to %d\n",current);
427 if(ioctl(1, VGASETSCREEN, &screeninfo) == -1)
428 err(1, "ioctl VGASETSCREEN failed");
435 printf("processing option -V, setting emulation to pure VT220\n");
436 screeninfo.pure_vt_mode = M_PUREVT;
441 printf("processing option -H, setting emulation to VT220 + HP Labels\n");
442 screeninfo.pure_vt_mode = M_HPVT;
447 printf("no change in terminal emulation\n");
453 printf("no change in screen resolution\n");
454 else if(res == SIZ_25ROWS)
455 printf("change screen resolution to 25 lines\n");
456 else if(res == SIZ_28ROWS)
457 printf("change screen resolution to 28 lines\n");
458 else if(res == SIZ_35ROWS)
459 printf("change screen resolution to 35 lines\n");
460 else if(res == SIZ_40ROWS)
461 printf("change screen resolution to 40 lines\n");
462 else if(res == SIZ_43ROWS)
463 printf("change screen resolution to 43 lines\n");
464 else if(res == SIZ_50ROWS)
465 printf("change screen resolution to 50 lines\n");
468 if(fflag == 1) /* force 24 lines on/off */
470 if(!strcmp(onoff, "on"))
474 else if(!strcmp(onoff, "off"))
480 fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n");
484 screeninfo.force_24lines = fflag;
486 if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1)
487 err(1, "ioctl VGASETSCREEN failed");
490 printf("successful execution of ioctl VGASETSCREEN!\n");
496 fprintf(stderr,"\nscon - screen control utility for the pcvt video driver\n");
497 fprintf(stderr,"usage: scon -a -l -m -v -c [n] -d [dev] -f [on|off] -V -H -s [n]\n");
498 fprintf(stderr,"usage: scon -p [default | list | i,r,g,b] | -t [sec] | -1 | -8\n");
499 fprintf(stderr," -a list video adaptor type (MDA,CGA,EGA or VGA)\n");
500 fprintf(stderr," -c <screen no> switch current virtual screen to <screen no>\n");
501 fprintf(stderr," -d <device> set parameters(-V|-H|-s) for virtual device\n");
502 fprintf(stderr," -f <on|off> force 24 lines in VT 25 lines and HP 28 lines mode\n");
503 fprintf(stderr," -H set VT220/HP emulation mode for a virtual screen\n");
504 fprintf(stderr," -l list current parameters for a virtual screen\n");
505 fprintf(stderr," -m report monitor type (MONO/COLOR)\n");
506 fprintf(stderr," -p default set default VGA palette\n");
507 fprintf(stderr," -p list list current VGA palette\n");
508 fprintf(stderr," -p <i,r,g,b> set VGA palette entry i to r/g/b\n");
509 fprintf(stderr," -p <name,r,g,b> set VGA palette entry for color name to r/g/b\n");
510 fprintf(stderr," -s <lines> set 25, 28, 35, 40, 43 or 50 lines for a virtual screen\n");
511 fprintf(stderr," -t <timeout> set screen saver timeout [seconds]\n");
512 fprintf(stderr," -1 set 132 columns mode\n");
513 fprintf(stderr," -8 set 80 columns mode\n");
514 fprintf(stderr," -v verbose mode\n");
515 fprintf(stderr," -V set pure VT220 emulation for a virtual screen\n");
516 fprintf(stderr," -? display help (this message)\n\n");
523 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
524 err(1, "ioctl VGAGETSCREEN failed");
525 switch(screeninfo.adaptor_type)
528 case UNKNOWN_ADAPTOR:
553 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
554 err(1, "ioctl VGAGETSCREEN failed");
555 switch(screeninfo.monitor_type)
571 char *vga_type(int number)
573 static char *vga_tab[] = {
610 return(vga_tab[number]);
613 char *vga_family(int number)
615 static char *vga_tab[] = {
624 return(vga_tab[number]);
630 if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
631 err(1, "ioctl VGAGETSCREEN failed");
633 printf( "\nVideo Adaptor Type = ");
635 switch(screeninfo.adaptor_type)
638 case UNKNOWN_ADAPTOR:
639 printf("UNKNOWN Video Adaptor\n");
643 printf("MDA - Monochrome Display Adaptor\n");
647 printf("CGA - Color Graphics Adaptor\n");
651 printf("EGA - Enhanced Graphics Adaptor\n");
655 printf("VGA - Video Graphics Adaptor/Array\n");
656 printf(" VGA Chipset Manufacturer = %s\n",
657 vga_family(screeninfo.vga_family));
658 printf(" VGA Chipset Type = %s\n",
659 vga_type(screeninfo.vga_type));
660 printf(" Support for 132 Column Mode = %s\n",
661 screeninfo.vga_132 ? "Yes" : "No");
665 printf( "Display Monitor Type = ");
667 switch(screeninfo.monitor_type)
670 printf("UNKNOWN Monitor Type\n");
674 printf("Monochrome Monitor\n");
678 printf("Color Monitor\n");
682 printf( "Number of Downloadable Fonts = %d\n",screeninfo.totalfonts);
683 printf( "Number of Virtual Screens = %d\n",screeninfo.totalscreens);
684 printf( "Info Request Screen Number = %d\n",screeninfo.screen_no);
685 printf( "Current Displayed Screen = %d\n",screeninfo.current_screen);
687 if(screeninfo.pure_vt_mode == M_PUREVT)
688 printf( "Terminal Emulation Mode = VT220\n");
690 printf( "Terminal Emulation Mode = VT220 with HP Features\n");
694 switch(screeninfo.screen_size)
721 printf( "UNKNOWN\n");
724 printf( "Force 24 Lines = %s",
725 screeninfo.force_24lines ? "Yes" : "No");
730 static const char *findname(unsigned idx)
732 /* try to find a name for palette entry idx */
733 /* if multiple names exist, returns first matching */
734 register struct colname *cnp;
736 for(cnp = colnames; cnp->name; cnp++)
741 return (const char *)NULL;
744 static void printpalette(int fd)
746 register unsigned idx, last;
748 for(idx = 0; idx < NVGAPEL; idx++)
752 if(ioctl(fd, VGAREADPEL, &p) < 0)
753 err(2, "ioctl(VGAREADPEL)");
754 palette[idx].r = p.r;
755 palette[idx].g = p.g;
756 palette[idx].b = p.b;
759 /* find last non-empty entry */
760 for(last = NVGAPEL - 1; last; last--)
761 if(palette[last].r || palette[last].g || palette[last].b)
764 if(last != NVGAPEL - 1)
767 /* now, everything's collected. print out table */
768 printf("VGA palette status\n");
769 printf("index red green blue name\n");
770 for(idx = 0; idx < last; idx++)
773 printf("%5d %5d %5d %5d",
774 idx, palette[idx].r, palette[idx].g, palette[idx].b);
775 if(cp = findname(idx))
784 static void parsepopt(char *arg, unsigned *idx,
785 unsigned *r, unsigned *g, unsigned *b)
790 if(sscanf(arg, "%20[a-zA-Z0-9]%*[,:]%u,%u,%u", firstarg, r, g, b) < 4
791 || strlen(firstarg) == 0)
792 errx(2, "too few args in -p i,r,g,b");
794 if(firstarg[0] >= '0' && firstarg[0] <= '9') {
795 *idx = strtoul(firstarg, NULL, 10);
799 for(i = 0; colnames[i].name; i++)
800 if(strcasecmp(colnames[i].name, firstarg) == 0) {
801 *idx = colnames[i].idx;
804 errx(2, "arg ``%s'' in -p option not recognized", firstarg);