xref: /netbsd-src/usr.sbin/iteconfig/iteconfig.c (revision 421949a31fb0942d3d87278998c2d7d432d8b3cb)
1*421949a3Ssevan /*	$NetBSD: iteconfig.c,v 1.10 2018/01/23 21:06:25 sevan Exp $	*/
228224014Schopps /*
328224014Schopps  * Copyright (c) 1994 Christian E. Hopps
428224014Schopps  * All rights reserved.
528224014Schopps  *
628224014Schopps  * Redistribution and use in source and binary forms, with or without
728224014Schopps  * modification, are permitted provided that the following conditions
828224014Schopps  * are met:
928224014Schopps  * 1. Redistributions of source code must retain the above copyright
1028224014Schopps  *    notice, this list of conditions and the following disclaimer.
1128224014Schopps  * 2. Redistributions in binary form must reproduce the above copyright
1228224014Schopps  *    notice, this list of conditions and the following disclaimer in the
1328224014Schopps  *    documentation and/or other materials provided with the distribution.
1428224014Schopps  * 3. All advertising materials mentioning features or use of this software
1528224014Schopps  *    must display the following acknowledgement:
1628224014Schopps  *      This product includes software developed by Christian E. Hopps
1728224014Schopps  * 4. The name of the author may not be used to endorse or promote products
1828224014Schopps  *    derived from this software without specific prior written permission
1928224014Schopps  *
2028224014Schopps  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2128224014Schopps  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2228224014Schopps  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2328224014Schopps  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2428224014Schopps  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2528224014Schopps  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2628224014Schopps  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2728224014Schopps  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2828224014Schopps  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2928224014Schopps  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3028224014Schopps  *
3128224014Schopps  */
32ffaa76b3Slukem #include <sys/cdefs.h>
33ffaa76b3Slukem #ifndef lint
34*421949a3Ssevan __RCSID("$NetBSD: iteconfig.c,v 1.10 2018/01/23 21:06:25 sevan Exp $");
35ffaa76b3Slukem #endif
3628224014Schopps 
3728224014Schopps #include <sys/types.h>
3828224014Schopps #include <sys/stat.h>
3928224014Schopps #include <sys/ioctl.h>
4028224014Schopps #include <sys/queue.h>
4193dc1f1fSleo 
4293dc1f1fSleo #if !defined(amiga) && !defined(atari)
4393dc1f1fSleo #error "This source is not suitable for this architecture!"
4493dc1f1fSleo #endif
4593dc1f1fSleo 
4693dc1f1fSleo #if defined(amiga)
4728224014Schopps #include <amiga/dev/grfabs_reg.h>
4828224014Schopps #include <amiga/dev/viewioctl.h>
4928224014Schopps #include <amiga/dev/iteioctl.h>
5093dc1f1fSleo #endif /* defined(amiga)	*/
5193dc1f1fSleo 
5293dc1f1fSleo #if defined(atari)
5393dc1f1fSleo #include <atari/dev/grfabs_reg.h>
5493dc1f1fSleo #include <atari/dev/viewioctl.h>
5593dc1f1fSleo #include <atari/dev/iteioctl.h>
5693dc1f1fSleo #endif /* defined(atari)	*/
5728224014Schopps 
580a4d67ddScgd #include <err.h>
590a4d67ddScgd #include <errno.h>
600a4d67ddScgd #include <fcntl.h>
610a4d67ddScgd #include <limits.h>
620a4d67ddScgd #include <stdio.h>
630a4d67ddScgd #include <stdlib.h>
643400c43eSmhitch #include <string.h>
650a4d67ddScgd #include <termios.h>
660a4d67ddScgd #include <unistd.h>
6728224014Schopps 
680a4d67ddScgd #include "pathnames.h"
690a4d67ddScgd 
70*421949a3Ssevan int	initialize(const char *, struct itewinsize *, struct itebell *,
71*421949a3Ssevan 			struct itewinsize *, struct itebell *);
72*421949a3Ssevan void	printcmap(colormap_t *, int);
73*421949a3Ssevan void	xioctl(int, int, void *);
74*421949a3Ssevan colormap_t *xgetcmap(int, int);
75*421949a3Ssevan long	xstrtol(char *);
76*421949a3Ssevan static void	usage(void) __dead;
7728224014Schopps 
7828224014Schopps int
main(int argc,char * argv[])79*421949a3Ssevan main(int argc, char *argv[])
8028224014Schopps {
818a0b9bb0Schopps 	struct itewinsize is, newis;
828a0b9bb0Schopps 	struct itebell ib, newib;
8328224014Schopps 	struct winsize ws;
8428224014Schopps 	colormap_t *cm;
85094ee530Smlelstv 	const char *file = _PATH_CONSOLE;
8693dc1f1fSleo 	int ch, fd, i, iflag, max_colors, did_reset;
8728224014Schopps 	long val;
8828224014Schopps 
890a4d67ddScgd 	iflag = 0;
9093dc1f1fSleo 	did_reset = 0;
9128224014Schopps 
9293dc1f1fSleo 	fd = initialize(_PATH_CONSOLE, &is, &ib, &newis, &newib);
9328224014Schopps 
9493dc1f1fSleo 	while ((ch = getopt(argc, argv, "D:H:P:T:V:W:X:Y:d:f:h:ip:t:v:w:x:y:"))
95ffaa76b3Slukem 	    != -1) {
960a4d67ddScgd 		switch (ch) {
970a4d67ddScgd 		case 'D':		/* undocumented backward compat */
9828224014Schopps 		case 'd':
9928224014Schopps 			newis.depth = xstrtol(optarg);
10028224014Schopps 			break;
10193dc1f1fSleo 		case 'f':
10293dc1f1fSleo 			if (did_reset)
10393dc1f1fSleo 				break;
10493dc1f1fSleo 			if (fd != -1)
10593dc1f1fSleo 				close(fd);
10693dc1f1fSleo 			file = optarg;
10793dc1f1fSleo 			fd = initialize(optarg, &is, &ib, &newis, &newib);
10893dc1f1fSleo 			did_reset = optreset = optind = 1;
10993dc1f1fSleo 			break;
1100a4d67ddScgd 		case 'H':		/* undocumented backward compat */
1110a4d67ddScgd 		case 'h':
1120a4d67ddScgd 			newis.height = xstrtol(optarg);
11328224014Schopps 			break;
1140a4d67ddScgd 		case 'i':
1150a4d67ddScgd 			iflag = 1;
1160a4d67ddScgd 			break;
11728224014Schopps 		case 'p':
1188a0b9bb0Schopps 			newib.pitch = xstrtol(optarg);
11928224014Schopps 			break;
12028224014Schopps 		case 't':
1218a0b9bb0Schopps 			newib.msec = xstrtol(optarg);
12228224014Schopps 			break;
1230a4d67ddScgd 		case 'V':		/* undocumented backward compat */
1240a4d67ddScgd 		case 'v':
1250a4d67ddScgd 			newib.volume = xstrtol(optarg);
1260a4d67ddScgd 			break;
1270a4d67ddScgd 		case 'W':		/* undocumented backward compat */
1280a4d67ddScgd 		case 'w':
1290a4d67ddScgd 			newis.width = xstrtol(optarg);
1300a4d67ddScgd 			break;
1310a4d67ddScgd 		case 'X':		/* undocumented backward compat */
1320a4d67ddScgd 		case 'x':
1330a4d67ddScgd 			newis.x = xstrtol(optarg);
1340a4d67ddScgd 			break;
1350a4d67ddScgd 		case 'Y':		/* undocumented backward compat */
1360a4d67ddScgd 		case 'y':
1370a4d67ddScgd 			newis.y = xstrtol(optarg);
1380a4d67ddScgd 			break;
13928224014Schopps 		case '?':
1400a4d67ddScgd 		default:
1410a4d67ddScgd 			usage();
14228224014Schopps 			/* NOTREACHED */
14328224014Schopps 		}
14428224014Schopps 	}
14528224014Schopps 	argc -= optind;
14628224014Schopps 	argv += optind;
14793dc1f1fSleo 	if(fd == -1)
14893dc1f1fSleo 		err(1, "open \"%s\"", file);
14928224014Schopps 
1500a4d67ddScgd 	if (memcmp(&newis, &is, sizeof(is))) {
1518a0b9bb0Schopps 		xioctl(fd, ITEIOCSWINSZ, &newis);
1528a0b9bb0Schopps 		xioctl(fd, ITEIOCGWINSZ, &is);
15328224014Schopps 	}
1540a4d67ddScgd 	if (memcmp(&newib, &ib, sizeof(ib))) {
1558a0b9bb0Schopps 		xioctl(fd, ITEIOCSBELL, &newib);
1568a0b9bb0Schopps 		xioctl(fd, ITEIOCGBELL, &ib);
15728224014Schopps 	}
15828224014Schopps 
15928224014Schopps 	/*
16028224014Schopps 	 * get, set and get colors again
16128224014Schopps 	 */
16228224014Schopps 	i = 0;
16328224014Schopps 	max_colors = 1 << is.depth;
16428224014Schopps 	cm = xgetcmap(fd, max_colors);
16528224014Schopps 	while (argc--) {
16628224014Schopps 		val = xstrtol(*argv++);
16728224014Schopps 		if (i >= max_colors) {
1680a4d67ddScgd 			warnx("warning: too many colors");
16928224014Schopps 			break;
17028224014Schopps 		}
17128224014Schopps 		cm->entry[i] = val;
17228224014Schopps 		i++;
17328224014Schopps 	}
1748a0b9bb0Schopps 	xioctl(fd, VIOCSCMAP, cm);
17528224014Schopps 	free(cm);
17628224014Schopps 	cm = xgetcmap(fd, max_colors);
17728224014Schopps 
17828224014Schopps 	/* do tty stuff to get it to register the changes. */
17928224014Schopps 	xioctl(fd, TIOCGWINSZ, &ws);
18028224014Schopps 
1810a4d67ddScgd 	if (iflag) {
18228224014Schopps 		printf("tty size: rows %d cols %d\n", ws.ws_row, ws.ws_col);
18328224014Schopps 		printf("ite size: w: %d  h: %d  d: %d  [x: %d  y: %d]\n",
18428224014Schopps 		    is.width, is.height, is.depth, is.x, is.y);
1858a0b9bb0Schopps 		printf("ite bell: vol: %d  millisec: %d  pitch: %d\n",
1868a0b9bb0Schopps 		    ib.volume, ib.msec, ib.pitch);
18728224014Schopps 		printcmap(cm, ws.ws_col);
18828224014Schopps 	}
18928224014Schopps 	close(fd);
19028224014Schopps 	exit(0);
19128224014Schopps }
19228224014Schopps 
19328224014Schopps void
xioctl(int fd,int cmd,void * addr)194*421949a3Ssevan xioctl(int fd, int cmd, void *addr)
19528224014Schopps {
1960a4d67ddScgd 	if (ioctl(fd, cmd, addr) == -1)
1970a4d67ddScgd 		err(1, "ioctl");
19828224014Schopps }
19928224014Schopps 
20028224014Schopps long
xstrtol(char * s)201*421949a3Ssevan xstrtol(char *s)
20228224014Schopps {
20328224014Schopps 	long rv;
20428224014Schopps 
205e7fa9814Slukem 	errno = 0;
20628224014Schopps 	rv = strtol(s, NULL, 0);
2070a4d67ddScgd 	if (errno == ERANGE && (rv == LONG_MIN || rv == LONG_MAX))
2080a4d67ddScgd 		err(1, "bad format: \"%s\"", s);
20928224014Schopps 	return(rv);
21028224014Schopps }
21128224014Schopps 
21228224014Schopps colormap_t *
xgetcmap(int fd,int ncolors)213*421949a3Ssevan xgetcmap(int fd, int ncolors)
21428224014Schopps {
21528224014Schopps 	colormap_t *cm;
21628224014Schopps 
21728224014Schopps 	cm = malloc(sizeof(colormap_t) + ncolors * sizeof(u_long));
2180a4d67ddScgd 	if (cm == NULL)
2190a4d67ddScgd 		err(1, "malloc");
22028224014Schopps 	cm->first = 0;
22128224014Schopps 	cm->size = ncolors;
22228224014Schopps 	cm->entry = (u_long *) & cm[1];
2238a0b9bb0Schopps 	xioctl(fd, VIOCGCMAP, cm);
22428224014Schopps 	return(cm);
22528224014Schopps }
22628224014Schopps 
22728224014Schopps void
printcmap(colormap_t * cm,int ncols)228*421949a3Ssevan printcmap(colormap_t *cm, int ncols)
22928224014Schopps {
23028224014Schopps 	int i, nel;
23128224014Schopps 
23228224014Schopps 	switch (cm->type) {
23328224014Schopps 	case CM_MONO:
2340a4d67ddScgd 		printf("monochrome");
23528224014Schopps 		return;
23628224014Schopps 	case CM_COLOR:
2370a4d67ddScgd 		printf("color levels: red: %d  green: %d  blue: %d",
23828224014Schopps 		    cm->red_mask + 1, cm->green_mask + 1, cm->blue_mask + 1);
23928224014Schopps 		break;
24028224014Schopps 	case CM_GREYSCALE:
2410a4d67ddScgd 		printf("greyscale levels: %d", cm->grey_mask + 1);
24228224014Schopps 		break;
24328224014Schopps 	}
2440a4d67ddScgd 	printf("\n");
24528224014Schopps 
24628224014Schopps 	nel = ncols / 11 - 1;
24728224014Schopps 	for (i = 0; i < cm->size; i++) {
24828224014Schopps 		printf("0x%08lx ", cm->entry[i]);
24928224014Schopps 		if ((i + 1) % nel == 0)
25028224014Schopps 			printf("\n");
25128224014Schopps 	}
25228224014Schopps 	if ((i + 1) % nel)
25328224014Schopps 		printf("\n");
25428224014Schopps }
25528224014Schopps 
25693dc1f1fSleo int
initialize(file,is,ib,newis,newib)25793dc1f1fSleo initialize(file, is, ib, newis, newib)
258094ee530Smlelstv 	const char	*file;
25993dc1f1fSleo 	struct itewinsize *is, *newis;
26093dc1f1fSleo 	struct itebell *ib, *newib;
26193dc1f1fSleo {
26293dc1f1fSleo 	int fd;
26393dc1f1fSleo 
26493dc1f1fSleo 	fd = open(file, O_RDONLY | O_NONBLOCK);
26593dc1f1fSleo 	if (fd == -1)
26693dc1f1fSleo 		return(-1);
26793dc1f1fSleo 
26893dc1f1fSleo 	xioctl(fd, ITEIOCGWINSZ, is);
26993dc1f1fSleo 	xioctl(fd, ITEIOCGBELL, ib);
27093dc1f1fSleo 
27193dc1f1fSleo 	memcpy(newis, is, sizeof(*is));
27293dc1f1fSleo 	memcpy(newib, ib, sizeof(*ib));
27393dc1f1fSleo 	return(fd);
27493dc1f1fSleo }
27593dc1f1fSleo 
276*421949a3Ssevan static void
usage(void)277*421949a3Ssevan usage(void)
27828224014Schopps {
279565cd653Sis 	fprintf(stderr, "%s\n\t\t%s\n\t\t%s\n",
280565cd653Sis 	    "usage: iteconfig [-i] [-f file] [-v volume] [-p pitch] [-t msec]",
281565cd653Sis 	    "[-w width] [-h height] [-d depth] [-x off] [-y off]",
282565cd653Sis 	    "[color ...]");
28328224014Schopps 	exit(1);
28428224014Schopps }
285