bellctrl.c revision 1.5 1 /* $NetBSD: bellctrl.c,v 1.5 2003/05/17 09:43:58 isaki Exp $ */
2
3 /*
4 * bellctrl - OPM bell controller (for NetBSD/X680x0)
5 * Copyright (c)1995 ussy.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <ctype.h>
11 #include <sys/file.h>
12 #include <sys/ioctl.h>
13 #include "../../include/opmbellio.h"
14 #include "../../dev/opmbellvar.h"
15 #include "../../dev/opmreg.h"
16
17 #define DEFAULT -1
18
19 #define nextarg(i, argv) \
20 argv[i]; \
21 if (i >= argc) \
22 break; \
23
24 int bell_setting;
25 char *progName;
26 struct opm_voice voice;
27
28 static struct bell_info values = {
29 DEFAULT, DEFAULT, DEFAULT
30 };
31
32 /* function prototype */
33 int is_number();
34 void set_bell_vol();
35 void set_bell_pitch();
36 void set_bell_dur();
37 void set_voice_param();
38 void set_bell_param();
39 int usage();
40 int error();
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 }
138 arg = nextarg(i, argv);
139 set_voice_param(arg, 0);
140 i++;
141 } else {
142 usage("unknown option %s", arg);
143 }
144 }
145
146 if (bell_setting)
147 set_bell_param();
148
149 exit(0);
150 }
151
152 int
153 is_number(char *arg, int maximum)
154 {
155 register char *p;
156
157 if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0')
158 return 1;
159 for (p = arg; isdigit((unsigned char)*p); p++)
160 ;
161 if (*p || atoi(arg) > maximum)
162 return 0;
163
164 return 1;
165 }
166
167 void
168 set_bell_vol(int percent)
169 {
170 values.volume = percent;
171 bell_setting++;
172 }
173
174 void
175 set_bell_pitch(int pitch)
176 {
177 values.pitch = pitch;
178 bell_setting++;
179 }
180
181 void
182 set_bell_dur(int duration)
183 {
184 values.msec = duration;
185 bell_setting++;
186 }
187
188 void
189 set_voice_param(char *path, int flag)
190 {
191 int fd;
192
193 if (flag) {
194 memcpy(&voice, &bell_voice, sizeof(bell_voice));
195 } else {
196 if ((fd = open(path, 0)) >= 0) {
197 if (read(fd, &voice, sizeof(voice)) != sizeof(voice))
198 error("cannot read voice parameter.");
199 close(fd);
200 } else {
201 error("cannot open voice parameter.");
202 }
203 }
204
205 if ((fd = open("/dev/bell", O_RDWR)) < 0)
206 error("cannot open /dev/bell");
207 if (ioctl(fd, BELLIOCSVOICE, &voice))
208 error("ioctl BELLIOCSVOICE failed");
209
210 close(fd);
211 }
212
213 void
214 set_bell_param(void)
215 {
216 int fd;
217 struct bell_info param;
218
219 if ((fd = open("/dev/bell", O_RDWR)) < 0)
220 error("cannot open /dev/bell");
221 if (ioctl(fd, BELLIOCGPARAM, ¶m))
222 error("ioctl BELLIOCGPARAM failed.");
223
224 if (values.volume == DEFAULT)
225 values.volume = param.volume;
226 if (values.pitch == DEFAULT)
227 values.pitch = param.pitch;
228 if (values.msec == DEFAULT)
229 values.msec = param.msec;
230
231 if (ioctl(fd, BELLIOCSPARAM, &values))
232 error("ioctl BELLIOCSPARAM failed.");
233
234 close(fd);
235 }
236
237 int
238 usage(char *fmt, char *arg)
239 {
240 if (fmt) {
241 fprintf (stderr, "%s: ", progName);
242 fprintf (stderr, fmt, arg);
243 fprintf (stderr, "\n\n");
244 }
245
246 fprintf(stderr, "usage: %s option ...\n", progName);
247 fprintf(stderr, " To turn bell off:\n");
248 fprintf(stderr, "\t-b b off"
249 " b 0\n");
250 fprintf(stderr, " To set bell volume, pitch and duration:\n");
251 fprintf(stderr, "\t b [vol [pitch [dur]]] b on\n");
252 fprintf(stderr, " To restore default voice parameter:\n");
253 fprintf(stderr, "\t v default\n");
254 fprintf(stderr, " To set voice parameter:\n");
255 fprintf(stderr, "\t-v voicefile\n");
256 exit(0);
257 }
258
259 int
260 error(char *message)
261 {
262 fprintf(stderr, "%s: %s\n", progName, message);
263 exit(1);
264 }
265