Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / pcvt / scon / scon.c
1 /*
2  * Copyright (c) 1992,1993,1994 Hellmuth Michaelis and Joerg Wunsch
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
20  *
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.
31  *
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 $
34  */
35
36 static char *id =
37         "@(#)scon.c, 3.20, Last Edit-Date: [Sun Sep 25 12:33:21 1994]";
38
39 /*---------------------------------------------------------------------------*
40  *
41  *      history:
42  *
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 ... ;-)
53  *      -hm     S3 chipsets ..
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
57  *
58  *---------------------------------------------------------------------------*/
59
60 #include <stdio.h>
61 #include <err.h>
62 #include <fcntl.h>
63 #include <machine/pcvt_ioctl.h>
64
65 #define DEFAULTFD 0
66
67 int aflag = -1;
68 int lflag = -1;
69 int mflag = -1;
70 int current = -1;
71 int pflag = -1;
72 int hflag = -1;
73 int res = -1;
74 char *device;
75 int dflag = -1;
76 int vflag = 0;
77 int Pflag = 0;
78 int tflag = 0;
79 int fflag = -1;
80 int colms = 0;
81 char *onoff;
82
83 unsigned timeout;
84 struct screeninfo screeninfo;
85
86 #define NVGAPEL 256
87
88 struct rgb {
89         unsigned r, g, b;
90         int dothis;
91 };
92
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      */
159 };
160
161 static struct colname {
162         const char *name;
163         unsigned idx;
164 } colnames[] = {
165         {"black", 0},
166         {"blue", 1},
167         {"green", 2},
168         {"cyan", 3},
169         {"red", 4},
170         {"magenta", 5},
171         {"brown", 20},
172         {"lightgray", 7},
173         {"lightgrey", 7},
174         {"darkgray", 56},
175         {"darkgrey", 56},
176         {"lightblue", 57},
177         {"lightgreen", 58},
178         {"lightcyan", 59},
179         {"lightred", 60},
180         {"lightmagenta", 61},
181         {"yellow", 62},
182         {"white", 63},
183         /* must be terminator: */ {(const char *)NULL, 0}
184 };
185
186
187 static void parsepopt(char *arg, unsigned *idx,
188                       unsigned *r, unsigned *g, unsigned *b);
189 static void printpalette(int fd);
190
191 main(argc,argv)
192 int argc;
193 char *argv[];
194 {
195         extern int optind;
196         extern int opterr;
197         extern char *optarg;
198
199         int c;
200         int fd;
201
202         while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != -1)
203         {
204                 switch(c)
205                 {
206                         case 'a':
207                                 aflag = 1;
208                                 break;
209
210                         case 'l':
211                                 lflag = 1;
212                                 break;
213
214                         case 'm':
215                                 mflag = 1;
216                                 break;
217
218                         case 'c':
219                                 current = atoi(optarg);
220                                 break;
221
222                         case 'd':
223                                 device = optarg;
224                                 dflag = 1;
225                                 break;
226
227                         case 'f':
228                                 onoff = optarg;
229                                 fflag = 1;
230                                 break;
231
232                         case 'V':
233                                 pflag = 1;
234                                 break;
235
236                         case 'H':
237                                 hflag = 1;
238                                 break;
239
240                         case 's':
241                                 if     (!strncmp(optarg, "25", 2))
242                                         res = SIZ_25ROWS;
243                                 else if(!strncmp(optarg, "28", 2))
244                                         res = SIZ_28ROWS;
245                                 else if(!strncmp(optarg, "35", 2))
246                                         res = SIZ_35ROWS;
247                                 else if(!strncmp(optarg, "40", 2))
248                                         res = SIZ_40ROWS;
249                                 else if(!strncmp(optarg, "43", 2))
250                                         res = SIZ_43ROWS;
251                                 else if(!strncmp(optarg, "50", 2))
252                                         res = SIZ_50ROWS;
253                                 break;
254
255                         case 'v':
256                                 vflag++;
257                                 break;
258
259                         case 'p':
260                                 if(!strcmp(optarg, "list"))
261                                 {
262                                         if(Pflag)
263                                                 errx(2, "-p list is mutual exclusive with other -p options");
264                                         Pflag = 3;
265                                 }
266                                 else if(!strcmp(optarg, "default"))
267                                 {
268                                         if(Pflag)
269                                                 errx(2, "multiple -p default not allowed");
270                                         Pflag = 2;
271                                 } else {
272                                         unsigned idx, r, g, b;
273
274                                         if(Pflag > 1)
275                                                 errx(2, "-p default and -p i,r,g,b ambiguous");
276                                         Pflag = 1;
277                                         parsepopt(optarg, &idx, &r, &g, &b);
278                                         if(idx >= NVGAPEL)
279                                                 errx(2, "index %u in -p option out of range", idx);
280                                         palette[idx].r = r;
281                                         palette[idx].g = g;
282                                         palette[idx].b = b;
283                                         palette[idx].dothis = 1;
284                                 }
285                                 break;
286
287                         case 't':
288                                 tflag++;
289                                 timeout = atoi(optarg);
290                                 break;
291
292                         case '1':
293                                 colms = 132;
294                                 break;
295
296                         case '8':
297                                 colms = 80;
298                                 break;
299
300                         case '?':
301                         default:
302                                 usage();
303                                 break;
304                 }
305         }
306
307         if((pflag == 1) && (hflag == 1))
308                 usage();
309
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)
313         {
314                 lflag = 1;
315         }
316
317         if(dflag == -1)
318         {
319                 if(vflag)
320                         printf("using current device\n");
321                 fd = DEFAULTFD;         /* -hm, Feb 12 1993 */
322         }
323         else
324         {
325                 if((fd = open(device, O_RDWR)) == -1)
326                         err(1, "ERROR opening %s", device);
327                 if(vflag)
328                         printf("using device %s\n",device);
329         }
330
331         if(aflag == 1)  /* return adaptor type */
332         {
333                 printadaptor(fd);
334                 exit(0);
335         }
336
337         if(mflag == 1)  /* return monitor type */
338         {
339                 printmonitor(fd);
340                 exit(0);
341         }
342
343         if(lflag == 1)  /* list information */
344         {
345                 if(vflag)
346                         printf("processing option -l, listing screen info\n");
347                 printinfo(fd);
348                 exit(0);
349         }
350
351         if(tflag)       /* set screen saver timeout */
352         {
353                 if(vflag)
354                 {
355                         printf(
356                         "processing option -t, setting screen saver timeout: "
357                         );
358                         if(timeout)
359                                 printf("new timeout = %d s\n", timeout);
360                         else
361                                 printf("turned off\n");
362                 }
363
364                 if(ioctl(fd, VGASCREENSAVER, &timeout) < 0)
365                 {
366                         warn("ioctl(VGASCREENSAVER)");
367                         fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n");
368                         exit(2);
369                 }
370                 goto success;
371         }
372
373         if(colms)
374         {
375                 if(vflag)
376                         printf("Setting number of columns to %d\n", colms);
377                 if(ioctl(fd, VGASETCOLMS, &colms) < 0)
378                         err(2, "ioctl(VGASETCOLMS)");
379                 goto success;
380         }
381
382         if(Pflag == 3)
383         {
384                 /* listing VGA palette */
385                 if(vflag)
386                         printf("processing option -p list, "
387                                "listing VGA palette\n");
388
389                 printpalette(fd);
390                 goto success;
391         }
392
393         if(Pflag)
394         {
395                 unsigned int idx;
396
397                 /* setting VGA palette */
398                 if(vflag)
399                         printf("processing option -p, setting VGA palette%s\n",
400                                Pflag == 2? " to default": "");
401
402                 for(idx = 0; idx < NVGAPEL; idx++)
403                         if(Pflag == 2 || palette[idx].dothis)
404                         {
405                                 struct vgapel p;
406                                 p.idx = idx;
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)");
412                         }
413                 goto success;
414         }
415
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;
421
422         if(current != -1)       /* set current screen */
423         {
424                 if(vflag)
425                         printf("processing option -c, setting current screen to %d\n",current);
426
427                 if(ioctl(1, VGASETSCREEN, &screeninfo) == -1)
428                         err(1, "ioctl VGASETSCREEN failed");
429                 exit(0);
430         }
431
432         if(pflag == 1)
433         {
434                 if(vflag)
435                         printf("processing option -V, setting emulation to pure VT220\n");
436                 screeninfo.pure_vt_mode = M_PUREVT;
437         }
438         else if(hflag == 1)
439         {
440                 if(vflag)
441                         printf("processing option -H, setting emulation to VT220 + HP Labels\n");
442                 screeninfo.pure_vt_mode = M_HPVT;
443         }
444         else
445         {
446                 if(vflag)
447                         printf("no change in terminal emulation\n");
448         }
449
450         if(vflag)
451         {
452                 if(res == -1)
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");
466         }
467
468         if(fflag == 1)  /* force 24 lines on/off */
469         {
470                 if(!strcmp(onoff, "on"))
471                 {
472                         fflag = 1;
473                 }
474                 else if(!strcmp(onoff, "off"))
475                 {
476                         fflag = 0;
477                 }
478                 else
479                 {
480                         fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n");
481                         exit(1);
482                 }
483         }
484         screeninfo.force_24lines = fflag;
485
486         if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1)
487                 err(1, "ioctl VGASETSCREEN failed");
488 success:
489         if(vflag)
490                 printf("successful execution of ioctl VGASETSCREEN!\n");
491         exit(0);
492 }
493
494 usage()
495 {
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");
517         exit(1);
518 }
519
520 printadaptor(fd)
521 int fd;
522 {
523         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
524                 err(1, "ioctl VGAGETSCREEN failed");
525         switch(screeninfo.adaptor_type)
526         {
527                 default:
528                 case UNKNOWN_ADAPTOR:
529                         printf("UNKNOWN\n");
530                         break;
531
532                 case MDA_ADAPTOR:
533                         printf("MDA\n");
534                         break;
535
536                 case CGA_ADAPTOR:
537                         printf("CGA\n");
538                         break;
539
540                 case EGA_ADAPTOR:
541                         printf("EGA\n");
542                         break;
543
544                 case VGA_ADAPTOR:
545                         printf("VGA\n");
546                         break;
547         }
548 }
549
550 printmonitor(fd)
551 int fd;
552 {
553         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
554                 err(1, "ioctl VGAGETSCREEN failed");
555         switch(screeninfo.monitor_type)
556         {
557                 default:
558                         printf("UNKNOWN\n");
559                         break;
560
561                 case MONITOR_MONO:
562                         printf("MONO\n");
563                         break;
564
565                 case MONITOR_COLOR:
566                         printf("COLOR\n");
567                         break;
568         }
569 }
570
571 char *vga_type(int number)
572 {
573         static char *vga_tab[] = {
574                 "Generic VGA",
575                 "ET4000",
576                 "ET3000",
577                 "PVGA1A",
578                 "WD90C00",
579                 "WD90C10",
580                 "WD90C11",
581                 "VIDEO 7 VEGA",
582                 "VIDEO 7 FAST",
583                 "VIDEO 7 VER5",
584                 "VIDEO 7 1024I",
585                 "Unknown VIDEO 7",
586                 "TVGA 8800BR",
587                 "TVGA 8800CS",
588                 "TVGA 8900B",
589                 "TVGA 8900C",
590                 "TVGA 8900CL",
591                 "TVGA 9000",
592                 "TVGA 9100",
593                 "TVGA 9200",
594                 "Unknown TRIDENT",
595                 "S3 80C911",
596                 "S3 80C924",
597                 "S3 80C801/80C805",
598                 "S3 80C928",
599                 "Unknown S3",
600                 "CL-GD5402",
601                 "CL-GD5402r1",
602                 "CL-GD5420",
603                 "CL-GD5420r1",
604                 "CL-GD5422",
605                 "CL-GD5424",
606                 "CL-GD5426",
607                 "CL-GD5428",
608
609         };
610         return(vga_tab[number]);
611 }
612
613 char *vga_family(int number)
614 {
615         static char *vga_tab[] = {
616                 "Generic VGA",
617                 "Tseng Labs",
618                 "Western Digital",
619                 "Video Seven",
620                 "Trident",
621                 "S3 Incorporated",
622                 "Cirrus Logic",
623         };
624         return(vga_tab[number]);
625 }
626
627 printinfo(fd)
628 int fd;
629 {
630         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
631                 err(1, "ioctl VGAGETSCREEN failed");
632
633         printf( "\nVideo Adaptor Type           = ");
634
635         switch(screeninfo.adaptor_type)
636         {
637                 default:
638                 case UNKNOWN_ADAPTOR:
639                         printf("UNKNOWN Video Adaptor\n");
640                         break;
641
642                 case MDA_ADAPTOR:
643                         printf("MDA - Monochrome Display Adaptor\n");
644                         break;
645
646                 case CGA_ADAPTOR:
647                         printf("CGA - Color Graphics Adaptor\n");
648                         break;
649
650                 case EGA_ADAPTOR:
651                         printf("EGA - Enhanced Graphics Adaptor\n");
652                         break;
653
654                 case VGA_ADAPTOR:
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");
662                         break;
663         }
664
665         printf( "Display Monitor Type         = ");
666
667         switch(screeninfo.monitor_type)
668         {
669                 default:
670                         printf("UNKNOWN Monitor Type\n");
671                         break;
672
673                 case MONITOR_MONO:
674                         printf("Monochrome Monitor\n");
675                         break;
676
677                 case MONITOR_COLOR:
678                         printf("Color Monitor\n");
679                         break;
680         }
681
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);
686
687         if(screeninfo.pure_vt_mode == M_PUREVT)
688                 printf( "Terminal Emulation Mode      = VT220\n");
689         else
690                 printf( "Terminal Emulation Mode      = VT220 with HP Features\n");
691
692         printf( "Lines                        = ");
693
694         switch(screeninfo.screen_size)
695         {
696                 case SIZ_25ROWS:
697                         printf( "25\n");
698                         break;
699
700                 case SIZ_28ROWS:
701                         printf( "28\n");
702                         break;
703
704                 case SIZ_35ROWS:
705                         printf( "35\n");
706                         break;
707
708                 case SIZ_40ROWS:
709                         printf( "40\n");
710                         break;
711
712                 case SIZ_43ROWS:
713                         printf( "43\n");
714                         break;
715
716                 case SIZ_50ROWS:
717                         printf( "50\n");
718                         break;
719
720                 default:
721                         printf( "UNKNOWN\n");
722                         break;
723         }
724         printf( "Force 24 Lines               = %s",
725                         screeninfo.force_24lines ? "Yes" : "No");
726
727         printf("\n\n");
728 }
729
730 static const char *findname(unsigned idx)
731 {
732         /* try to find a name for palette entry idx */
733         /* if multiple names exist, returns first matching */
734         register struct colname *cnp;
735
736         for(cnp = colnames; cnp->name; cnp++)
737                 if(cnp->idx == idx)
738                         return cnp->name;
739
740         /* not found */
741         return (const char *)NULL;
742 }
743
744 static void printpalette(int fd)
745 {
746         register unsigned idx, last;
747
748         for(idx = 0; idx < NVGAPEL; idx++)
749         {
750                 struct vgapel p;
751                 p.idx = 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;
757         }
758
759         /* find last non-empty entry */
760         for(last = NVGAPEL - 1; last; last--)
761                 if(palette[last].r || palette[last].g || palette[last].b)
762                         break;
763
764         if(last != NVGAPEL - 1)
765                 last++;
766
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++)
771         {
772                 const char *cp;
773                 printf("%5d  %5d  %5d  %5d",
774                        idx, palette[idx].r, palette[idx].g, palette[idx].b);
775                 if(cp = findname(idx))
776                         printf("  %s\n", cp);
777                 else
778                         putchar('\n');
779         }
780         putchar('\n');
781 }
782
783
784 static void parsepopt(char *arg, unsigned *idx,
785                       unsigned *r, unsigned *g, unsigned *b)
786 {
787         char firstarg[21];
788         register unsigned i;
789
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");
793
794         if(firstarg[0] >= '0' && firstarg[0] <= '9') {
795                 *idx = strtoul(firstarg, NULL, 10);
796                 return;
797         }
798
799         for(i = 0; colnames[i].name; i++)
800                 if(strcasecmp(colnames[i].name, firstarg) == 0) {
801                         *idx = colnames[i].idx;
802                         return;
803                 }
804         errx(2, "arg ``%s'' in -p option not recognized", firstarg);
805 }