xref: /netbsd-src/sys/arch/x68k/usr.bin/bellctrl/bellctrl.c (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
1 /*	$NetBSD: bellctrl.c,v 1.12 2011/05/19 21:26:39 tsutsui Exp $	*/
2 
3 /*
4  * bellctrl - OPM bell controller (for NetBSD/X680x0)
5  * Copyright (c)1995 ussy.
6  */
7 
8 #include <sys/cdefs.h>
9 __RCSID("$NetBSD: bellctrl.c,v 1.12 2011/05/19 21:26:39 tsutsui Exp $");
10 
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <ctype.h>
16 #include <string.h>
17 #include <sys/file.h>
18 #include <sys/ioctl.h>
19 #include <machine/opmbellio.h>
20 
21 #define DEFAULT -1
22 
23 #define nextarg(i, argv) \
24 	argv[i]; \
25 	if (i >= argc) \
26 		break; \
27 
28 int bell_setting;
29 char *progName;
30 struct opm_voice voice;
31 
32 static struct opm_voice bell_voice = DEFAULT_BELL_VOICE;
33 
34 static struct bell_info values = {
35 	DEFAULT, DEFAULT, DEFAULT
36 };
37 
38 /* function prototype */
39 int is_number(const char *, int);
40 void set_bell_vol(int);
41 void set_bell_pitch(int);
42 void set_bell_dur(int);
43 void set_voice_param(const char *, int);
44 void set_bell_param(void);
45 int usage(const char *, const char *);
46 
47 int
48 main(int argc, char **argv)
49 {
50 	const char *arg;
51 	int percent;
52 	int i;
53 
54 	progName = argv[0];
55 	bell_setting = 0;
56 
57 	if (argc < 2)
58 		usage(NULL, NULL);
59 
60 	for (i = 1; i < argc; ) {
61 		arg = argv[i++];
62 		if (strcmp(arg, "-b") == 0) {
63 			/* turn off bell */
64 			set_bell_vol(0);
65 		} else if (strcmp(arg, "b") == 0) {
66 			/* set bell to default */
67 			percent = DEFAULT;
68 
69 			if (i >= argc) {
70 				/* set bell to default */
71 				set_bell_vol(percent);
72 				/* set pitch to default */
73 				set_bell_pitch(percent);
74 				/* set duration to default */
75 				set_bell_dur(percent);
76 				break;
77 			}
78 			arg = nextarg(i, argv);
79 			if (strcmp(arg, "on") == 0) {
80 				/*
81 				 * let it stay that way
82 				 */
83 				/* set bell on */
84 				set_bell_vol(BELL_VOLUME);
85 				/* set pitch to default */
86 				set_bell_pitch(BELL_PITCH);
87 				/* set duration to default */
88 				set_bell_dur(BELL_DURATION);
89 				i++;
90 			} else if (strcmp(arg, "off") == 0) {
91 				/* turn the bell off */
92 				percent = 0;
93 				set_bell_vol(percent);
94 				i++;
95 			} else if (is_number(arg, MAXBVOLUME)) {
96 				/*
97 				 * If volume is given
98 				 */
99 				/* set bell appropriately */
100 				percent = atoi(arg);
101 
102 				set_bell_vol(percent);
103 				i++;
104 
105 				arg = nextarg(i, argv);
106 
107 				/* if pitch is given */
108 				if (is_number(arg, MAXBPITCH)) {
109 					/* set the bell */
110 					set_bell_pitch(atoi(arg));
111 					i++;
112 
113 					arg = nextarg(i, argv);
114 					/* If duration is given	*/
115 					if (is_number(arg, MAXBTIME)) {
116 						/* set the bell */
117 						set_bell_dur(atoi(arg));
118 						i++;
119 					}
120 				}
121 			} else {
122 				/* set bell to default */
123 				set_bell_vol(BELL_VOLUME);
124 			}
125 		} else if (strcmp(arg, "v") == 0) {
126 			/*
127 			 * set voice parameter
128 			 */
129 			if (i >= argc) {
130 				arg = "default";
131 			} else {
132 				arg = nextarg(i, argv);
133 			}
134 			set_voice_param(arg, 1);
135 			i++;
136 		} else if (strcmp(arg, "-v") == 0) {
137 			/*
138 			 * set voice parameter
139 			 */
140 			if (i >= argc)
141 				usage("missing -v argument", NULL);
142 			arg = nextarg(i, argv);
143 			set_voice_param(arg, 0);
144 			i++;
145 		} else {
146 			usage("unknown option %s", arg);
147 		}
148 	}
149 
150 	if (bell_setting)
151 		set_bell_param();
152 
153 	exit(0);
154 }
155 
156 int
157 is_number(const char *arg, int maximum)
158 {
159 	const char *p;
160 
161 	if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0')
162 		return 1;
163 	for (p = arg; isdigit((unsigned char)*p); p++)
164 		;
165 	if (*p || atoi(arg) > maximum)
166 		return 0;
167 
168 	return 1;
169 }
170 
171 void
172 set_bell_vol(int percent)
173 {
174 	values.volume = percent;
175 	bell_setting++;
176 }
177 
178 void
179 set_bell_pitch(int pitch)
180 {
181 	values.pitch = pitch;
182 	bell_setting++;
183 }
184 
185 void
186 set_bell_dur(int duration)
187 {
188 	values.msec = duration;
189 	bell_setting++;
190 }
191 
192 void
193 set_voice_param(const char *path, int flag)
194 {
195 	int fd;
196 
197 	if (flag) {
198 		memcpy(&voice, &bell_voice, sizeof(bell_voice));
199 	} else {
200 		if ((fd = open(path, 0)) >= 0) {
201 			if (read(fd, &voice, sizeof(voice)) != sizeof(voice))
202 				err(1, "cannot read voice parameter");
203 			close(fd);
204 		} else {
205 			err(1, "cannot open voice parameter");
206 		}
207 	}
208 
209 	if ((fd = open("/dev/bell", O_RDWR)) < 0)
210 		err(1, "cannot open /dev/bell");
211 	if (ioctl(fd, BELLIOCSVOICE, &voice))
212 		err(1, "ioctl BELLIOCSVOICE failed");
213 
214 	close(fd);
215 }
216 
217 void
218 set_bell_param(void)
219 {
220 	int fd;
221 	struct bell_info param;
222 
223 	if ((fd = open("/dev/bell", O_RDWR)) < 0)
224 		err(1, "cannot open /dev/bell");
225 	if (ioctl(fd, BELLIOCGPARAM, &param))
226 		err(1, "ioctl BELLIOCGPARAM failed");
227 
228 	if (values.volume == DEFAULT)
229 		values.volume = param.volume;
230 	if (values.pitch == DEFAULT)
231 		values.pitch = param.pitch;
232 	if (values.msec == DEFAULT)
233 		values.msec = param.msec;
234 
235 	if (ioctl(fd, BELLIOCSPARAM, &values))
236 		err(1, "ioctl BELLIOCSPARAM failed");
237 
238 	close(fd);
239 }
240 
241 int
242 usage(const char *fmt, const char *arg)
243 {
244 	if (fmt) {
245 		fprintf(stderr, "%s:  ", progName);
246 		fprintf(stderr, fmt, arg);
247 		fprintf(stderr, "\n\n");
248 	}
249 
250 	fprintf(stderr, "usage:  %s option ...\n", progName);
251 	fprintf(stderr, "	To turn bell off:\n");
252 	fprintf(stderr, "\t-b				b off"
253 	                "			   b 0\n");
254 	fprintf(stderr, "	To set bell volume, pitch and duration:\n");
255 	fprintf(stderr, "\t b [vol [pitch [dur]]]		  b on\n");
256 	fprintf(stderr, "	To restore default voice parameter:\n");
257 	fprintf(stderr, "\t v default\n");
258 	fprintf(stderr, "	To set voice parameter:\n");
259 	fprintf(stderr, "\t-v voicefile\n");
260 	exit(0);
261 }
262