1/*	$NetBSD: videomode.c,v 1.7 2009/01/17 22:01:32 he Exp $	*/
2
3/*
4 * Copyright (c) 1995 Christian E. Hopps
5 * Copyright (c) 1994 Markus Wild
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *      This product includes software developed by Markus Wild
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/ioctl.h>
37#include <sys/device.h>
38#include <amiga/dev/grfioctl.h>
39#include <amiga/dev/grfvar.h>
40
41#include <err.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <unistd.h>
47
48void	dump_mode __P((int));
49void	dump_vm   __P((struct grfvideo_mode *));
50int	get_grf __P((void));
51int	main __P((int, char **));
52void	set_mode __P((int));
53void	usage __P((void));
54
55int
56main(argc, argv)
57	int argc;
58	char *argv[];
59{
60	int m;
61	int c;
62
63	if (argc == 1) {
64		dump_mode(0);
65		return (0);
66	}
67	while ((c = getopt(argc, argv, "as:")) != -1) {
68		switch (c) {
69		case 'a':
70			if (optind < argc)
71				usage();
72			dump_mode(-1);
73			return (0);
74		case 's':
75			m = atoi(optarg);
76			if (m == 0 || optind < argc)
77				usage();
78			set_mode(m);
79			return (0);
80		}
81	}
82
83	argc -= optind;
84	argv += optind;
85	if (argc != 1)
86		usage();
87
88	dump_mode(atoi(*argv));
89	return (0);
90}
91
92
93int
94get_grf()
95{
96	struct stat stb;
97	char grfname[80];
98	int grffd;
99
100	/* find out on which ite/grf we are */
101	if (fstat(0, &stb) == -1)
102		err(1, "fstat 0");
103	if (!S_ISCHR(stb.st_mode) || !isatty(0))
104		errx(1, "stdin not a tty");
105	if (major(stb.st_rdev) != 13)
106		errx(1, "stdin not an ite device");
107	(void)snprintf(grfname, sizeof(grfname), "/dev/grf%u",
108	    (u_int)minor(stb.st_rdev) & 0x7);
109	if ((grffd = open(grfname, 2)) < 0)
110		err(1, "%s", grfname);
111	return (grffd);
112}
113
114void
115dump_mode(m)
116	int m;
117{
118	struct grfvideo_mode vm;
119	int num_vm;
120	int grffd;
121
122	grffd = get_grf();
123
124	if (ioctl(grffd, GRFGETNUMVM, &num_vm) < 0)
125		err(1, "GRFGETNUMVM");
126	if (m > 0 && m > num_vm)
127		errx(1, "no such mode");
128	if (m <= 0) {
129		(void)printf("Current mode:\n");
130		vm.mode_num = 0;
131		if (ioctl(grffd, GRFGETVMODE, &vm) == 0)
132			dump_vm(&vm);
133		(void)printf("\n");
134	}
135	if (m >= 0) {
136		(void)close(grffd);
137		return;
138	}
139	for (m = 1; m <= num_vm; m++) {
140		vm.mode_num = m;
141		if (ioctl(grffd, GRFGETVMODE, &vm) == -1)
142			break;
143		dump_vm(&vm);
144	}
145	(void)close(grffd);
146}
147
148void
149set_mode(m)
150	int m;
151{
152	int grffd;
153
154	grffd = get_grf();
155	(void)ioctl(grffd, GRFSETVMODE, &m);
156	(void)close(grffd);
157}
158
159void
160dump_vm(vm)
161	struct grfvideo_mode *vm;
162{
163	(void)printf("%d: %s\n", vm->mode_num, vm->mode_descr);
164	(void)printf(
165	    "pixel_clock = %lu, width = %d, height = %d, depth = %d\n",
166	    vm->pixel_clock, vm->disp_width, vm->disp_height, vm->depth);
167}
168
169void
170usage()
171{
172	(void)fprintf(stderr, "usage: videomode [mode]\n");
173	(void)fprintf(stderr, "usage: videomode -a\n");
174	(void)fprintf(stderr, "usage: videomode -s mode\n");
175	exit(0);
176}
177