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