bellctrl.c revision 1.7 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, ¶m))
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