aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jsmond.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/jsmond.c b/jsmond.c
index 0e3b35f..3dd2578 100644
--- a/jsmond.c
+++ b/jsmond.c
@@ -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) {