diff options
Diffstat (limited to 'unsaver.c')
-rw-r--r-- | unsaver.c | 110 |
1 files changed, 79 insertions, 31 deletions
@@ -47,16 +47,16 @@ typedef enum { /* user options */ int interval = DEFAULT_INTERVAL; /* -i (always in millisec) */ -int debug = 0; /* -D */ +int debug = 0; /* -d */ int keycode = -1; /* -k */ int button = -1; /* -b */ -char *event_dir = EVENTDIR; /* -d */ +const char *event_dir = EVENTDIR; /* joydev args can change this */ 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 */ -int monitor_joysticks = 1; /* -F */ -int monitor_fullscreen = 0; /* -f, -F */ +int monitor_joysticks = 1; /* -f clears this */ +int monitor_fullscreen = 1; /* -j clears this */ /* joystick stuff */ char *joynames[MAX_STICKS + 1]; @@ -77,8 +77,8 @@ struct inotify_event *inotify_ev = (struct inotify_event *)inotify_buf; /* not going to include pages of usage info duplicating the man page */ void usage(void) { printf(PROJ " 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("Usage: %s [-i interval] [-m | -b button | -k keycode | -c command | -x]\n", self); + printf(" [-j | -f ] [-d] [inputdir] [joystick [...]]\n"); printf("Built-in defaults: MAX_STICKS=%d, -d " EVENTDIR ", -j " JSNODE "\n", MAX_STICKS); printf("See man page for details\n"); exit(0); @@ -206,6 +206,39 @@ void send_fake_x_event(void) { } } +/* wrapper for open(2), does an ioctl to make sure the thing it just + opened really is a joystick. also warns on 'permission denied'. */ +int js_open(const char *path, int mode) { + int fd, res, ver; + + fd = open(path, mode); + + if(fd < 0 && errno == EACCES) + fprintf(stderr, "%s: warning: %s exists, but: %s\n", + self, path, strerror(errno)); + + if(fd > -1) { + res = ioctl(fd, JSIOCGVERSION, &ver); + + if(res < 0) { + if(errno == ENOTTY || errno == EINVAL) { + fprintf(stderr, "%s: file %s is not a joystick\n", self, path); + exit(1); + } else { + fprintf(stderr, "%s: %s: %s\n", self, path, strerror(errno)); + exit(1); + } + } + + /* don't really need this much detail: + if(debug) + fprintf(stderr, "joystick driver version 0x%x\n", ver); + */ + } + + return fd; +} + void open_joysticks(void) { int fdcount, i; struct js_event e; @@ -214,7 +247,7 @@ void open_joysticks(void) { for(i = 0; i < last_joyname; i++) { int synthev = 0; if(joyfds[i] > -1) close(joyfds[i]); - joyfds[i] = open(joynames[i], O_RDONLY | O_NONBLOCK); + joyfds[i] = js_open(joynames[i], O_RDONLY | O_NONBLOCK); if(joyfds[i] > -1) { fdcount++; while( (read(joyfds[i], &e, sizeof(e)) > 0) && (e.type & JS_EVENT_INIT) ) @@ -389,7 +422,7 @@ void set_exe_name(const char *argv0) { if(p[0] == '/' && p[1]) self = p + 1; } -char *make_joystick_name(int js) { +char *joy_num_to_name(int js) { static char buf[PATH_MAX + 1]; sprintf(buf, "%s/%s%d", event_dir, js_node_name, js); return buf; @@ -407,7 +440,7 @@ void add_joystick_name(const char *name) { } if(*name >= '0' && *name <= '9') { - add_joystick_name(make_joystick_name(atoi(name))); + add_joystick_name(joy_num_to_name(atoi(name))); return; } @@ -415,16 +448,30 @@ void add_joystick_name(const char *name) { die(strerror(errno)); if(debug) - fprintf(stderr, "added device name %d: %s\n", last_joyname, name); + fprintf(stderr, "added device %d: %s\n", last_joyname, joynames[last_joyname]); last_joyname++; } +void add_joystick_num(char *arg) { + int i; + char *end; + + i = strtol(arg, &end, 0); + + if(end == arg || *end || i < 0) { + fprintf(stderr, "%s: invalid joystick number: %s\n", self, arg); + exit(1); + } + + add_joystick_name(joy_num_to_name(i)); +} + void populate_joynames(void) { int i; for(i = 0; i < MAX_STICKS; i++) { - add_joystick_name(make_joystick_name(i)); + add_joystick_name(joy_num_to_name(i)); } } @@ -474,7 +521,7 @@ void parse_args(int argc, char **argv) { while(++argv, --argc) { if(argv[0][0] != '-') { /* no dash, treat as a joystick device */ - add_joystick_name(*argv); + add_joystick_num(*argv); autodiscover = 0; } else { if(argv[0][1] && argv[0][2]) @@ -516,22 +563,6 @@ void parse_args(int argc, char **argv) { die("-i requires a positive integer argument in milliseconds"); break; case 'd': - if(nextarg) { - event_dir = nextarg; - argv++, argc--; - } else { - die("-d requires a directory argument"); - } - break; - case 'j': - if(nextarg) { - js_node_name = nextarg; - argv++, argc--; - } else { - die("-j requires a string argument"); - } - break; - case 'D': debug = 1; break; case 'c': @@ -547,10 +578,11 @@ void parse_args(int argc, char **argv) { set_fake_mode(fm_cmd); c_command = X_COMMAND; break; - case 'F': - monitor_joysticks = 0; /* and fall thru */ case 'f': - monitor_fullscreen = 1; + monitor_joysticks = 0; + break; + case 'j': + monitor_fullscreen = 0; break; default: die("unrecognized argument, try --help"); @@ -558,6 +590,9 @@ void parse_args(int argc, char **argv) { } } } + + if(!monitor_joysticks && !monitor_fullscreen) + die("nothing to monitor (can't use -f and -j together)"); } /* make ourselves a daemon, double-fork technique. @@ -731,9 +766,22 @@ void print_banner() { self, VERSION, m, interval); } +void read_env_vars(void) { + char *tmp; + + if( (tmp = getenv("UNSAVER_JS_DIR")) ) + event_dir = tmp; + + if( (tmp = getenv("UNSAVER_JS_NODE")) ) + js_node_name = tmp; + +} + int main(int argc, char **argv) { set_exe_name(argv[0]); + read_env_vars(); + parse_args(argc, argv); print_banner(); |