Andrew Geissler | 8fc454f | 2020-12-11 16:27:59 -0600 | [diff] [blame] | 1 | # the diff between Alessandro Zummo's copy of beep.c and the original |
| 2 | # one... |
| 3 | |
| 4 | --- beep-1.2.2/beep.c.orig 2006-01-29 12:13:36.994560551 -0800 |
| 5 | +++ beep-1.2.2/beep.c 2006-01-29 12:35:02.950558713 -0800 |
| 6 | @@ -26,6 +26,7 @@ |
| 7 | #include <sys/ioctl.h> |
| 8 | #include <sys/types.h> |
| 9 | #include <linux/kd.h> |
| 10 | +#include <linux/input.h> |
| 11 | |
| 12 | /* I don't know where this number comes from, I admit that freely. A |
| 13 | wonderful human named Raine M. Ekman used it in a program that played |
| 14 | @@ -86,18 +87,28 @@ typedef struct beep_parms_t { |
| 15 | struct beep_parms_t *next; /* in case -n/--new is used. */ |
| 16 | } beep_parms_t; |
| 17 | |
| 18 | +enum { BEEP_TYPE_CONSOLE, BEEP_TYPE_EVDEV }; |
| 19 | + |
| 20 | /* Momma taught me never to use globals, but we need something the signal |
| 21 | handlers can get at.*/ |
| 22 | int console_fd = -1; |
| 23 | +int console_type = BEEP_TYPE_CONSOLE; |
| 24 | +char *console_device = NULL; |
| 25 | + |
| 26 | +void do_beep(int freq); |
| 27 | |
| 28 | /* If we get interrupted, it would be nice to not leave the speaker beeping in |
| 29 | perpetuity. */ |
| 30 | void handle_signal(int signum) { |
| 31 | + |
| 32 | + if(console_device) |
| 33 | + free(console_device); |
| 34 | + |
| 35 | switch(signum) { |
| 36 | case SIGINT: |
| 37 | if(console_fd >= 0) { |
| 38 | /* Kill the sound, quit gracefully */ |
| 39 | - ioctl(console_fd, KIOCSOUND, 0); |
| 40 | + do_beep(0); |
| 41 | close(console_fd); |
| 42 | exit(signum); |
| 43 | } else { |
| 44 | @@ -110,7 +121,7 @@ void handle_signal(int signum) { |
| 45 | /* print usage and exit */ |
| 46 | void usage_bail(const char *executable_name) { |
| 47 | printf("Usage:\n%s [-f freq] [-l length] [-r reps] [-d delay] " |
| 48 | - "[-D delay] [-s] [-c]\n", |
| 49 | + "[-D delay] [-s] [-c] [-e device]\n", |
| 50 | executable_name); |
| 51 | printf("%s [Options...] [-n] [--new] [Options...] ... \n", executable_name); |
| 52 | printf("%s [-h] [--help]\n", executable_name); |
| 53 | @@ -141,11 +152,12 @@ void usage_bail(const char *executable_n |
| 54 | void parse_command_line(int argc, char **argv, beep_parms_t *result) { |
| 55 | int c; |
| 56 | |
| 57 | - struct option opt_list[4] = {{"help", 0, NULL, 'h'}, |
| 58 | + struct option opt_list[] = {{"help", 0, NULL, 'h'}, |
| 59 | {"version", 0, NULL, 'V'}, |
| 60 | {"new", 0, NULL, 'n'}, |
| 61 | + {"device", 1, NULL, 'e'}, |
| 62 | {0,0,0,0}}; |
| 63 | - while((c = getopt_long(argc, argv, "f:l:r:d:D:schvVn", opt_list, NULL)) |
| 64 | + while((c = getopt_long(argc, argv, "f:l:r:d:D:schvVne:", opt_list, NULL)) |
| 65 | != EOF) { |
| 66 | int argval = -1; /* handle parsed numbers for various arguments */ |
| 67 | float argfreq = -1; |
| 68 | @@ -207,6 +219,9 @@ void parse_command_line(int argc, char * |
| 69 | result->next->next = NULL; |
| 70 | result = result->next; /* yes, I meant to do that. */ |
| 71 | break; |
| 72 | + case 'e' : /* also --device */ |
| 73 | + console_device = strdup(optarg); |
| 74 | + break; |
| 75 | case 'h' : /* notice that this is also --help */ |
| 76 | default : |
| 77 | usage_bail(argv[0]); |
| 78 | @@ -214,26 +229,61 @@ void parse_command_line(int argc, char * |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | +void do_beep(int freq) |
| 83 | +{ |
| 84 | + if (console_type == BEEP_TYPE_CONSOLE) |
| 85 | + { |
| 86 | + if(ioctl(console_fd, KIOCSOUND, freq != 0 |
| 87 | + ? (int)(CLOCK_TICK_RATE/freq) |
| 88 | + : freq) < 0) { |
| 89 | + printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ |
| 90 | + perror("ioctl"); |
| 91 | + } |
| 92 | + } |
| 93 | + else |
| 94 | + { |
| 95 | + /* BEEP_TYPE_EVDEV */ |
| 96 | + struct input_event e; |
| 97 | + |
| 98 | + e.type = EV_SND; |
| 99 | + e.code = SND_TONE; |
| 100 | + e.value = freq; |
| 101 | + |
| 102 | + write(console_fd, &e, sizeof(struct input_event)); |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | void play_beep(beep_parms_t parms) { |
| 107 | int i; /* loop counter */ |
| 108 | |
| 109 | /* try to snag the console */ |
| 110 | - if((console_fd = open("/dev/console", O_WRONLY)) == -1) { |
| 111 | - fprintf(stderr, "Could not open /dev/console for writing.\n"); |
| 112 | + |
| 113 | + if(console_device) |
| 114 | + console_fd = open(console_device, O_WRONLY); |
| 115 | + else |
| 116 | + if((console_fd = open("/dev/input/event0", O_WRONLY)) == -1) |
| 117 | + if((console_fd = open("/dev/tty0", O_WRONLY)) == -1) |
| 118 | + console_fd = open("/dev/vc/0", O_WRONLY); |
| 119 | + |
| 120 | + if(console_fd == -1) { |
| 121 | + fprintf(stderr, "Could not open %s for writing\n", |
| 122 | + console_device != NULL ? console_device : "/dev/tty0 or /dev/vc/0"); |
| 123 | printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ |
| 124 | perror("open"); |
| 125 | exit(1); |
| 126 | } |
| 127 | |
| 128 | + if (ioctl(console_fd, EVIOCGSND(0)) != -1) |
| 129 | + console_type = BEEP_TYPE_EVDEV; |
| 130 | + else |
| 131 | + console_type = BEEP_TYPE_CONSOLE; |
| 132 | + |
| 133 | /* Beep */ |
| 134 | for (i = 0; i < parms.reps; i++) { /* start beep */ |
| 135 | - if(ioctl(console_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/parms.freq)) < 0) { |
| 136 | - printf("\a"); /* Output the only beep we can, in an effort to fall back on usefulness */ |
| 137 | - perror("ioctl"); |
| 138 | - } |
| 139 | + do_beep(parms.freq); |
| 140 | /* Look ma, I'm not ansi C compatible! */ |
| 141 | usleep(1000*parms.length); /* wait... */ |
| 142 | - ioctl(console_fd, KIOCSOUND, 0); /* stop beep */ |
| 143 | + do_beep(0); |
| 144 | if(parms.end_delay || (i+1 < parms.reps)) |
| 145 | usleep(1000*parms.delay); /* wait... */ |
| 146 | } /* repeat. */ |
| 147 | @@ -295,5 +345,8 @@ int main(int argc, char **argv) { |
| 148 | parms = next; |
| 149 | } |
| 150 | |
| 151 | + if(console_device) |
| 152 | + free(console_device); |
| 153 | + |
| 154 | return EXIT_SUCCESS; |
| 155 | } |