X-Git-Url: https://git.deb.at/w?p=pkg%2Fbeep.git;a=blobdiff_plain;f=beep.c;h=452fc08376393f6cde807911fea3fc37e61c9f9c;hp=f80eb7648c9b6fee6c2d76b59635b49a2f541310;hb=HEAD;hpb=0b72fe17e679c0b3c88448cc2fc6830d3db20f93 diff --git a/beep.c b/beep.c index f80eb76..452fc08 100644 --- a/beep.c +++ b/beep.c @@ -26,6 +26,7 @@ #include #include #include +#include /* I don't know where this number comes from, I admit that freely. A wonderful human named Raine M. Ekman used it in a program that played @@ -47,7 +48,7 @@ #define CLOCK_TICK_RATE 1193180 #endif -#define VERSION_STRING "beep-1.2.2" +#define VERSION_STRING "beep-1.3" char *copyright = "Copyright (C) Johnathan Nightingale, 2002. " "Use and Distribution subject to GPL. " @@ -83,21 +84,52 @@ typedef struct beep_parms_t { so that beep can be tucked appropriately into a text- processing pipe. */ + int verbose; /* verbose output? */ struct beep_parms_t *next; /* in case -n/--new is used. */ } beep_parms_t; +enum { BEEP_TYPE_CONSOLE, BEEP_TYPE_EVDEV }; + /* Momma taught me never to use globals, but we need something the signal handlers can get at.*/ int console_fd = -1; +int console_type = BEEP_TYPE_CONSOLE; +char *console_device = NULL; + + +void do_beep(int freq) { + if (console_type == BEEP_TYPE_CONSOLE) { + if(ioctl(console_fd, KIOCSOUND, freq != 0 + ? (int)(CLOCK_TICK_RATE/freq) + : freq) < 0) { + printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ + perror("ioctl"); + } + } else { + /* BEEP_TYPE_EVDEV */ + struct input_event e; + + e.type = EV_SND; + e.code = SND_TONE; + e.value = freq; + + write(console_fd, &e, sizeof(struct input_event)); + } +} + /* If we get interrupted, it would be nice to not leave the speaker beeping in perpetuity. */ void handle_signal(int signum) { + + if(console_device) + free(console_device); + switch(signum) { case SIGINT: if(console_fd >= 0) { /* Kill the sound, quit gracefully */ - ioctl(console_fd, KIOCSOUND, 0); + do_beep(0); close(console_fd); exit(signum); } else { @@ -110,7 +142,7 @@ void handle_signal(int signum) { /* print usage and exit */ void usage_bail(const char *executable_name) { printf("Usage:\n%s [-f freq] [-l length] [-r reps] [-d delay] " - "[-D delay] [-s] [-c]\n", + "[-D delay] [-s] [-c] [--verbose | --debug] [-e device]\n", executable_name); printf("%s [Options...] [-n] [--new] [Options...] ... \n", executable_name); printf("%s [-h] [--help]\n", executable_name); @@ -131,6 +163,7 @@ void usage_bail(const char *executable_name) { * "-D " (similar to -d, but delay after last repetition as well) * "-s" (beep after each line of input from stdin, echo line to stdout) * "-c" (beep after each char of input from stdin, echo char to stdout) + * "--verbose/--debug" * "-h/--help" * "-v/-V/--version" * "-n/--new" @@ -141,11 +174,14 @@ void usage_bail(const char *executable_name) { void parse_command_line(int argc, char **argv, beep_parms_t *result) { int c; - struct option opt_list[4] = {{"help", 0, NULL, 'h'}, + struct option opt_list[7] = {{"help", 0, NULL, 'h'}, {"version", 0, NULL, 'V'}, {"new", 0, NULL, 'n'}, + {"verbose", 0, NULL, 'X'}, + {"debug", 0, NULL, 'X'}, + {"device", 1, NULL, 'e'}, {0,0,0,0}}; - while((c = getopt_long(argc, argv, "f:l:r:d:D:schvVn", opt_list, NULL)) + while((c = getopt_long(argc, argv, "f:l:r:d:D:schvVne:", opt_list, NULL)) != EOF) { int argval = -1; /* handle parsed numbers for various arguments */ float argfreq = -1; @@ -155,6 +191,9 @@ void parse_command_line(int argc, char **argv, beep_parms_t *result) { (argfreq <= 0)) usage_bail(argv[0]); else + if (result->freq != 0) + fprintf(stderr, "WARNING: multiple -f values given, only last " + "one is used.\n"); result->freq = argfreq; break; case 'l' : /* length */ @@ -197,45 +236,68 @@ void parse_command_line(int argc, char **argv, beep_parms_t *result) { exit(0); break; case 'n' : /* also --new - create another beep */ + if (result->freq == 0) + result->freq = DEFAULT_FREQ; result->next = (beep_parms_t *)malloc(sizeof(beep_parms_t)); - result->next->freq = DEFAULT_FREQ; + result->next->freq = 0; result->next->length = DEFAULT_LENGTH; result->next->reps = DEFAULT_REPS; result->next->delay = DEFAULT_DELAY; result->next->end_delay = DEFAULT_END_DELAY; result->next->stdin_beep = DEFAULT_STDIN_BEEP; + result->next->verbose = result->verbose; result->next->next = NULL; result = result->next; /* yes, I meant to do that. */ break; + case 'X' : /* --debug / --verbose */ + result->verbose = 1; + break; + case 'e' : /* also --device */ + console_device = strdup(optarg); + break; case 'h' : /* notice that this is also --help */ default : usage_bail(argv[0]); } } + if (result->freq == 0) + result->freq = DEFAULT_FREQ; } void play_beep(beep_parms_t parms) { int i; /* loop counter */ + if(parms.verbose == 1) + fprintf(stderr, "[DEBUG] %d times %d ms beeps (%d delay between, " + "%d delay after) @ %.2f Hz\n", + parms.reps, parms.length, parms.delay, parms.end_delay, parms.freq); + /* try to snag the console */ - if((console_fd = open("/dev/tty0", O_WRONLY)) == -1) { - if((console_fd = open("/dev/vc/0", O_WRONLY)) == -1) { - fprintf(stderr, "Could not open /dev/tty0 or /dev/vc/0 for writing.\n"); - printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ - perror("open"); - exit(1); - } + if(console_device) + console_fd = open(console_device, O_WRONLY); + else + if((console_fd = open("/dev/tty0", O_WRONLY)) == -1) + console_fd = open("/dev/vc/0", O_WRONLY); + + if(console_fd == -1) { + fprintf(stderr, "Could not open %s for writing\n", + console_device != NULL ? console_device : "/dev/tty0 or /dev/vc/0"); + printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ + perror("open"); + exit(1); } + + if (ioctl(console_fd, EVIOCGSND(0)) != -1) + console_type = BEEP_TYPE_EVDEV; + else + console_type = BEEP_TYPE_CONSOLE; /* Beep */ for (i = 0; i < parms.reps; i++) { /* start beep */ - if(ioctl(console_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/parms.freq)) < 0) { - printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ - perror("ioctl"); - } + do_beep(parms.freq); /* Look ma, I'm not ansi C compatible! */ usleep(1000*parms.length); /* wait... */ - ioctl(console_fd, KIOCSOUND, 0); /* stop beep */ + do_beep(0); /* stop beep */ if(parms.end_delay || (i+1 < parms.reps)) usleep(1000*parms.delay); /* wait... */ } /* repeat. */ @@ -249,12 +311,13 @@ int main(int argc, char **argv) { char sin[4096], *ptr; beep_parms_t *parms = (beep_parms_t *)malloc(sizeof(beep_parms_t)); - parms->freq = DEFAULT_FREQ; + parms->freq = 0; parms->length = DEFAULT_LENGTH; parms->reps = DEFAULT_REPS; parms->delay = DEFAULT_DELAY; parms->end_delay = DEFAULT_END_DELAY; parms->stdin_beep = DEFAULT_STDIN_BEEP; + parms->verbose = 0; parms->next = NULL; signal(SIGINT, handle_signal); @@ -297,5 +360,8 @@ int main(int argc, char **argv) { parms = next; } + if(console_device) + free(console_device); + return EXIT_SUCCESS; }