diff options
Diffstat (limited to 'jsmond.c')
-rw-r--r-- | jsmond.c | 91 |
1 files changed, 86 insertions, 5 deletions
@@ -35,12 +35,15 @@ #define MIN_BUTTON 1 #define MAX_BUTTON 10 +/* command for -x */ +#define X_COMMAND "xscreensaver-command -deactivate" + typedef enum { - fm_auto_keycode, fm_keycode, fm_button, fm_motion + fm_auto_keycode, fm_keycode, fm_button, fm_motion, fm_cmd } fake_mode_t; /* user options */ -int interval = 250; /* -i */ +int interval = 250; /* -i (always in millisec) */ int debug = 0; /* -D */ int keycode = -1; /* -k */ int button = -1; /* -b */ @@ -48,6 +51,7 @@ char *event_dir = EVENTDIR; /* -d */ char *js_node_name = JSNODE; /* -j */ int autodiscover = 1; /* cleared if user supplies joydev args */ fake_mode_t fake_mode = fm_auto_keycode; /* -k, -b, -m */ +char *c_command = NULL; /* -c, -x */ /* joystick stuff */ char *joynames[MAX_STICKS + 1]; @@ -167,6 +171,14 @@ void send_fake_motion(void) { XSync(xdisp, 0); } +void exec_command(void) { + if(!c_command) + die("BUG: c_command is NULL\n"); + + if(debug) fprintf(stderr, "executing \"%s\"\n", c_command); + system(c_command); +} + void send_fake_x_event(void) { switch(fake_mode) { case fm_keycode: @@ -178,6 +190,9 @@ void send_fake_x_event(void) { case fm_motion: send_fake_motion(); break; + case fm_cmd: + exec_command(); + break; default: /* This Never Happens(tm) */ fprintf(stderr, "%s: BUG: fake_mode %d isn't a valid fake_mode_t!\n", self, fake_mode); @@ -221,10 +236,17 @@ void check_inotify() { fprintf(stderr, "got event with name %s: 0x%x\n", inotify_ev->name, inotify_ev->mask); } } + + /* not much we can do to recover from this: */ if(inotify_ev->mask & IN_DELETE_SELF) { - /* not much we can do to recover from this */ die("someone deleted our device directory!"); } + + /* ...or this: */ + if(inotify_ev->mask & IN_UNMOUNT) { + die("someone unmounted our device directory!"); + } + usleep(EVENT_DELAY); /* might not need, be paranoid */ open_joysticks(); } else { @@ -340,6 +362,37 @@ void set_fake_mode(fake_mode_t newmode) { fake_mode = newmode; } +int set_interval(const char *arg) { + char *end; + + interval = strtol(arg, &end, 0); + + /* no digits at all */ + if(end == arg) return 0; + + /* no 0 or negative */ + if(interval < 1) return 0; + + /* digits only */ + switch(*end) { + case '\0': + /* digits only, try to guess */ + if(interval < 100) { + fprintf(stderr, + "%s: treating -i %d as %d seconds (use -i %dms if you meant %dms)\n", + self, interval, interval, interval, interval); + /* fall through */ + } else { + break; + } + case 's': interval *= 1000; break; /* sec */ + case 'm': break; /* ms, use as-is */ + } + + if(debug) fprintf(stderr, "interval set to %dms\n", interval); + return 1; +} + void parse_args(int argc, char **argv) { char *nextarg; @@ -384,7 +437,7 @@ void parse_args(int argc, char **argv) { } break; case 'i': - if(nextarg && (interval = atoi(nextarg)) > 0) + if(nextarg && set_interval(nextarg)) argv++, argc--; else die("-i requires a positive integer argument in milliseconds"); @@ -408,6 +461,23 @@ void parse_args(int argc, char **argv) { case 'D': debug = 1; break; + case 'c': + if(nextarg) { + set_fake_mode(fm_cmd); + c_command = nextarg; + argv++, argc--; + } else { + die("-c requires a command argument"); + } + break; + case 'x': + set_fake_mode(fm_cmd); + c_command = X_COMMAND; + break; + case 'f': + case 'F': + die("-f and -F not yet implemented"); + break; default: die("unrecognized argument, try --help"); break; @@ -511,12 +581,23 @@ void find_keycode() { } } +/* the device name check is mostly to guard against typos */ +void check_joyname(int i) { + if(joynames[i] && (strncmp(event_dir, joynames[i], strlen(event_dir)) != 0)) { + fprintf(stderr, "%s: device %s is not in event dir %s\n", + self, joynames[i], event_dir); + exit(1); + } +} + /* init_* functions. these are only called once each, from main() */ void init_joysticks(void) { int i; - for(i = 0; i < MAX_STICKS; i++) + for(i = 0; i < MAX_STICKS; i++) { joyfds[i] = -1; + check_joyname(i); + } open_joysticks(); } |