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