1 /* $NetBSD: bellctrl.c,v 1.13 2011/08/25 17:00:55 christos 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.13 2011/08/25 17:00:55 christos 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 static int bell_setting; 29 static 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 static int is_number(const char *, int); 39 static void set_bell_vol(int); 40 static void set_bell_pitch(int); 41 static void set_bell_dur(int); 42 static void set_voice_param(const char *, int); 43 static void set_bell_param(void); 44 static void usage(void) __dead; 45 46 int 47 main(int argc, char **argv) 48 { 49 const char *arg; 50 int percent; 51 int i; 52 53 bell_setting = 0; 54 55 if (argc < 2) 56 usage(); 57 58 for (i = 1; i < argc; ) { 59 arg = argv[i++]; 60 if (strcmp(arg, "-b") == 0) { 61 /* turn off bell */ 62 set_bell_vol(0); 63 } else if (strcmp(arg, "b") == 0) { 64 /* set bell to default */ 65 percent = DEFAULT; 66 67 if (i >= argc) { 68 /* set bell to default */ 69 set_bell_vol(percent); 70 /* set pitch to default */ 71 set_bell_pitch(percent); 72 /* set duration to default */ 73 set_bell_dur(percent); 74 break; 75 } 76 arg = nextarg(i, argv); 77 if (strcmp(arg, "on") == 0) { 78 /* 79 * let it stay that way 80 */ 81 /* set bell on */ 82 set_bell_vol(BELL_VOLUME); 83 /* set pitch to default */ 84 set_bell_pitch(BELL_PITCH); 85 /* set duration to default */ 86 set_bell_dur(BELL_DURATION); 87 i++; 88 } else if (strcmp(arg, "off") == 0) { 89 /* turn the bell off */ 90 percent = 0; 91 set_bell_vol(percent); 92 i++; 93 } else if (is_number(arg, MAXBVOLUME)) { 94 /* 95 * If volume is given 96 */ 97 /* set bell appropriately */ 98 percent = atoi(arg); 99 100 set_bell_vol(percent); 101 i++; 102 103 arg = nextarg(i, argv); 104 105 /* if pitch is given */ 106 if (is_number(arg, MAXBPITCH)) { 107 /* set the bell */ 108 set_bell_pitch(atoi(arg)); 109 i++; 110 111 arg = nextarg(i, argv); 112 /* If duration is given */ 113 if (is_number(arg, MAXBTIME)) { 114 /* set the bell */ 115 set_bell_dur(atoi(arg)); 116 i++; 117 } 118 } 119 } else { 120 /* set bell to default */ 121 set_bell_vol(BELL_VOLUME); 122 } 123 } else if (strcmp(arg, "v") == 0) { 124 /* 125 * set voice parameter 126 */ 127 if (i >= argc) { 128 arg = "default"; 129 } else { 130 arg = nextarg(i, argv); 131 } 132 set_voice_param(arg, 1); 133 i++; 134 } else if (strcmp(arg, "-v") == 0) { 135 /* 136 * set voice parameter 137 */ 138 if (i >= argc) { 139 warnx("Missing -v argument"); 140 usage(); 141 } 142 arg = nextarg(i, argv); 143 set_voice_param(arg, 0); 144 i++; 145 } else { 146 warnx("Unknown option %s", arg); 147 usage(); 148 } 149 } 150 151 if (bell_setting) 152 set_bell_param(); 153 154 exit(0); 155 } 156 157 static int 158 is_number(const char *arg, int maximum) 159 { 160 const char *p; 161 162 if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0') 163 return 1; 164 for (p = arg; isdigit((unsigned char)*p); p++) 165 ; 166 if (*p || atoi(arg) > maximum) 167 return 0; 168 169 return 1; 170 } 171 172 static void 173 set_bell_vol(int percent) 174 { 175 values.volume = percent; 176 bell_setting++; 177 } 178 179 static void 180 set_bell_pitch(int pitch) 181 { 182 values.pitch = pitch; 183 bell_setting++; 184 } 185 186 static void 187 set_bell_dur(int duration) 188 { 189 values.msec = duration; 190 bell_setting++; 191 } 192 193 static void 194 set_voice_param(const char *path, int flag) 195 { 196 int fd; 197 198 if (flag) { 199 memcpy(&voice, &bell_voice, sizeof(bell_voice)); 200 } else { 201 if ((fd = open(path, 0)) >= 0) { 202 if (read(fd, &voice, sizeof(voice)) != sizeof(voice)) 203 err(1, "cannot read voice parameter"); 204 close(fd); 205 } else { 206 err(1, "cannot open voice parameter"); 207 } 208 } 209 210 if ((fd = open("/dev/bell", O_RDWR)) < 0) 211 err(1, "cannot open /dev/bell"); 212 if (ioctl(fd, BELLIOCSVOICE, &voice)) 213 err(1, "ioctl BELLIOCSVOICE failed"); 214 215 close(fd); 216 } 217 218 static void 219 set_bell_param(void) 220 { 221 int fd; 222 struct bell_info param; 223 224 if ((fd = open("/dev/bell", O_RDWR)) < 0) 225 err(1, "cannot open /dev/bell"); 226 if (ioctl(fd, BELLIOCGPARAM, ¶m)) 227 err(1, "ioctl BELLIOCGPARAM failed"); 228 229 if (values.volume == DEFAULT) 230 values.volume = param.volume; 231 if (values.pitch == DEFAULT) 232 values.pitch = param.pitch; 233 if (values.msec == DEFAULT) 234 values.msec = param.msec; 235 236 if (ioctl(fd, BELLIOCSPARAM, &values)) 237 err(1, "ioctl BELLIOCSPARAM failed"); 238 239 close(fd); 240 } 241 242 static void 243 usage(void) 244 { 245 fprintf(stderr, "Usage: %s option ...\n", getprogname()); 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