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