Home | History | Annotate | Line # | Download | only in grfconfig
grfconfig.c revision 1.7
      1 /*	$NetBSD: grfconfig.c,v 1.7 1997/10/08 22:19:19 jtc Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Ezra Story and Bernd Ernesti.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 #ifndef lint
     41 __COPYRIGHT("@(#) Copyright (c) 1997 The NetBSD Foundation, Inc.\n\
     42 	All rights reserved.\n");
     43 #endif /* not lint */
     44 
     45 #ifndef lint
     46 __RCSID("$NetBSD: grfconfig.c,v 1.7 1997/10/08 22:19:19 jtc Exp $");
     47 #endif /* not lint */
     48 
     49 #include <sys/file.h>
     50 #include <sys/ioctl.h>
     51 #include <ctype.h>
     52 #include <limits.h>
     53 #include <stdio.h>
     54 #include <stdlib.h>
     55 #include <string.h>
     56 #include <unistd.h>
     57 
     58 #include <amiga/dev/grfioctl.h>
     59 
     60 extern char *optarg;
     61 extern int optind;
     62 
     63 int main __P((int, char **));
     64 static void print_rawdata __P((struct grfvideo_mode *, int));
     65 
     66 static struct grf_flag {
     67 	u_short	grf_flag_number;
     68 	char	*grf_flag_name;
     69 } grf_flags[] = {
     70 	{GRF_FLAGS_DBLSCAN,		"doublescan"},
     71 	{GRF_FLAGS_LACE,		"interlace"},
     72 	{GRF_FLAGS_PHSYNC,		"+hsync"},
     73 	{GRF_FLAGS_NHSYNC,		"-hsync"},
     74 	{GRF_FLAGS_PVSYNC,		"+vsync"},
     75 	{GRF_FLAGS_NVSYNC,		"-vsync"},
     76 	{GRF_FLAGS_SYNC_ON_GREEN,	"sync-on-green"},
     77 	{0,				0}
     78 };
     79 
     80 /*
     81  * Dynamic mode loader for NetBSD/Amiga grf devices.
     82  */
     83 int
     84 main(ac, av)
     85 	int     ac;
     86 	char  **av;
     87 {
     88 	struct	grfvideo_mode gv[1];
     89 	struct	grf_flag *grf_flagp;
     90 	FILE	*fp;
     91 	int	c, y, grffd;
     92 	int	i, lineno = 0;
     93 	int	uplim, lowlim;
     94 	char	rawdata = 0, testmode = 0;
     95 	char	*grfdevice = 0;
     96 	char	*modefile = 0;
     97 	char	buf[_POSIX2_LINE_MAX], obuf[_POSIX2_LINE_MAX];
     98 	char	*cps[31];
     99 	char	*p;
    100 	char	*errortext;
    101 
    102 
    103 	while ((c = getopt(ac, av, "rt")) != -1) {
    104 		switch (c) {
    105 		case 'r':	/* raw output */
    106 			rawdata = 1;
    107 			break;
    108 		case 't':	/* test the modefile without setting it */
    109 			testmode = 1;
    110 			break;
    111 		default:
    112 			printf("grfconfig [-r] device [file]\n");
    113 			return (1);
    114 		}
    115 	}
    116 	ac -= optind;
    117 	av += optind;
    118 
    119 
    120 	if (ac >= 1)
    121 		grfdevice = av[0];
    122 	else {
    123 		printf("grfconfig: No grf device specified.\n");
    124 		return (1);
    125 	}
    126 
    127 	if (ac >= 2)
    128 		modefile = av[1];
    129 
    130 	if ((grffd = open(grfdevice, O_RDWR)) < 0) {
    131 		printf("grfconfig: can't open grf device.\n");
    132 		return (1);
    133 	}
    134 	/* If a mode file is specificied, load it in, don't display any info. */
    135 
    136 	if (modefile) {
    137 		if (!(fp = fopen(modefile, "r"))) {
    138 			printf("grfconfig: Cannot open mode definition "
    139 			    "file.\n");
    140 			return (1);
    141 		}
    142 		while (fgets(buf, sizeof(buf), fp)) {
    143 			/*
    144 			 * check for end-of-section, comments, strip off trailing
    145 			 * spaces and newline character.
    146 			 */
    147 			for (p = buf; isspace(*p); ++p)
    148 				continue;
    149 			if (*p == '\0' || *p == '#')
    150 				continue;
    151 			for (p = strchr(buf, '\0'); isspace(*--p);)
    152 				continue;
    153 			*++p = '\0';
    154 
    155 			sprintf(obuf, "%s", buf);
    156 			lineno = lineno + 1;
    157 
    158 			for (i = 0, *cps = strtok(buf, " \b\t\r\n");
    159 			    cps[i] != NULL && i < 30; i++)
    160 				cps[i + 1] = strtok(NULL, " \b\t\r\n");
    161 			cps[i] = NULL;
    162 
    163 			if (cps[13] == NULL) {
    164 				printf("grfconfig: too few values in mode "
    165 				    "definition file:\n %s\n", obuf);
    166 				return (1);
    167 			}
    168 
    169 			gv->pixel_clock	= atoi(cps[1]);
    170 			gv->disp_width	= atoi(cps[2]);
    171 			gv->disp_height	= atoi(cps[3]);
    172 			gv->depth	= atoi(cps[4]);
    173 			gv->hblank_start	= atoi(cps[5]);
    174 			gv->hsync_start	= atoi(cps[6]);
    175 			gv->hsync_stop	= atoi(cps[7]);
    176 			gv->htotal	= atoi(cps[8]);
    177 			gv->vblank_start	= atoi(cps[9]);
    178 			gv->vsync_start	= atoi(cps[10]);
    179 			gv->vsync_stop	= atoi(cps[11]);
    180 			gv->vtotal	= atoi(cps[12]);
    181 
    182 			if ((y = atoi(cps[0])))
    183 				gv->mode_num = y;
    184 			else
    185 				if (strncasecmp("c", cps[0], 1) == 0) {
    186 					gv->mode_num = 255;
    187 					gv->depth = 4;
    188 				} else {
    189 					printf("grfconfig: Illegal mode "
    190 					    "number: %s\n", cps[0]);
    191 					return (1);
    192 				}
    193 
    194 			if ((gv->pixel_clock == 0) ||
    195 			    (gv->disp_width == 0) ||
    196 			    (gv->disp_height == 0) ||
    197 			    (gv->depth == 0) ||
    198 			    (gv->hblank_start == 0) ||
    199 			    (gv->hsync_start == 0) ||
    200 			    (gv->hsync_stop == 0) ||
    201 			    (gv->htotal == 0) ||
    202 			    (gv->vblank_start == 0) ||
    203 			    (gv->vsync_start == 0) ||
    204 			    (gv->vsync_stop == 0) ||
    205 			    (gv->vtotal == 0)) {
    206 				printf("grfconfig: Illegal value in "
    207 				    "mode #%d:\n %s\n", gv->mode_num, obuf);
    208 				return (1);
    209 			}
    210 
    211 			if (strstr(obuf, "default") != NULL) {
    212 				gv->disp_flags = GRF_FLAGS_DEFAULT;
    213 			} else {
    214 				gv->disp_flags = GRF_FLAGS_DEFAULT;
    215 				for (grf_flagp = grf_flags;
    216 				  grf_flagp->grf_flag_number; grf_flagp++) {
    217 				    if (strstr(obuf, grf_flagp->grf_flag_name) != NULL) {
    218 					gv->disp_flags |= grf_flagp->grf_flag_number;
    219 				    }
    220 				}
    221 				if (gv->disp_flags == GRF_FLAGS_DEFAULT) {
    222 					printf("grfconfig: Your are using an "
    223 					    "mode file with an obsolete "
    224 					    "format.\n See the manpage of "
    225 					    "grfconfig for more information "
    226 					    "about the new mode definition "
    227 					    "file.\n");
    228 					return (1);
    229 				}
    230 			}
    231 
    232 			/*
    233 			 * Check for impossible gv->disp_flags:
    234 			 * doublescan and interlace,
    235 			 * +hsync and -hsync
    236 			 * +vsync and -vsync.
    237 			 */
    238 			errortext = NULL;
    239 			if ((gv->disp_flags & GRF_FLAGS_DBLSCAN) &&
    240 			    (gv->disp_flags & GRF_FLAGS_LACE))
    241 				errortext = "Interlace and Doublescan";
    242 			if ((gv->disp_flags & GRF_FLAGS_PHSYNC) &&
    243 			    (gv->disp_flags & GRF_FLAGS_NHSYNC))
    244 				errortext = "+hsync and -hsync";
    245 			if ((gv->disp_flags & GRF_FLAGS_PVSYNC) &&
    246 			    (gv->disp_flags & GRF_FLAGS_NVSYNC))
    247 				errortext = "+vsync and -vsync";
    248 
    249 			if (errortext != NULL) {
    250 				printf("grfconfig: Illegal flags in "
    251 				    "mode #%d: %s are both defined!\n",
    252 				    gv->mode_num, errortext);
    253 				return (1);
    254 			}
    255 
    256 			/* Check for old horizontal cycle values */
    257 			if ((gv->htotal < (gv->disp_width / 4))) {
    258 				gv->hblank_start *= 8;
    259 				gv->hsync_start *= 8;
    260 				gv->hsync_stop *= 8;
    261 				gv->htotal *= 8;
    262 				printf("grfconfig: Old and no longer "
    263 				    "supported horizontal videoclock cycle "
    264 				    "values.\n Wrong mode line:\n  %s\n "
    265 				    "This could be a possible good mode "
    266 				    "line:\n  ", obuf);
    267 				printf("%d ", gv->mode_num);
    268 				print_rawdata(gv, 0);
    269 				printf(" See the manpage of grfconfig for "
    270 				    "more information about the new mode "
    271 				    "definition file.\n");
    272 				return (1);
    273 			}
    274 
    275 			/* Check for old interlace or doublescan modes */
    276 			uplim = gv->disp_height + (gv->disp_height / 4);
    277 			lowlim = gv->disp_height - (gv->disp_height / 4);
    278 			if (((gv->vtotal * 2) > lowlim) &&
    279 			    ((gv->vtotal * 2) < uplim)) {
    280 				gv->vblank_start *= 2;
    281 				gv->vsync_start *= 2;
    282 				gv->vsync_stop *= 2;
    283 				gv->vtotal *= 2;
    284 				gv->disp_flags &= ~GRF_FLAGS_DBLSCAN;
    285 				gv->disp_flags |= GRF_FLAGS_LACE;
    286 				printf("grfconfig: Old and no longer "
    287 				    "supported vertical values for "
    288 				    "interlace modes.\n Wrong mode "
    289 				    "line:\n  %s\n This could be a "
    290 				    "possible good mode line:\n  ", obuf);
    291 				printf("%d ", gv->mode_num);
    292 				print_rawdata(gv, 0);
    293 				printf(" See the manpage of grfconfig for "
    294 				    "more information about the new mode "
    295 				    "definition file.\n");
    296 				return (1);
    297 			} else if (((gv->vtotal / 2) > lowlim) &&
    298 			    ((gv->vtotal / 2) < uplim)) {
    299 				gv->vblank_start /= 2;
    300 				gv->vsync_start /= 2;
    301 				gv->vsync_stop /= 2;
    302 				gv->vtotal /= 2;
    303 				gv->disp_flags &= ~GRF_FLAGS_LACE;
    304 				gv->disp_flags |= GRF_FLAGS_DBLSCAN;
    305 				printf("grfconfig: Old and no longer "
    306 				    "supported vertical values for "
    307 				    "doublescan modes.\n Wrong mode "
    308 				    "line:\n  %s\n This could be a "
    309 				    "possible good mode line:\n  ", obuf);
    310 				printf("%d ", gv->mode_num);
    311 				print_rawdata(gv, 0);
    312 				printf(" See the manpage of grfconfig for "
    313 				    "more information about the new mode "
    314 				    "definition file.\n");
    315 				return (1);
    316 			}
    317 
    318 			if (testmode == 1) {
    319 				if (lineno == 1)
    320 					printf("num clk wid hi dep hbs "
    321 					    "hss hse ht vbs vss vse vt "
    322 					    "flags\n");
    323 				printf("%d ", gv->mode_num);
    324 				print_rawdata(gv, 1);
    325 			} else {
    326 				gv->mode_descr[0] = 0;
    327 				if (ioctl(grffd, GRFIOCSETMON, (char *) gv) < 0)
    328 					printf("grfconfig: bad monitor "
    329 					    "definition for mode #%d.\n",
    330 					    gv->mode_num);
    331 			}
    332 		}
    333 		fclose(fp);
    334 	} else {
    335 		ioctl(grffd, GRFGETNUMVM, &y);
    336 		y += 2;
    337 		for (c = 1; c < y; c++) {
    338 			c = gv->mode_num = (c != (y - 1)) ? c : 255;
    339 			if (ioctl(grffd, GRFGETVMODE, gv) < 0)
    340 				continue;
    341 			if (rawdata) {
    342 				if (c == 255)
    343 					printf("c ");
    344 				else
    345 					printf("%d ", c);
    346 				print_rawdata(gv, 0);
    347 				continue;
    348 			}
    349 			if (c == 255)
    350 				printf("Console: ");
    351 			else
    352 				printf("%2d: ", gv->mode_num);
    353 
    354 			printf("%dx%d",
    355 			    gv->disp_width,
    356 			    gv->disp_height);
    357 
    358 			if (c != 255)
    359 				printf("x%d", gv->depth);
    360 			else
    361 				printf(" (%dx%d)",
    362 				    gv->disp_width / 8,
    363 				    gv->disp_height / gv->depth);
    364 
    365 			printf("\t%ld.%ldkHz @ %ldHz",
    366 			    gv->pixel_clock / (gv->htotal * 1000),
    367 			    (gv->pixel_clock / (gv->htotal * 100))
    368     	    	    	    	% 10,
    369 			    gv->pixel_clock / (gv->htotal * gv->vtotal));
    370 			printf(" flags:");
    371 
    372 			if (gv->disp_flags == GRF_FLAGS_DEFAULT) {
    373 				printf(" default");
    374 			} else {
    375 				for (grf_flagp = grf_flags;
    376 				  grf_flagp->grf_flag_number; grf_flagp++) {
    377 				    if (gv->disp_flags & grf_flagp->grf_flag_number) {
    378 					printf(" %s", grf_flagp->grf_flag_name);
    379 				    }
    380 				}
    381 			}
    382 			printf("\n");
    383 		}
    384 	}
    385 
    386 	close(grffd);
    387 	return (0);
    388 }
    389 
    390 static void
    391 print_rawdata(gv, rawflags)
    392 	struct grfvideo_mode *gv;
    393 	int rawflags;
    394 {
    395 	struct	grf_flag *grf_flagp;
    396 
    397 	printf("%ld %d %d %d %d %d %d %d %d %d %d %d",
    398 		gv->pixel_clock,
    399 		gv->disp_width,
    400 		gv->disp_height,
    401 		gv->depth,
    402 		gv->hblank_start,
    403 		gv->hsync_start,
    404 		gv->hsync_stop,
    405 		gv->htotal,
    406 		gv->vblank_start,
    407 		gv->vsync_start,
    408 		gv->vsync_stop,
    409 		gv->vtotal);
    410 		if (rawflags) {
    411 			printf(" 0x%.2x", gv->disp_flags);
    412 		} else {
    413 			if (gv->disp_flags == GRF_FLAGS_DEFAULT) {
    414 				printf(" default");
    415 			} else {
    416 				for (grf_flagp = grf_flags;
    417 				  grf_flagp->grf_flag_number; grf_flagp++) {
    418 				    if (gv->disp_flags & grf_flagp->grf_flag_number) {
    419 					printf(" %s", grf_flagp->grf_flag_name);
    420 				    }
    421 				}
    422 			}
    423 		}
    424 		printf("\n");
    425 }
    426