diff options
author | B. Watson <yalhcru@gmail.com> | 2020-05-18 19:50:10 -0400 |
---|---|---|
committer | B. Watson <yalhcru@gmail.com> | 2020-05-18 19:50:10 -0400 |
commit | 71280fcd79497f4c9731c89b33ddc300bb14ae82 (patch) | |
tree | d537ebbacf4a25f61c582005a80afe570702b19a | |
parent | 7c9e476867bc4271919dfc367514be0033426344 (diff) | |
download | unsaver-71280fcd79497f4c9731c89b33ddc300bb14ae82.tar.gz |
add command execution mode, -c and -x
-rw-r--r-- | jsmond.1 | 58 | ||||
-rw-r--r-- | jsmond.c | 91 | ||||
-rw-r--r-- | jsmond.html | 57 | ||||
-rw-r--r-- | jsmond.rst | 34 |
4 files changed, 198 insertions, 42 deletions
@@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH JSMOND 1 "2020-05-17" "0.2.0" "Urchlay" +.TH JSMOND 1 "2020-05-18" "0.2.0" "Urchlay" .SH NAME jsmond \- deactivate screensaver on joystick activity . @@ -36,7 +36,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] . .SH SYNOPSIS .sp -jsmond [\fB\-i interval\fP] [\fB\-k keycode\fP | \fB\-b button\fP] [\fB\-d dir\fP] [\fB\-j name\fP] [\fB\-D\fP] [\fBjoydev [joydev ...]\fP] +jsmond [\fB\-i interval[s|ms]\fP] [\fB\-m\fP | \fB\-k keycode\fP | \fB\-b button\fP] [\fB\-d dir\fP] [\fB\-j name\fP] [\fB\-D\fP] [\fBjoydev [joydev ...]\fP] .SH DESCRIPTION .sp jsmond lets you play games with your joysticks/gamepads without @@ -49,7 +49,7 @@ as joysticks are plugged in and unplugged. .sp Every \fIinterval\fP milliseconds (250, or whatever \fB\-i\fP is set to), jsmond checks to see if there\(aqs been any activity on any of the devices it\(aqs -monitoring. If so, it sends a fake keystroke or mouse button click, which +monitoring. If so, it sends a fake mouse movement, keystroke, or mouse button click, which the screen saver will see as activity. .sp It\(aqs recommended to let jsmond find the joysticks itself. However, @@ -67,9 +67,12 @@ if you need to kill the daemon. .B \-\-help Print usage summary .TP -.BI \-i \ <millis> -Interval to check for activity, in milliseconds. -Default: 250. +.BI \-i \ <interval> +Interval to check for activity. Can be given in seconds +with \fIs\fP suffix (e.g. \fB1s\fP), or milliseconds with \fIm\fP +(e.g. \fB200m\fP). If just a number is given, it\(aqs assumed +to be in seconds if it\(aqs under 100, otherwise it\(aqs treated +as milliseconds. Default: 250m. .TP .BI \-k \ <keycode> Send this keycode when activity is detected. Default @@ -80,7 +83,24 @@ in your usual keymapping (use "xmodmap \-pk" to find one). .BI \-b \ <button> Send a click of this button when activity is detected, rather than a keystroke. Should be a button that -applications don\(aqt normally respond to (6 or higher). +applications don\(aqt normally respond to (6 or higher), +but in some environments, the window manager responds to +all the \(aqextra\(aq buttons as though they were button 1. +.TP +.B \-m +Send mouse movements rather than a keystroke. This will +move the pointer 10 pixels to the right and down, then +10 pixels to the left and up, then warp the pointer back +to its starting point. +.TP +.BI \-c \ <command> +Run a command when activity is detected, rather than +sending a fake keystroke/click/motion. It\(aqs recommended +to set \fIinterval\fP to at least 1 second, when using this +option. +.TP +.B \-x +Same as \fB\-c "xscreensaver\-command \-exit" \-i 1s\fP\&. .UNINDENT .sp These options are intended for developers and \fIreally\fP shouldn\(aqt be @@ -103,11 +123,14 @@ A space is required between an option and its argument, as shown above. Use e.g. \fB\-i 300\fP, not \fB\-i300\fP\&. .SH NOTES .sp -By default, jsmond searches for and monitors all the joysticks it can -find, up to MAX_STICKS (normally 16; see the \fB\-\-help\fP output to find -the compiled\-in default). You can override the search on the command -line by providing one or more \fBjoydev\fP arguments, in which case only -those devices will be monitored. +jsmond was tested with xlock(1) and xscreensaver(1). All 3 modes +(keycode, mouse click, and mouse motion) work with xscreensaver. +xlock doesn\(aqt respond to mouse motion, so use the keycode or click +modes with it. +.sp +jsmond can monitor up to MAX_STICKS joysticks. This is a compile time +constant, normally set to 16. See the \fB\-\-help\fP output to find out +the compiled\-in default. .sp \fBjoydev\fP arguments can be either a path to a device node (e.g. \fI/dev/input/js0\fP or similar), or a number, which will have the default @@ -121,8 +144,12 @@ jsmond will wait for devices to come into existence (e.g. as created by \fBudev\fP). .sp If the screensaver is configured to lock the screen, and it has already -activated, pressing a joystick button/direction will just bring up the +done so, pressing a joystick button/direction will just bring up the password dialog, same as pressing a key or mouse button would. +.sp +jsmond depends on the XTest extension being present in the X server. If +you get a "X server doesn\(aqt support XTest extension" error, see your X +server documentation to find out how to enable XTest. .SH EXIT STATUS .sp Without the \-D option, the exit status is 0 (success) if jsmond @@ -141,7 +168,10 @@ names (better to autodetect). .sp Normally once daemonized, jsmond is very robust. However, if something does go wrong, there\(aqs no way to find out what. Probably there should -be a log file, or use syslog. +be a log file, or use syslog (or is that overkill?). +.sp +It should be (but currently isn\(aqt) possible to at least work in +mouse\-motion mode even without the XTest extension, via XWarpPointer(). .sp jsmond isn\(aqt portable. It only works on Linux, at least for now, for three reasons: @@ -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(); } diff --git a/jsmond.html b/jsmond.html index 20608d9..9c4f31b 100644 --- a/jsmond.html +++ b/jsmond.html @@ -5,7 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> <title>jsmond</title> -<meta name="date" content="2020-05-17" /> +<meta name="date" content="2020-05-18" /> <style type="text/css"> /* @@ -373,7 +373,7 @@ ul.auto-toc { <tr class="manual-group field"><th class="docinfo-name">Manual group:</th><td class="field-body">Urchlay</td> </tr> <tr><th class="docinfo-name">Date:</th> -<td>2020-05-17</td></tr> +<td>2020-05-18</td></tr> <tr><th class="docinfo-name">Version:</th> <td>0.2.0</td></tr> </tbody> @@ -382,7 +382,7 @@ ul.auto-toc { <!-- rst2man.py jsmond.rst > jsmond.1 --> <div class="section" id="synopsis"> <h1>SYNOPSIS</h1> -<p>jsmond [<strong>-i interval</strong>] [<strong>-k keycode</strong> | <strong>-b button</strong>] [<strong>-d dir</strong>] [<strong>-j name</strong>] [<strong>-D</strong>] [<strong>joydev [joydev ...]</strong>]</p> +<p>jsmond [<strong>-i interval[s|ms]</strong>] [<strong>-m</strong> | <strong>-k keycode</strong> | <strong>-b button</strong>] [<strong>-d dir</strong>] [<strong>-j name</strong>] [<strong>-D</strong>] [<strong>joydev [joydev ...]</strong>]</p> </div> <div class="section" id="description"> <h1>DESCRIPTION</h1> @@ -394,7 +394,7 @@ These devices don't have to actually exist: they can come and go as joysticks are plugged in and unplugged.</p> <p>Every <em>interval</em> milliseconds (250, or whatever <strong>-i</strong> is set to), jsmond checks to see if there's been any activity on any of the devices it's -monitoring. If so, it sends a fake keystroke or mouse button click, which +monitoring. If so, it sends a fake mouse movement, keystroke, or mouse button click, which the screen saver will see as activity.</p> <p>It's recommended to let jsmond find the joysticks itself. However, you can pass one or more device names (or just numbers) if the default @@ -415,9 +415,12 @@ if you need to kill the daemon.</p> <kbd><span class="option">--help</span></kbd></td> <td>Print usage summary</td></tr> <tr><td class="option-group"> -<kbd><span class="option">-i <var><millis></var></span></kbd></td> -<td>Interval to check for activity, in milliseconds. -Default: 250.</td></tr> +<kbd><span class="option">-i <var><interval></var></span></kbd></td> +<td>Interval to check for activity. Can be given in seconds +with <em>s</em> suffix (e.g. <strong>1s</strong>), or milliseconds with <em>m</em> +(e.g. <strong>200m</strong>). If just a number is given, it's assumed +to be in seconds if it's under 100, otherwise it's treated +as milliseconds. Default: 250m.</td></tr> <tr><td class="option-group"> <kbd><span class="option">-k <var><keycode></var></span></kbd></td> <td>Send this keycode when activity is detected. Default @@ -428,7 +431,24 @@ in your usual keymapping (use "xmodmap -pk" to find one).</td></tr> <kbd><span class="option">-b <var><button></var></span></kbd></td> <td>Send a click of this button when activity is detected, rather than a keystroke. Should be a button that -applications don't normally respond to (6 or higher).</td></tr> +applications don't normally respond to (6 or higher), +but in some environments, the window manager responds to +all the 'extra' buttons as though they were button 1.</td></tr> +<tr><td class="option-group"> +<kbd><span class="option">-m</span></kbd></td> +<td>Send mouse movements rather than a keystroke. This will +move the pointer 10 pixels to the right and down, then +10 pixels to the left and up, then warp the pointer back +to its starting point.</td></tr> +<tr><td class="option-group"> +<kbd><span class="option">-c <var><command></var></span></kbd></td> +<td>Run a command when activity is detected, rather than +sending a fake keystroke/click/motion. It's recommended +to set <em>interval</em> to at least 1 second, when using this +option.</td></tr> +<tr><td class="option-group"> +<kbd><span class="option">-x</span></kbd></td> +<td>Same as <strong>-c "xscreensaver-command -exit" -i 1s</strong>.</td></tr> </tbody> </table> <p>These options are intended for developers and <em>really</em> shouldn't be @@ -455,11 +475,13 @@ above. Use e.g. <strong>-i 300</strong>, not <strong>-i300</strong>.</p> </div> <div class="section" id="notes"> <h1>NOTES</h1> -<p>By default, jsmond searches for and monitors all the joysticks it can -find, up to MAX_STICKS (normally 16; see the <strong>--help</strong> output to find -the compiled-in default). You can override the search on the command -line by providing one or more <strong>joydev</strong> arguments, in which case only -those devices will be monitored.</p> +<p>jsmond was tested with xlock(1) and xscreensaver(1). All 3 modes +(keycode, mouse click, and mouse motion) work with xscreensaver. +xlock doesn't respond to mouse motion, so use the keycode or click +modes with it.</p> +<p>jsmond can monitor up to MAX_STICKS joysticks. This is a compile time +constant, normally set to 16. See the <strong>--help</strong> output to find out +the compiled-in default.</p> <p><strong>joydev</strong> arguments can be either a path to a device node (e.g. <em>/dev/input/js0</em> or similar), or a number, which will have the default device basename prepended to it. This is normally "/dev/input/js", but @@ -470,8 +492,11 @@ to detect hotplug events!</p> jsmond will wait for devices to come into existence (e.g. as created by <strong>udev</strong>).</p> <p>If the screensaver is configured to lock the screen, and it has already -activated, pressing a joystick button/direction will just bring up the +done so, pressing a joystick button/direction will just bring up the password dialog, same as pressing a key or mouse button would.</p> +<p>jsmond depends on the XTest extension being present in the X server. If +you get a "X server doesn't support XTest extension" error, see your X +server documentation to find out how to enable XTest.</p> </div> <div class="section" id="exit-status"> <h1>EXIT STATUS</h1> @@ -489,7 +514,9 @@ been plugged in yet. Try to avoid typos, if you really have to use device names (better to autodetect).</p> <p>Normally once daemonized, jsmond is very robust. However, if something does go wrong, there's no way to find out what. Probably there should -be a log file, or use syslog.</p> +be a log file, or use syslog (or is that overkill?).</p> +<p>It should be (but currently isn't) possible to at least work in +mouse-motion mode even without the XTest extension, via XWarpPointer().</p> <p>jsmond isn't portable. It only works on Linux, at least for now, for three reasons:</p> <ul class="simple"> @@ -20,7 +20,7 @@ deactivate screensaver on joystick activity SYNOPSIS ======== -jsmond [**-i interval**] [**-m** | **-k keycode** | **-b button**] [**-d dir**] [**-j name**] [**-D**] [**joydev [joydev ...]**] +jsmond [**-i interval[s|ms]**] [**-m** | **-k keycode** | **-b button**] [**-d dir**] [**-j name**] [**-D**] [**joydev [joydev ...]**] DESCRIPTION =========== @@ -53,8 +53,11 @@ OPTIONS --help Print usage summary --i <millis> Interval to check for activity, in milliseconds. - Default: 250. +-i <interval> Interval to check for activity. Can be given in seconds + with *s* suffix (e.g. **1s**), or milliseconds with *m* + (e.g. **200m**). If just a number is given, it's assumed + to be in seconds if it's under 100, otherwise it's treated + as milliseconds. Default: 250m. -k <keycode> Send this keycode when activity is detected. Default is to search the keymap for an unused code. If you set this @@ -72,6 +75,18 @@ OPTIONS 10 pixels to the left and up, then warp the pointer back to its starting point. +-c <command> Run a command when activity is detected, rather than + sending a fake keystroke/click/motion. It's recommended + to set *interval* to at least 1 second, when using this + option. + +-x Same as **-c "xscreensaver-command -deactivate" -i 1s**. + +-f Disable screensaver if a full-screen window is detected. + This isn't likely to be 100% reliable. + +-F Same as **-f**, but also disables joystick monitoring entirely. + These options are intended for developers and *really* shouldn't be needed for normal use: @@ -89,11 +104,14 @@ above. Use e.g. **-i 300**, not **-i300**. NOTES ===== -By default, jsmond searches for and monitors all the joysticks it can -find, up to MAX_STICKS (normally 16; see the **--help** output to find -the compiled-in default). You can override the search on the command -line by providing one or more **joydev** arguments, in which case only -those devices will be monitored. +jsmond was tested with xlock(1) and xscreensaver(1). All 3 modes +(keycode, mouse click, and mouse motion) work with xscreensaver. +xlock doesn't respond to mouse motion, so use the keycode or click +modes with it. + +jsmond can monitor up to MAX_STICKS joysticks. This is a compile time +constant, normally set to 16. See the **--help** output to find out +the compiled-in default. **joydev** arguments can be either a path to a device node (e.g. */dev/input/js0* or similar), or a number, which will have the default |