/* * Copyright (c) 1992,1993,1994 Hellmuth Michaelis and Joerg Wunsch * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by * Hellmuth Michaelis and Joerg Wunsch * 4. The name authors may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/usr.sbin/pcvt/scon/scon.c,v 1.5.6.1 2001/05/12 10:11:42 kris Exp $ * $DragonFly: src/usr.sbin/pcvt/scon/Attic/scon.c,v 1.3 2004/03/24 17:46:23 cpressey Exp $ */ static char *id = "@(#)scon.c, 3.20, Last Edit-Date: [Sun Sep 25 12:33:21 1994]"; /*---------------------------------------------------------------------------* * * history: * * -hm moving fd for default device from 1 -> 0 for such things * as "scon -p list | more" to be possible * (reported by Gordon L. Burditt, gordon@sneaky.lonestar.org) * -hm adding option "a" for just returning the type of video adaptor * -hm removing explicit HGC support, same as MDA ... * -hm vga type/family/132col support info on -l * -hm force 24 lines in DEC 25 lines mode and HP 28 lines mode * -hm fixed bug with 132 column mode display status display * -jw added 132/80 col mode switching * -hm removed -h flag, use -? now ... ;-) * -hm S3 chipsets .. * -hm Cirrus chipsets support from Onno van der Linden * -hm -m option, display monitor type * -hm bugfix, scon -c cleared dest screen, fixed * *---------------------------------------------------------------------------*/ #include #include #include #include #define DEFAULTFD 0 int aflag = -1; int lflag = -1; int mflag = -1; int current = -1; int pflag = -1; int hflag = -1; int res = -1; char *device; int dflag = -1; int vflag = 0; int Pflag = 0; int tflag = 0; int fflag = -1; int colms = 0; char *onoff; unsigned timeout; struct screeninfo screeninfo; #define NVGAPEL 256 struct rgb { unsigned r, g, b; int dothis; }; static struct rgb palette[NVGAPEL] = { { 0x00, 0x00, 0x00, 0}, /* 0 - black */ { 0x00, 0x00, 0x2a, 0}, /* 1 - blue */ { 0x00, 0x2a, 0x00, 0}, /* 2 - green */ { 0x00, 0x2a, 0x2a, 0}, /* 3 - cyan */ { 0x2a, 0x00, 0x00, 0}, /* 4 - red */ { 0x2a, 0x00, 0x2a, 0}, /* 5 - magenta */ { 0x2a, 0x2a, 0x00, 0}, /* 6 */ { 0x2a, 0x2a, 0x2a, 0}, /* 7 - lightgray */ { 0x00, 0x00, 0x15, 0}, /* 8 */ { 0x00, 0x00, 0x3f, 0}, /* 9 */ { 0x00, 0x2a, 0x15, 0}, /* 10 */ { 0x00, 0x2a, 0x3f, 0}, /* 11 */ { 0x2a, 0x00, 0x15, 0}, /* 12 */ { 0x2a, 0x00, 0x3f, 0}, /* 13 */ { 0x2a, 0x2a, 0x15, 0}, /* 14 */ { 0x2a, 0x2a, 0x3f, 0}, /* 15 */ { 0x00, 0x15, 0x00, 0}, /* 16 */ { 0x00, 0x15, 0x2a, 0}, /* 17 */ { 0x00, 0x3f, 0x00, 0}, /* 18 */ { 0x00, 0x3f, 0x2a, 0}, /* 19 */ { 0x2a, 0x15, 0x00, 0}, /* 20 - brown */ { 0x2a, 0x15, 0x2a, 0}, /* 21 */ { 0x2a, 0x3f, 0x00, 0}, /* 22 */ { 0x2a, 0x3f, 0x2a, 0}, /* 23 */ { 0x00, 0x15, 0x15, 0}, /* 24 */ { 0x00, 0x15, 0x3f, 0}, /* 25 */ { 0x00, 0x3f, 0x15, 0}, /* 26 */ { 0x00, 0x3f, 0x3f, 0}, /* 27 */ { 0x2a, 0x15, 0x15, 0}, /* 28 */ { 0x2a, 0x15, 0x3f, 0}, /* 29 */ { 0x2a, 0x3f, 0x15, 0}, /* 30 */ { 0x2a, 0x3f, 0x3f, 0}, /* 31 */ { 0x15, 0x00, 0x00, 0}, /* 32 */ { 0x15, 0x00, 0x2a, 0}, /* 33 */ { 0x15, 0x2a, 0x00, 0}, /* 34 */ { 0x15, 0x2a, 0x2a, 0}, /* 35 */ { 0x3f, 0x00, 0x00, 0}, /* 36 */ { 0x3f, 0x00, 0x2a, 0}, /* 37 */ { 0x3f, 0x2a, 0x00, 0}, /* 38 */ { 0x3f, 0x2a, 0x2a, 0}, /* 39 */ { 0x15, 0x00, 0x15, 0}, /* 40 */ { 0x15, 0x00, 0x3f, 0}, /* 41 */ { 0x15, 0x2a, 0x15, 0}, /* 42 */ { 0x15, 0x2a, 0x3f, 0}, /* 43 */ { 0x3f, 0x00, 0x15, 0}, /* 44 */ { 0x3f, 0x00, 0x3f, 0}, /* 45 */ { 0x3f, 0x2a, 0x15, 0}, /* 46 */ { 0x3f, 0x2a, 0x3f, 0}, /* 47 */ { 0x15, 0x15, 0x00, 0}, /* 48 */ { 0x15, 0x15, 0x2a, 0}, /* 49 */ { 0x15, 0x3f, 0x00, 0}, /* 50 */ { 0x15, 0x3f, 0x2a, 0}, /* 51 */ { 0x3f, 0x15, 0x00, 0}, /* 52 */ { 0x3f, 0x15, 0x2a, 0}, /* 53 */ { 0x3f, 0x3f, 0x00, 0}, /* 54 */ { 0x3f, 0x3f, 0x2a, 0}, /* 55 */ { 0x15, 0x15, 0x15, 0}, /* 56 - darkgray */ { 0x15, 0x15, 0x3f, 0}, /* 57 - lightblue */ { 0x15, 0x3f, 0x15, 0}, /* 58 - lightgreen */ { 0x15, 0x3f, 0x3f, 0}, /* 59 - lightcyan */ { 0x3f, 0x15, 0x15, 0}, /* 60 - lightred */ { 0x3f, 0x15, 0x3f, 0}, /* 61 - lightmagenta */ { 0x3f, 0x3f, 0x15, 0}, /* 62 - yellow */ { 0x3f, 0x3f, 0x3f, 0}, /* 63 - white */ { 0x00, 0x00, 0x00, 0} /* 64 ... - empty */ }; static struct colname { const char *name; unsigned idx; } colnames[] = { {"black", 0}, {"blue", 1}, {"green", 2}, {"cyan", 3}, {"red", 4}, {"magenta", 5}, {"brown", 20}, {"lightgray", 7}, {"lightgrey", 7}, {"darkgray", 56}, {"darkgrey", 56}, {"lightblue", 57}, {"lightgreen", 58}, {"lightcyan", 59}, {"lightred", 60}, {"lightmagenta", 61}, {"yellow", 62}, {"white", 63}, /* must be terminator: */ {(const char *)NULL, 0} }; static void usage(void); static void printadaptor(int); static void printmonitor(int); static void printinfo(int); static void parsepopt(char *arg, unsigned *idx, unsigned *r, unsigned *g, unsigned *b); static void printpalette(int fd); int main(int argc, char **argv) { extern int optind; extern int opterr; extern char *optarg; int c; int fd; while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != -1) { switch(c) { case 'a': aflag = 1; break; case 'l': lflag = 1; break; case 'm': mflag = 1; break; case 'c': current = atoi(optarg); break; case 'd': device = optarg; dflag = 1; break; case 'f': onoff = optarg; fflag = 1; break; case 'V': pflag = 1; break; case 'H': hflag = 1; break; case 's': if (!strncmp(optarg, "25", 2)) res = SIZ_25ROWS; else if(!strncmp(optarg, "28", 2)) res = SIZ_28ROWS; else if(!strncmp(optarg, "35", 2)) res = SIZ_35ROWS; else if(!strncmp(optarg, "40", 2)) res = SIZ_40ROWS; else if(!strncmp(optarg, "43", 2)) res = SIZ_43ROWS; else if(!strncmp(optarg, "50", 2)) res = SIZ_50ROWS; break; case 'v': vflag++; break; case 'p': if(!strcmp(optarg, "list")) { if(Pflag) errx(2, "-p list is mutual exclusive with other -p options"); Pflag = 3; } else if(!strcmp(optarg, "default")) { if(Pflag) errx(2, "multiple -p default not allowed"); Pflag = 2; } else { unsigned idx, r, g, b; if(Pflag > 1) errx(2, "-p default and -p i,r,g,b ambiguous"); Pflag = 1; parsepopt(optarg, &idx, &r, &g, &b); if(idx >= NVGAPEL) errx(2, "index %u in -p option out of range", idx); palette[idx].r = r; palette[idx].g = g; palette[idx].b = b; palette[idx].dothis = 1; } break; case 't': tflag++; timeout = atoi(optarg); break; case '1': colms = 132; break; case '8': colms = 80; break; case '?': default: usage(); break; } } if((pflag == 1) && (hflag == 1)) usage(); if(dflag == -1 && lflag == -1 && current == -1 && pflag == -1 && hflag == -1 && res == -1 && Pflag == 0 && tflag == 0 && fflag == -1 && colms == 0 && mflag == -1) { lflag = 1; } if(dflag == -1) { if(vflag) printf("using current device\n"); fd = DEFAULTFD; /* -hm, Feb 12 1993 */ } else { if((fd = open(device, O_RDWR)) == -1) err(1, "ERROR opening %s", device); if(vflag) printf("using device %s\n",device); } if(aflag == 1) /* return adaptor type */ { printadaptor(fd); exit(0); } if(mflag == 1) /* return monitor type */ { printmonitor(fd); exit(0); } if(lflag == 1) /* list information */ { if(vflag) printf("processing option -l, listing screen info\n"); printinfo(fd); exit(0); } if(tflag) /* set screen saver timeout */ { if(vflag) { printf( "processing option -t, setting screen saver timeout: " ); if(timeout) printf("new timeout = %d s\n", timeout); else printf("turned off\n"); } if(ioctl(fd, VGASCREENSAVER, &timeout) < 0) { warn("ioctl(VGASCREENSAVER)"); fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n"); exit(2); } goto success; } if(colms) { if(vflag) printf("Setting number of columns to %d\n", colms); if(ioctl(fd, VGASETCOLMS, &colms) < 0) err(2, "ioctl(VGASETCOLMS)"); goto success; } if(Pflag == 3) { /* listing VGA palette */ if(vflag) printf("processing option -p list, " "listing VGA palette\n"); printpalette(fd); goto success; } if(Pflag) { unsigned int idx; /* setting VGA palette */ if(vflag) printf("processing option -p, setting VGA palette%s\n", Pflag == 2? " to default": ""); for(idx = 0; idx < NVGAPEL; idx++) if(Pflag == 2 || palette[idx].dothis) { struct vgapel p; p.idx = idx; p.r = palette[idx].r; p.g = palette[idx].g; p.b = palette[idx].b; if(ioctl(fd, VGAWRITEPEL, (caddr_t)&p) < 0) err(2, "ioctl(fd, VGAWRITEPEL)"); } goto success; } screeninfo.screen_no = -1; /* We are using fd */ screeninfo.current_screen = current; screeninfo.pure_vt_mode = -1; screeninfo.screen_size = res; screeninfo.force_24lines = -1; if(current != -1) /* set current screen */ { if(vflag) printf("processing option -c, setting current screen to %d\n",current); if(ioctl(1, VGASETSCREEN, &screeninfo) == -1) err(1, "ioctl VGASETSCREEN failed"); exit(0); } if(pflag == 1) { if(vflag) printf("processing option -V, setting emulation to pure VT220\n"); screeninfo.pure_vt_mode = M_PUREVT; } else if(hflag == 1) { if(vflag) printf("processing option -H, setting emulation to VT220 + HP Labels\n"); screeninfo.pure_vt_mode = M_HPVT; } else { if(vflag) printf("no change in terminal emulation\n"); } if(vflag) { if(res == -1) printf("no change in screen resolution\n"); else if(res == SIZ_25ROWS) printf("change screen resolution to 25 lines\n"); else if(res == SIZ_28ROWS) printf("change screen resolution to 28 lines\n"); else if(res == SIZ_35ROWS) printf("change screen resolution to 35 lines\n"); else if(res == SIZ_40ROWS) printf("change screen resolution to 40 lines\n"); else if(res == SIZ_43ROWS) printf("change screen resolution to 43 lines\n"); else if(res == SIZ_50ROWS) printf("change screen resolution to 50 lines\n"); } if(fflag == 1) /* force 24 lines on/off */ { if(!strcmp(onoff, "on")) { fflag = 1; } else if(!strcmp(onoff, "off")) { fflag = 0; } else { fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n"); exit(1); } } screeninfo.force_24lines = fflag; if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1) err(1, "ioctl VGASETSCREEN failed"); success: if(vflag) printf("successful execution of ioctl VGASETSCREEN!\n"); exit(0); } void usage(void) { fprintf(stderr,"\nscon - screen control utility for the pcvt video driver\n"); fprintf(stderr,"usage: scon -a -l -m -v -c [n] -d [dev] -f [on|off] -V -H -s [n]\n"); fprintf(stderr,"usage: scon -p [default | list | i,r,g,b] | -t [sec] | -1 | -8\n"); fprintf(stderr," -a list video adaptor type (MDA,CGA,EGA or VGA)\n"); fprintf(stderr," -c switch current virtual screen to \n"); fprintf(stderr," -d set parameters(-V|-H|-s) for virtual device\n"); fprintf(stderr," -f force 24 lines in VT 25 lines and HP 28 lines mode\n"); fprintf(stderr," -H set VT220/HP emulation mode for a virtual screen\n"); fprintf(stderr," -l list current parameters for a virtual screen\n"); fprintf(stderr," -m report monitor type (MONO/COLOR)\n"); fprintf(stderr," -p default set default VGA palette\n"); fprintf(stderr," -p list list current VGA palette\n"); fprintf(stderr," -p set VGA palette entry i to r/g/b\n"); fprintf(stderr," -p set VGA palette entry for color name to r/g/b\n"); fprintf(stderr," -s set 25, 28, 35, 40, 43 or 50 lines for a virtual screen\n"); fprintf(stderr," -t set screen saver timeout [seconds]\n"); fprintf(stderr," -1 set 132 columns mode\n"); fprintf(stderr," -8 set 80 columns mode\n"); fprintf(stderr," -v verbose mode\n"); fprintf(stderr," -V set pure VT220 emulation for a virtual screen\n"); fprintf(stderr," -? display help (this message)\n\n"); exit(1); } void printadaptor(int fd) { if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1) err(1, "ioctl VGAGETSCREEN failed"); switch(screeninfo.adaptor_type) { default: case UNKNOWN_ADAPTOR: printf("UNKNOWN\n"); break; case MDA_ADAPTOR: printf("MDA\n"); break; case CGA_ADAPTOR: printf("CGA\n"); break; case EGA_ADAPTOR: printf("EGA\n"); break; case VGA_ADAPTOR: printf("VGA\n"); break; } } void printmonitor(int fd) { if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1) err(1, "ioctl VGAGETSCREEN failed"); switch(screeninfo.monitor_type) { default: printf("UNKNOWN\n"); break; case MONITOR_MONO: printf("MONO\n"); break; case MONITOR_COLOR: printf("COLOR\n"); break; } } char * vga_type(int number) { static char *vga_tab[] = { "Generic VGA", "ET4000", "ET3000", "PVGA1A", "WD90C00", "WD90C10", "WD90C11", "VIDEO 7 VEGA", "VIDEO 7 FAST", "VIDEO 7 VER5", "VIDEO 7 1024I", "Unknown VIDEO 7", "TVGA 8800BR", "TVGA 8800CS", "TVGA 8900B", "TVGA 8900C", "TVGA 8900CL", "TVGA 9000", "TVGA 9100", "TVGA 9200", "Unknown TRIDENT", "S3 80C911", "S3 80C924", "S3 80C801/80C805", "S3 80C928", "Unknown S3", "CL-GD5402", "CL-GD5402r1", "CL-GD5420", "CL-GD5420r1", "CL-GD5422", "CL-GD5424", "CL-GD5426", "CL-GD5428", }; return(vga_tab[number]); } char * vga_family(int number) { static char *vga_tab[] = { "Generic VGA", "Tseng Labs", "Western Digital", "Video Seven", "Trident", "S3 Incorporated", "Cirrus Logic", }; return(vga_tab[number]); } void printinfo(int fd) { if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1) err(1, "ioctl VGAGETSCREEN failed"); printf( "\nVideo Adaptor Type = "); switch(screeninfo.adaptor_type) { default: case UNKNOWN_ADAPTOR: printf("UNKNOWN Video Adaptor\n"); break; case MDA_ADAPTOR: printf("MDA - Monochrome Display Adaptor\n"); break; case CGA_ADAPTOR: printf("CGA - Color Graphics Adaptor\n"); break; case EGA_ADAPTOR: printf("EGA - Enhanced Graphics Adaptor\n"); break; case VGA_ADAPTOR: printf("VGA - Video Graphics Adaptor/Array\n"); printf(" VGA Chipset Manufacturer = %s\n", vga_family(screeninfo.vga_family)); printf(" VGA Chipset Type = %s\n", vga_type(screeninfo.vga_type)); printf(" Support for 132 Column Mode = %s\n", screeninfo.vga_132 ? "Yes" : "No"); break; } printf( "Display Monitor Type = "); switch(screeninfo.monitor_type) { default: printf("UNKNOWN Monitor Type\n"); break; case MONITOR_MONO: printf("Monochrome Monitor\n"); break; case MONITOR_COLOR: printf("Color Monitor\n"); break; } printf( "Number of Downloadable Fonts = %d\n",screeninfo.totalfonts); printf( "Number of Virtual Screens = %d\n",screeninfo.totalscreens); printf( "Info Request Screen Number = %d\n",screeninfo.screen_no); printf( "Current Displayed Screen = %d\n",screeninfo.current_screen); if(screeninfo.pure_vt_mode == M_PUREVT) printf( "Terminal Emulation Mode = VT220\n"); else printf( "Terminal Emulation Mode = VT220 with HP Features\n"); printf( "Lines = "); switch(screeninfo.screen_size) { case SIZ_25ROWS: printf( "25\n"); break; case SIZ_28ROWS: printf( "28\n"); break; case SIZ_35ROWS: printf( "35\n"); break; case SIZ_40ROWS: printf( "40\n"); break; case SIZ_43ROWS: printf( "43\n"); break; case SIZ_50ROWS: printf( "50\n"); break; default: printf( "UNKNOWN\n"); break; } printf( "Force 24 Lines = %s", screeninfo.force_24lines ? "Yes" : "No"); printf("\n\n"); } static const char * findname(unsigned idx) { /* try to find a name for palette entry idx */ /* if multiple names exist, returns first matching */ struct colname *cnp; for(cnp = colnames; cnp->name; cnp++) if(cnp->idx == idx) return cnp->name; /* not found */ return (const char *)NULL; } static void printpalette(int fd) { unsigned idx, last; for(idx = 0; idx < NVGAPEL; idx++) { struct vgapel p; p.idx = idx; if(ioctl(fd, VGAREADPEL, &p) < 0) err(2, "ioctl(VGAREADPEL)"); palette[idx].r = p.r; palette[idx].g = p.g; palette[idx].b = p.b; } /* find last non-empty entry */ for(last = NVGAPEL - 1; last; last--) if(palette[last].r || palette[last].g || palette[last].b) break; if(last != NVGAPEL - 1) last++; /* now, everything's collected. print out table */ printf("VGA palette status\n"); printf("index red green blue name\n"); for(idx = 0; idx < last; idx++) { const char *cp; printf("%5d %5d %5d %5d", idx, palette[idx].r, palette[idx].g, palette[idx].b); if(cp = findname(idx)) printf(" %s\n", cp); else putchar('\n'); } putchar('\n'); } static void parsepopt(char *arg, unsigned *idx, unsigned *r, unsigned *g, unsigned *b) { char firstarg[21]; unsigned i; if(sscanf(arg, "%20[a-zA-Z0-9]%*[,:]%u,%u,%u", firstarg, r, g, b) < 4 || strlen(firstarg) == 0) errx(2, "too few args in -p i,r,g,b"); if(firstarg[0] >= '0' && firstarg[0] <= '9') { *idx = strtoul(firstarg, NULL, 10); return; } for(i = 0; colnames[i].name; i++) if(strcasecmp(colnames[i].name, firstarg) == 0) { *idx = colnames[i].idx; return; } errx(2, "arg ``%s'' in -p option not recognized", firstarg); }