Unhook gperf, it was only used by gcc2.
[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.3 2004/03/24 17:46:23 cpressey 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 usage(void);
188 static void printadaptor(int);
189 static void printmonitor(int);
190 static void printinfo(int);
191 static void parsepopt(char *arg, unsigned *idx,
192                       unsigned *r, unsigned *g, unsigned *b);
193 static void printpalette(int fd);
194
195 int
196 main(int argc, char **argv)
197 {
198         extern int optind;
199         extern int opterr;
200         extern char *optarg;
201
202         int c;
203         int fd;
204
205         while( (c = getopt(argc, argv, "ac:d:f:HVlms:t:vp:18")) != -1)
206         {
207                 switch(c)
208                 {
209                         case 'a':
210                                 aflag = 1;
211                                 break;
212
213                         case 'l':
214                                 lflag = 1;
215                                 break;
216
217                         case 'm':
218                                 mflag = 1;
219                                 break;
220
221                         case 'c':
222                                 current = atoi(optarg);
223                                 break;
224
225                         case 'd':
226                                 device = optarg;
227                                 dflag = 1;
228                                 break;
229
230                         case 'f':
231                                 onoff = optarg;
232                                 fflag = 1;
233                                 break;
234
235                         case 'V':
236                                 pflag = 1;
237                                 break;
238
239                         case 'H':
240                                 hflag = 1;
241                                 break;
242
243                         case 's':
244                                 if     (!strncmp(optarg, "25", 2))
245                                         res = SIZ_25ROWS;
246                                 else if(!strncmp(optarg, "28", 2))
247                                         res = SIZ_28ROWS;
248                                 else if(!strncmp(optarg, "35", 2))
249                                         res = SIZ_35ROWS;
250                                 else if(!strncmp(optarg, "40", 2))
251                                         res = SIZ_40ROWS;
252                                 else if(!strncmp(optarg, "43", 2))
253                                         res = SIZ_43ROWS;
254                                 else if(!strncmp(optarg, "50", 2))
255                                         res = SIZ_50ROWS;
256                                 break;
257
258                         case 'v':
259                                 vflag++;
260                                 break;
261
262                         case 'p':
263                                 if(!strcmp(optarg, "list"))
264                                 {
265                                         if(Pflag)
266                                                 errx(2, "-p list is mutual exclusive with other -p options");
267                                         Pflag = 3;
268                                 }
269                                 else if(!strcmp(optarg, "default"))
270                                 {
271                                         if(Pflag)
272                                                 errx(2, "multiple -p default not allowed");
273                                         Pflag = 2;
274                                 } else {
275                                         unsigned idx, r, g, b;
276
277                                         if(Pflag > 1)
278                                                 errx(2, "-p default and -p i,r,g,b ambiguous");
279                                         Pflag = 1;
280                                         parsepopt(optarg, &idx, &r, &g, &b);
281                                         if(idx >= NVGAPEL)
282                                                 errx(2, "index %u in -p option out of range", idx);
283                                         palette[idx].r = r;
284                                         palette[idx].g = g;
285                                         palette[idx].b = b;
286                                         palette[idx].dothis = 1;
287                                 }
288                                 break;
289
290                         case 't':
291                                 tflag++;
292                                 timeout = atoi(optarg);
293                                 break;
294
295                         case '1':
296                                 colms = 132;
297                                 break;
298
299                         case '8':
300                                 colms = 80;
301                                 break;
302
303                         case '?':
304                         default:
305                                 usage();
306                                 break;
307                 }
308         }
309
310         if((pflag == 1) && (hflag == 1))
311                 usage();
312
313         if(dflag == -1 && lflag == -1 && current == -1 && pflag == -1 &&
314            hflag == -1 && res == -1 && Pflag == 0 && tflag == 0 && fflag == -1
315            && colms == 0 && mflag == -1)
316         {
317                 lflag = 1;
318         }
319
320         if(dflag == -1)
321         {
322                 if(vflag)
323                         printf("using current device\n");
324                 fd = DEFAULTFD;         /* -hm, Feb 12 1993 */
325         }
326         else
327         {
328                 if((fd = open(device, O_RDWR)) == -1)
329                         err(1, "ERROR opening %s", device);
330                 if(vflag)
331                         printf("using device %s\n",device);
332         }
333
334         if(aflag == 1)  /* return adaptor type */
335         {
336                 printadaptor(fd);
337                 exit(0);
338         }
339
340         if(mflag == 1)  /* return monitor type */
341         {
342                 printmonitor(fd);
343                 exit(0);
344         }
345
346         if(lflag == 1)  /* list information */
347         {
348                 if(vflag)
349                         printf("processing option -l, listing screen info\n");
350                 printinfo(fd);
351                 exit(0);
352         }
353
354         if(tflag)       /* set screen saver timeout */
355         {
356                 if(vflag)
357                 {
358                         printf(
359                         "processing option -t, setting screen saver timeout: "
360                         );
361                         if(timeout)
362                                 printf("new timeout = %d s\n", timeout);
363                         else
364                                 printf("turned off\n");
365                 }
366
367                 if(ioctl(fd, VGASCREENSAVER, &timeout) < 0)
368                 {
369                         warn("ioctl(VGASCREENSAVER)");
370                         fprintf(stderr, "Check the driver, the screensaver is probably not compiled in!\n");
371                         exit(2);
372                 }
373                 goto success;
374         }
375
376         if(colms)
377         {
378                 if(vflag)
379                         printf("Setting number of columns to %d\n", colms);
380                 if(ioctl(fd, VGASETCOLMS, &colms) < 0)
381                         err(2, "ioctl(VGASETCOLMS)");
382                 goto success;
383         }
384
385         if(Pflag == 3)
386         {
387                 /* listing VGA palette */
388                 if(vflag)
389                         printf("processing option -p list, "
390                                "listing VGA palette\n");
391
392                 printpalette(fd);
393                 goto success;
394         }
395
396         if(Pflag)
397         {
398                 unsigned int idx;
399
400                 /* setting VGA palette */
401                 if(vflag)
402                         printf("processing option -p, setting VGA palette%s\n",
403                                Pflag == 2? " to default": "");
404
405                 for(idx = 0; idx < NVGAPEL; idx++)
406                         if(Pflag == 2 || palette[idx].dothis)
407                         {
408                                 struct vgapel p;
409                                 p.idx = idx;
410                                 p.r = palette[idx].r;
411                                 p.g = palette[idx].g;
412                                 p.b = palette[idx].b;
413                                 if(ioctl(fd, VGAWRITEPEL, (caddr_t)&p) < 0)
414                                         err(2, "ioctl(fd, VGAWRITEPEL)");
415                         }
416                 goto success;
417         }
418
419         screeninfo.screen_no = -1; /* We are using fd */
420         screeninfo.current_screen = current;
421         screeninfo.pure_vt_mode = -1;
422         screeninfo.screen_size = res;
423         screeninfo.force_24lines = -1;
424
425         if(current != -1)       /* set current screen */
426         {
427                 if(vflag)
428                         printf("processing option -c, setting current screen to %d\n",current);
429
430                 if(ioctl(1, VGASETSCREEN, &screeninfo) == -1)
431                         err(1, "ioctl VGASETSCREEN failed");
432                 exit(0);
433         }
434
435         if(pflag == 1)
436         {
437                 if(vflag)
438                         printf("processing option -V, setting emulation to pure VT220\n");
439                 screeninfo.pure_vt_mode = M_PUREVT;
440         }
441         else if(hflag == 1)
442         {
443                 if(vflag)
444                         printf("processing option -H, setting emulation to VT220 + HP Labels\n");
445                 screeninfo.pure_vt_mode = M_HPVT;
446         }
447         else
448         {
449                 if(vflag)
450                         printf("no change in terminal emulation\n");
451         }
452
453         if(vflag)
454         {
455                 if(res == -1)
456                         printf("no change in screen resolution\n");
457                 else if(res == SIZ_25ROWS)
458                         printf("change screen resolution to 25 lines\n");
459                 else if(res == SIZ_28ROWS)
460                         printf("change screen resolution to 28 lines\n");
461                 else if(res == SIZ_35ROWS)
462                         printf("change screen resolution to 35 lines\n");
463                 else if(res == SIZ_40ROWS)
464                         printf("change screen resolution to 40 lines\n");
465                 else if(res == SIZ_43ROWS)
466                         printf("change screen resolution to 43 lines\n");
467                 else if(res == SIZ_50ROWS)
468                         printf("change screen resolution to 50 lines\n");
469         }
470
471         if(fflag == 1)  /* force 24 lines on/off */
472         {
473                 if(!strcmp(onoff, "on"))
474                 {
475                         fflag = 1;
476                 }
477                 else if(!strcmp(onoff, "off"))
478                 {
479                         fflag = 0;
480                 }
481                 else
482                 {
483                         fprintf(stderr,"you must specify 'on' or 'off' with -f option!\n");
484                         exit(1);
485                 }
486         }
487         screeninfo.force_24lines = fflag;
488
489         if(ioctl(fd, VGASETSCREEN, &screeninfo) == -1)
490                 err(1, "ioctl VGASETSCREEN failed");
491 success:
492         if(vflag)
493                 printf("successful execution of ioctl VGASETSCREEN!\n");
494         exit(0);
495 }
496
497 void
498 usage(void)
499 {
500         fprintf(stderr,"\nscon - screen control utility for the pcvt video driver\n");
501         fprintf(stderr,"usage: scon -a -l -m -v -c [n] -d [dev] -f [on|off] -V -H -s [n]\n");
502         fprintf(stderr,"usage: scon -p [default | list | i,r,g,b] | -t [sec] | -1 | -8\n");
503         fprintf(stderr,"       -a              list video adaptor type (MDA,CGA,EGA or VGA)\n");
504         fprintf(stderr,"       -c <screen no>  switch current virtual screen to <screen no>\n");
505         fprintf(stderr,"       -d <device>     set parameters(-V|-H|-s) for virtual device\n");
506         fprintf(stderr,"       -f <on|off>     force 24 lines in VT 25 lines and HP 28 lines mode\n");
507         fprintf(stderr,"       -H              set VT220/HP emulation mode for a virtual screen\n");
508         fprintf(stderr,"       -l              list current parameters for a virtual screen\n");
509         fprintf(stderr,"       -m              report monitor type (MONO/COLOR)\n");
510         fprintf(stderr,"       -p default      set default VGA palette\n");
511         fprintf(stderr,"       -p list         list current VGA palette\n");
512         fprintf(stderr,"       -p <i,r,g,b>    set VGA palette entry i to r/g/b\n");
513         fprintf(stderr,"       -p <name,r,g,b> set VGA palette entry for color name to r/g/b\n");
514         fprintf(stderr,"       -s <lines>      set 25, 28, 35, 40, 43 or 50 lines for a virtual screen\n");
515         fprintf(stderr,"       -t <timeout>    set screen saver timeout [seconds]\n");
516         fprintf(stderr,"       -1              set 132 columns mode\n");
517         fprintf(stderr,"       -8              set 80 columns mode\n");
518         fprintf(stderr,"       -v              verbose mode\n");
519         fprintf(stderr,"       -V              set pure VT220 emulation for a virtual screen\n");
520         fprintf(stderr,"       -?              display help (this message)\n\n");
521         exit(1);
522 }
523
524 void
525 printadaptor(int fd)
526 {
527         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
528                 err(1, "ioctl VGAGETSCREEN failed");
529         switch(screeninfo.adaptor_type)
530         {
531                 default:
532                 case UNKNOWN_ADAPTOR:
533                         printf("UNKNOWN\n");
534                         break;
535
536                 case MDA_ADAPTOR:
537                         printf("MDA\n");
538                         break;
539
540                 case CGA_ADAPTOR:
541                         printf("CGA\n");
542                         break;
543
544                 case EGA_ADAPTOR:
545                         printf("EGA\n");
546                         break;
547
548                 case VGA_ADAPTOR:
549                         printf("VGA\n");
550                         break;
551         }
552 }
553
554 void
555 printmonitor(int fd)
556 {
557         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
558                 err(1, "ioctl VGAGETSCREEN failed");
559         switch(screeninfo.monitor_type)
560         {
561                 default:
562                         printf("UNKNOWN\n");
563                         break;
564
565                 case MONITOR_MONO:
566                         printf("MONO\n");
567                         break;
568
569                 case MONITOR_COLOR:
570                         printf("COLOR\n");
571                         break;
572         }
573 }
574
575 char *
576 vga_type(int number)
577 {
578         static char *vga_tab[] = {
579                 "Generic VGA",
580                 "ET4000",
581                 "ET3000",
582                 "PVGA1A",
583                 "WD90C00",
584                 "WD90C10",
585                 "WD90C11",
586                 "VIDEO 7 VEGA",
587                 "VIDEO 7 FAST",
588                 "VIDEO 7 VER5",
589                 "VIDEO 7 1024I",
590                 "Unknown VIDEO 7",
591                 "TVGA 8800BR",
592                 "TVGA 8800CS",
593                 "TVGA 8900B",
594                 "TVGA 8900C",
595                 "TVGA 8900CL",
596                 "TVGA 9000",
597                 "TVGA 9100",
598                 "TVGA 9200",
599                 "Unknown TRIDENT",
600                 "S3 80C911",
601                 "S3 80C924",
602                 "S3 80C801/80C805",
603                 "S3 80C928",
604                 "Unknown S3",
605                 "CL-GD5402",
606                 "CL-GD5402r1",
607                 "CL-GD5420",
608                 "CL-GD5420r1",
609                 "CL-GD5422",
610                 "CL-GD5424",
611                 "CL-GD5426",
612                 "CL-GD5428",
613
614         };
615         return(vga_tab[number]);
616 }
617
618 char *
619 vga_family(int number)
620 {
621         static char *vga_tab[] = {
622                 "Generic VGA",
623                 "Tseng Labs",
624                 "Western Digital",
625                 "Video Seven",
626                 "Trident",
627                 "S3 Incorporated",
628                 "Cirrus Logic",
629         };
630         return(vga_tab[number]);
631 }
632
633 void
634 printinfo(int fd)
635 {
636         if(ioctl(fd, VGAGETSCREEN, &screeninfo) == -1)
637                 err(1, "ioctl VGAGETSCREEN failed");
638
639         printf( "\nVideo Adaptor Type           = ");
640
641         switch(screeninfo.adaptor_type)
642         {
643                 default:
644                 case UNKNOWN_ADAPTOR:
645                         printf("UNKNOWN Video Adaptor\n");
646                         break;
647
648                 case MDA_ADAPTOR:
649                         printf("MDA - Monochrome Display Adaptor\n");
650                         break;
651
652                 case CGA_ADAPTOR:
653                         printf("CGA - Color Graphics Adaptor\n");
654                         break;
655
656                 case EGA_ADAPTOR:
657                         printf("EGA - Enhanced Graphics Adaptor\n");
658                         break;
659
660                 case VGA_ADAPTOR:
661                         printf("VGA - Video Graphics Adaptor/Array\n");
662                         printf(" VGA Chipset Manufacturer    = %s\n",
663                                         vga_family(screeninfo.vga_family));
664                         printf(" VGA Chipset Type            = %s\n",
665                                         vga_type(screeninfo.vga_type));
666                         printf(" Support for 132 Column Mode = %s\n",
667                                         screeninfo.vga_132 ? "Yes" : "No");
668                         break;
669         }
670
671         printf( "Display Monitor Type         = ");
672
673         switch(screeninfo.monitor_type)
674         {
675                 default:
676                         printf("UNKNOWN Monitor Type\n");
677                         break;
678
679                 case MONITOR_MONO:
680                         printf("Monochrome Monitor\n");
681                         break;
682
683                 case MONITOR_COLOR:
684                         printf("Color Monitor\n");
685                         break;
686         }
687
688         printf( "Number of Downloadable Fonts = %d\n",screeninfo.totalfonts);
689         printf( "Number of Virtual Screens    = %d\n",screeninfo.totalscreens);
690         printf( "Info Request Screen Number   = %d\n",screeninfo.screen_no);
691         printf( "Current Displayed Screen     = %d\n",screeninfo.current_screen);
692
693         if(screeninfo.pure_vt_mode == M_PUREVT)
694                 printf( "Terminal Emulation Mode      = VT220\n");
695         else
696                 printf( "Terminal Emulation Mode      = VT220 with HP Features\n");
697
698         printf( "Lines                        = ");
699
700         switch(screeninfo.screen_size)
701         {
702                 case SIZ_25ROWS:
703                         printf( "25\n");
704                         break;
705
706                 case SIZ_28ROWS:
707                         printf( "28\n");
708                         break;
709
710                 case SIZ_35ROWS:
711                         printf( "35\n");
712                         break;
713
714                 case SIZ_40ROWS:
715                         printf( "40\n");
716                         break;
717
718                 case SIZ_43ROWS:
719                         printf( "43\n");
720                         break;
721
722                 case SIZ_50ROWS:
723                         printf( "50\n");
724                         break;
725
726                 default:
727                         printf( "UNKNOWN\n");
728                         break;
729         }
730         printf( "Force 24 Lines               = %s",
731                         screeninfo.force_24lines ? "Yes" : "No");
732
733         printf("\n\n");
734 }
735
736 static const char *
737 findname(unsigned idx)
738 {
739         /* try to find a name for palette entry idx */
740         /* if multiple names exist, returns first matching */
741         struct colname *cnp;
742
743         for(cnp = colnames; cnp->name; cnp++)
744                 if(cnp->idx == idx)
745                         return cnp->name;
746
747         /* not found */
748         return (const char *)NULL;
749 }
750
751 static void
752 printpalette(int fd)
753 {
754         unsigned idx, last;
755
756         for(idx = 0; idx < NVGAPEL; idx++)
757         {
758                 struct vgapel p;
759                 p.idx = idx;
760                 if(ioctl(fd, VGAREADPEL, &p) < 0)
761                         err(2, "ioctl(VGAREADPEL)");
762                 palette[idx].r = p.r;
763                 palette[idx].g = p.g;
764                 palette[idx].b = p.b;
765         }
766
767         /* find last non-empty entry */
768         for(last = NVGAPEL - 1; last; last--)
769                 if(palette[last].r || palette[last].g || palette[last].b)
770                         break;
771
772         if(last != NVGAPEL - 1)
773                 last++;
774
775         /* now, everything's collected. print out table */
776         printf("VGA palette status\n");
777         printf("index    red  green   blue  name\n");
778         for(idx = 0; idx < last; idx++)
779         {
780                 const char *cp;
781                 printf("%5d  %5d  %5d  %5d",
782                        idx, palette[idx].r, palette[idx].g, palette[idx].b);
783                 if(cp = findname(idx))
784                         printf("  %s\n", cp);
785                 else
786                         putchar('\n');
787         }
788         putchar('\n');
789 }
790
791
792 static void
793 parsepopt(char *arg, unsigned *idx, unsigned *r, unsigned *g, unsigned *b)
794 {
795         char firstarg[21];
796         unsigned i;
797
798         if(sscanf(arg, "%20[a-zA-Z0-9]%*[,:]%u,%u,%u", firstarg, r, g, b) < 4
799            || strlen(firstarg) == 0)
800                 errx(2, "too few args in -p i,r,g,b");
801
802         if(firstarg[0] >= '0' && firstarg[0] <= '9') {
803                 *idx = strtoul(firstarg, NULL, 10);
804                 return;
805         }
806
807         for(i = 0; colnames[i].name; i++)
808                 if(strcasecmp(colnames[i].name, firstarg) == 0) {
809                         *idx = colnames[i].idx;
810                         return;
811                 }
812         errx(2, "arg ``%s'' in -p option not recognized", firstarg);
813 }