bellctrl.c revision 1.11.84.1 1 /* $NetBSD: bellctrl.c,v 1.11.84.1 2011/05/31 03:04:22 rmind 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.84.1 2011/05/31 03:04:22 rmind 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, ¶m))
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