1 /* $NetBSD: bellctrl.c,v 1.12 2011/05/19 21:26:39 tsutsui 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.12 2011/05/19 21:26:39 tsutsui 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