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 } 156