diff options
-rw-r--r-- | jsmond.c | 73 |
1 files changed, 58 insertions, 15 deletions
@@ -18,6 +18,23 @@ #include <linux/joystick.h> #include <sys/inotify.h> +/* microseconds to wait between sending a keypresss + or mouse click event and its release */ +#define EVENT_DELAY 100000 + +/* if we can't find an unused keycode in the X keymap, use this one */ +#define FALLBACK_KEYCODE 255 + +/* min/max allowed keycodes. really this should be queried from + the X server, but for Xorg this value is good enough for + argument checking. the max is 0xff as keycodes are 8 bit unsigned. */ +#define MIN_KEYCODE 8 +#define MAX_KEYCODE 255 + +/* same as above, for mouse buttons. */ +#define MIN_BUTTON 1 +#define MAX_BUTTON 10 + /* user options */ int interval = 250; /* -i */ int debug = 0; /* -D */ @@ -46,7 +63,7 @@ void usage(void) { printf("jsmond v" VERSION " by B. Watson, WTFPL\n"); printf("Usage: %s [-i interval] [-b button | -k keycode] [-j name]\n", self); printf(" [-d dir] [-D] [joystick [...]]\n"); - printf("Built-in defaults: MAX_STICKS=%d, EVENTDIR=" EVENTDIR ", JSNODE=" JSNODE "\n"); + printf("Built-in defaults: MAX_STICKS=%d, EVENTDIR=" EVENTDIR ", JSNODE=" JSNODE "\n", MAX_STICKS); printf("See man page for details\n"); exit(0); } @@ -72,7 +89,7 @@ void send_fake_key(void) { XSync(xdisp, 0); /* ...wait 1/10 sec... */ - usleep(100000); + usleep(EVENT_DELAY); /* ...release */ XTestFakeKeyEvent(xdisp, keycode, 0, 0L); @@ -87,7 +104,7 @@ void send_fake_click(void) { XSync(xdisp, 0); /* ...wait 1/10 sec... */ - usleep(100000); + usleep(EVENT_DELAY); /* ...release */ XTestFakeButtonEvent(xdisp, button, 0, 0L); @@ -117,8 +134,10 @@ void open_joysticks(void) { void init_joysticks(void) { int i; + for(i = 0; i < MAX_STICKS; i++) joyfds[i] = -1; + open_joysticks(); } @@ -136,7 +155,7 @@ void check_inotify() { fprintf(stderr, "got event with name %s: %x\n", inotify_ev->name, inotify_ev->mask); } } - usleep(100000); /* might not need, be paranoid */ + usleep(EVENT_DELAY); /* might not need, be paranoid */ open_joysticks(); } else { if(errno != EAGAIN) { @@ -151,10 +170,11 @@ void check_inotify() { is process death. */ void main_loop(void) { struct js_event e; - int i, active; + int i, active, sleep_us; fprintf(stderr, "entering main_loop()\n"); + sleep_us = interval * 1000; while(1) { /* Xlib will obligingly kill us, if X goes away */ ping_x_server(); @@ -164,7 +184,7 @@ void main_loop(void) { /* let the fds gather events as we slumber */ if(debug) fprintf(stderr, "sleeping %dms...\n", interval); - usleep(interval * 1000); + usleep(sleep_us); /* now see if any of them got any events while we took a nap */ active = 0; @@ -254,19 +274,26 @@ void parse_args(int argc, char **argv) { nextarg = argv[1]; switch(argv[0][1]) { case 'k': - if(nextarg) { - keycode = atoi(nextarg); /* TODO: error check */ + if(nextarg && + (keycode = atoi(nextarg)) && + (keycode >= MIN_KEYCODE) && + (keycode <= MAX_KEYCODE) ) + { argv++, argc--; } else { - die("-k requires a keycode argument, 0-255"); + fprintf(stderr, "%s: -k requires a keycode argument, %d-%d\n", + self, MIN_KEYCODE, MAX_KEYCODE); + exit(1); } break; case 'b': - if(nextarg && (button = atoi(nextarg))) { - keycode = -1; + if(nextarg) button = atoi(nextarg); + if ( (button >= MIN_BUTTON) && (button <= MAX_BUTTON) ) { argv++, argc--; } else { - die("-b requires a positive integer button argument"); + fprintf(stderr, "%s: -b requires a mouse button argument, %d-%d\n", + self, MIN_BUTTON, MAX_BUTTON); + exit(1); } break; case 'i': @@ -409,14 +436,30 @@ void find_keycode() { } if(keycode < 0) { - fprintf(stderr, "%s: can't find a free keycode in the keymap, using 255\n", self); - keycode = 255; + fprintf(stderr, + "%s: can't find a free keycode in the keymap, using %d\n", + self, FALLBACK_KEYCODE); + keycode = FALLBACK_KEYCODE; } + } void init_x(void) { connect_to_x(); - if(keycode < 0 && button < 0) find_keycode(); + + if(keycode < 0 && button < 0) { + find_keycode(); + } + + /* do this now, before daemonizing. if the keycode is invalid, Xlib + will kill us. we'd better let that happen while we still have a + stderr, so the user can see what happened. */ + if(keycode > -1) + send_fake_key(); + + /* same for the mouse, just in case */ + if(button > -1) + send_fake_click(); } int main(int argc, char **argv) { |