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