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