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