diff options
author | B. Watson <yalhcru@gmail.com> | 2020-05-20 02:01:27 -0400 |
---|---|---|
committer | B. Watson <yalhcru@gmail.com> | 2020-05-20 02:01:27 -0400 |
commit | 3a5967b742ee196822e4d059a3bb2f6bea560ca6 (patch) | |
tree | dd698e0a20abceba0386fdc8e896751850d3d626 | |
parent | ede400dfffd0cdf0a59e224a116ef56352b4e5ac (diff) | |
download | unsaver-3a5967b742ee196822e4d059a3bb2f6bea560ca6.tar.gz |
simplify arguments, check that joysticks are really joysticks
-rw-r--r-- | unsaver.1 | 141 | ||||
-rw-r--r-- | unsaver.c | 110 | ||||
-rw-r--r-- | unsaver.html | 152 | ||||
-rw-r--r-- | unsaver.rst | 137 |
4 files changed, 326 insertions, 214 deletions
@@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH UNSAVER 1 "2020-05-19" "0.3.0" "Urchlay" +.TH UNSAVER 1 "2020-05-20" "0.3.0" "Urchlay" .SH NAME unsaver \- deactivate screensaver on joystick activity . @@ -36,38 +36,41 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] . .SH SYNOPSIS .sp -unsaver [\fB\-i interval[s|ms]\fP] [\fB\-m\fP | \fB\-k keycode\fP | \fB\-b button\fP | \fB\-c command\fP | \fB\-x\fP ] [\fB\-d dir\fP] [\fB\-j name\fP] [\fB\-f\fP] [\fB\-F\fP] [\fB\-D\fP] [\fBjoydev [joydev ...]\fP] +unsaver [\fB\-i interval[s|ms]\fP] [\fB\-m\fP | \fB\-k keycode\fP | \fB\-b button\fP | \fB\-c command\fP | \fB\-x\fP ] [\fB\-j\fP | \fB\-f\fP] [\fB\-d\fP] [\fBjoydev [joydev ...]\fP] .SH DESCRIPTION .sp unsaver lets you play games with your joysticks/gamepads without the screen -saver activating due to lack of keyboard/mouse input. It can also prevent +saver activating due to lack of keyboard/mouse input. It also prevents the screensaver from activating when a fullscreen window is in use (e.g. while watching a movie). .sp -Multiple joystick devices can be monitored. By default, unsaver -monitors up to 16 devices, named /dev/input/js0 through js15. -These devices don\(aqt have to actually exist: they can come and go -as joysticks are plugged in and unplugged. +unsaver should be started from your \fB\&.xinitrc\fP or whatever X startup +script your window manager or desktop environment uses. By default, it +will exit when the X server does. There\(aqs no PID file: use "pkill unsaver" +if you need to kill the daemon. .sp Every \fIinterval\fP milliseconds (250, or whatever \fB\-i\fP is set to), unsaver checks to see if there\(aqs been any activity on any of the devices it\(aqs 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 unsaver find the joysticks itself. However, -you can pass one or more device names (or just numbers) if the default -doesn\(aqt do the right thing for you. In this case, only these devices -will be monitored (no search is done). -.sp -unsaver should be started from your \fB\&.xinitrc\fP or whatever X startup -script your window manager or desktop environment uses. By default, it -will exit when the X server does. There\(aqs no PID file: use "pkill unsaver" -if you need to kill the daemon. +Multiple joystick devices can be monitored. By default, unsaver +monitors up to 16 devices, named /dev/input/js0 through js15. +These devices don\(aqt have to actually exist: they can come and go +as joysticks are plugged in and unplugged. See JOYSTICK DEVICES +if the defaults don\(aqt work for you. .SH OPTIONS +.SS General options .INDENT 0.0 .TP .B \-\-help -Print usage summary +Print usage summary and exit. +.TP +.B \-d +Debug mode: run in foreground and print verbose messages. +.UNINDENT +.SS Monitoring options +.INDENT 0.0 .TP .BI \-i \ <interval> Interval to check for activity. Can be given in seconds @@ -76,6 +79,20 @@ with \fIs\fP suffix (e.g. \fB1s\fP), or milliseconds with \fIm\fP to be in seconds if it\(aqs under 100, otherwise it\(aqs treated as milliseconds. Default: 250m. .TP +.B \-j +Only monitor joysticks; don\(aqt try to detect fullscreen windows. +\fB\-j\fP and \fB\-f\fP are mutually exclusive. +.TP +.B \-f +Only detect fullscreen windows; don\(aqt monitor joysticks. +\fB\-j\fP and \fB\-f\fP are mutually exclusive. Note that +\fBjoydevs\fP are ignored with \fB\-f\fP\&. +.UNINDENT +.SS Deactivation mode options +.sp +Only one of \fB\-k\fP/\fB\-b\fP/\fB\-m\fP/\fB\-c\fP/\fB\-x\fP is accepted. +.INDENT 0.0 +.TP .BI \-k \ <keycode> Send this keycode when activity is detected. Default is to search the keymap for an unused code. If you set this @@ -103,61 +120,25 @@ option, to avoid excess process\-spawning overhead. .TP .B \-x Same as \fB\-c "xscreensaver\-command \-deactivate" \-i 1s\fP\&. -.TP -.B \-f -Deactivate screensaver if a fullscreen window is detected. -This isn\(aqt likely to be 100% reliable yet. -.TP -.B \-F -Same as \fB\-f\fP, but also disables joystick monitoring entirely. -Note that \fB\-j\fP, \fB\-d\fP, and \fBjoydev\fP are ignored -with this option. -.UNINDENT -.sp -These options are intended for developers and \fIreally\fP shouldn\(aqt be -needed for normal use: -.INDENT 0.0 -.TP -.BI \-d \ <dir> -Path to the directory containing joystick device nodes. -Default is "/dev/input". This directory is monitored with -inotify(7) so unsaver will be aware of hotplug events. -.TP -.BI \-j \ <name> -Name of joystick device nodes, without any numeric -suffix. Default is "js". -.TP -.B \-D -Debug mode: run in foreground and print verbose messages. .UNINDENT .sp 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 -unsaver 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. +unsaver was tested with xlock(1), xscreensaver(1), and the built\-in +Xorg screensaver (see xset(1)). All 4 modes (keycode, mouse click, mouse +motion, command execution) work with xscreensaver. xlock doesn\(aqt have a +disable command nor respond to mouse motion, so use the keycode or click +modes with it. The "xset s" screen\-blanker works with keycodes, mouse +clicks, and mouse motion. I didn\(aqt test with gnome\-screensaver, sorry. .sp unsaver 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 -device basename prepended to it. This is normally "/dev/input/js", but -can be changed via the \fB\-d\fP and \fB\-j\fP options. Note that (currently) -all the joystick devices have to be in the same directory for unsaver -to detect hotplug events! -.sp -Note that it\(aqs \fInot\fP an error to give nonexistent joystick device names. -unsaver 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 -done so, pressing a joystick button/direction will just bring up the -password dialog, same as pressing a key or mouse button would. +done so, unsaver can\(aqt magically type your password for you. .sp unsaver 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 @@ -165,15 +146,43 @@ server documentation to find out how to enable XTest. .sp The fullscreen window monitoring has only been tested on a system with a single monitor, and may not work properly in multi\-head environments. +.SH JOYSTICK DEVICES +.sp +It\(aqs recommended to let unsaver find the joysticks itself. However, you +can pass one or more joystick numbers if the default doesn\(aqt do the right +thing for you. Remember that the first joystick is numbered 0, not 1. +.sp +When you manually set the list of devices, unsaver will only detect +hotplug events on the devices you gave it. If you plug in more joysticks, +they won\(aqt be monitored. +.sp +None of the joystick devices (whether autodetected or not) has to +actually exist when unsaver starts up, although their directory does +have to exist. This means unsaver can detect hotplug events, but you +have to be careful not to typo the device names. +.sp +If your system doesn\(aqt keep its joystick device nodes in /dev/input, and/or +if they\(aqre not named "js<num>", see ENVIRONMENT for a way to override +the default names. +.SH ENVIRONMENT +.INDENT 0.0 +.TP +.B UNSAVER_JS_DIR Path to joystick device nodes. If your OS keeps them +somewhere besides "/dev/input", set this variable. +.TP +.B UNSAVER_JS_NODE Base name for joystick device nodes. "js" by default. +\fIDon\(aqt\fP set this to "event", unsaver doesn\(aqt speak the +full Linux event protocol. +.UNINDENT .SH EXIT STATUS .sp -Without the \-D option, the exit status is 0 (success) if unsaver +Without the \-d option, the exit status is 0 (success) if unsaver successfully forked into the background. .sp A non\-zero exit status means an error in the command line arguments, or else fork() failed. No daemon will be running in this case. .sp -With the \-D option, unsaver never exits until it\(aqs killed. +With the \-d option, unsaver never exits until it\(aqs killed. .SH BUGS .sp There\(aqs no way to distinguish between an invalid device name and a @@ -188,9 +197,15 @@ be a log file, or use syslog (or is that overkill?). It should be (but currently isn\(aqt) possible to at least work in mouse\-motion mode even without the XTest extension, via XWarpPointer(). .sp +I \fIreally\fP need to use the XKB extension rather than the old & deprecated +Xlib keyboard API. This mainly affects the default "find an unused +keycode" mode. +.sp unsaver isn\(aqt portable. It only works on Linux, at least for now, for three reasons: .INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 .IP \(bu 2 It uses the Linux joystick API. .IP \(bu 2 @@ -199,6 +214,8 @@ It uses inotify(7) to detect joystick hotplug events. I haven\(aqt even looked at other OSes to see if it would be possible to port the code. .UNINDENT +.UNINDENT +.UNINDENT .\" EXAMPLES . .\" ======== @@ -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(); diff --git a/unsaver.html b/unsaver.html index 7d3ce80..04e1e92 100644 --- a/unsaver.html +++ b/unsaver.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>unsaver</title> -<meta name="date" content="2020-05-19" /> +<meta name="date" content="2020-05-20" /> <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-19</td></tr> +<td>2020-05-20</td></tr> <tr><th class="docinfo-name">Version:</th> <td>0.3.0</td></tr> </tbody> @@ -382,40 +382,51 @@ ul.auto-toc { <!-- rst2man.py unsaver.rst > unsaver.1 --> <div class="section" id="synopsis"> <h1>SYNOPSIS</h1> -<p>unsaver [<strong>-i interval[s|ms]</strong>] [<strong>-m</strong> | <strong>-k keycode</strong> | <strong>-b button</strong> | <strong>-c command</strong> | <strong>-x</strong> ] [<strong>-d dir</strong>] [<strong>-j name</strong>] [<strong>-f</strong>] [<strong>-F</strong>] [<strong>-D</strong>] [<strong>joydev [joydev ...]</strong>]</p> +<p>unsaver [<strong>-i interval[s|ms]</strong>] [<strong>-m</strong> | <strong>-k keycode</strong> | <strong>-b button</strong> | <strong>-c command</strong> | <strong>-x</strong> ] [<strong>-j</strong> | <strong>-f</strong>] [<strong>-d</strong>] [<strong>joydev [joydev ...]</strong>]</p> </div> <div class="section" id="description"> <h1>DESCRIPTION</h1> <p>unsaver lets you play games with your joysticks/gamepads without the screen -saver activating due to lack of keyboard/mouse input. It can also prevent +saver activating due to lack of keyboard/mouse input. It also prevents the screensaver from activating when a fullscreen window is in use (e.g. while watching a movie).</p> -<p>Multiple joystick devices can be monitored. By default, unsaver -monitors up to 16 devices, named /dev/input/js0 through js15. -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), unsaver -checks to see if there's been any activity on any of the devices it's -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 unsaver find the joysticks itself. However, -you can pass one or more device names (or just numbers) if the default -doesn't do the right thing for you. In this case, only these devices -will be monitored (no search is done).</p> <p>unsaver should be started from your <strong>.xinitrc</strong> or whatever X startup script your window manager or desktop environment uses. By default, it will exit when the X server does. There's no PID file: use "pkill unsaver" if you need to kill the daemon.</p> +<p>Every <em>interval</em> milliseconds (250, or whatever <strong>-i</strong> is set to), unsaver +checks to see if there's been any activity on any of the devices it's +monitoring. If so, it sends a fake mouse movement, keystroke, or mouse +button click, which the screen saver will see as activity.</p> +<p>Multiple joystick devices can be monitored. By default, unsaver +monitors up to 16 devices, named /dev/input/js0 through js15. +These devices don't have to actually exist: they can come and go +as joysticks are plugged in and unplugged. See JOYSTICK DEVICES +if the defaults don't work for you.</p> </div> <div class="section" id="options"> <h1>OPTIONS</h1> +<div class="section" id="general-options"> +<h2>General options</h2> <table class="docutils option-list" frame="void" rules="none"> <col class="option" /> <col class="description" /> <tbody valign="top"> <tr><td class="option-group"> <kbd><span class="option">--help</span></kbd></td> -<td>Print usage summary</td></tr> +<td>Print usage summary and exit.</td></tr> +<tr><td class="option-group"> +<kbd><span class="option">-d</span></kbd></td> +<td>Debug mode: run in foreground and print verbose messages.</td></tr> +</tbody> +</table> +</div> +<div class="section" id="monitoring-options"> +<h2>Monitoring options</h2> +<table class="docutils option-list" frame="void" rules="none"> +<col class="option" /> +<col class="description" /> +<tbody valign="top"> <tr><td class="option-group"> <kbd><span class="option">-i <var><interval></var></span></kbd></td> <td>Interval to check for activity. Can be given in seconds @@ -424,6 +435,25 @@ with <em>s</em> suffix (e.g. <strong>1s</strong>), or milliseconds with <em>m</e 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">-j</span></kbd></td> +<td>Only monitor joysticks; don't try to detect fullscreen windows. +<strong>-j</strong> and <strong>-f</strong> are mutually exclusive.</td></tr> +<tr><td class="option-group"> +<kbd><span class="option">-f</span></kbd></td> +<td>Only detect fullscreen windows; don't monitor joysticks. +<strong>-j</strong> and <strong>-f</strong> are mutually exclusive. Note that +<strong>joydevs</strong> are ignored with <strong>-f</strong>.</td></tr> +</tbody> +</table> +</div> +<div class="section" id="deactivation-mode-options"> +<h2>Deactivation mode options</h2> +<p>Only one of <strong>-k</strong>/<strong>-b</strong>/<strong>-m</strong>/<strong>-c</strong>/<strong>-x</strong> is accepted.</p> +<table class="docutils option-list" frame="void" rules="none"> +<col class="option" /> +<col class="description" /> +<tbody valign="top"> +<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 is to search the keymap for an unused code. If you set this @@ -451,74 +481,65 @@ option, to avoid excess process-spawning overhead.</td></tr> <tr><td class="option-group"> <kbd><span class="option">-x</span></kbd></td> <td>Same as <strong>-c "xscreensaver-command -deactivate" -i 1s</strong>.</td></tr> -<tr><td class="option-group"> -<kbd><span class="option">-f</span></kbd></td> -<td>Deactivate screensaver if a fullscreen window is detected. -This isn't likely to be 100% reliable yet.</td></tr> -<tr><td class="option-group"> -<kbd><span class="option">-F</span></kbd></td> -<td>Same as <strong>-f</strong>, but also disables joystick monitoring entirely. -Note that <strong>-j</strong>, <strong>-d</strong>, and <strong>joydev</strong> are ignored -with this option.</td></tr> -</tbody> -</table> -<p>These options are intended for developers and <em>really</em> shouldn't be -needed for normal use:</p> -<table class="docutils option-list" frame="void" rules="none"> -<col class="option" /> -<col class="description" /> -<tbody valign="top"> -<tr><td class="option-group"> -<kbd><span class="option">-d <var><dir></var></span></kbd></td> -<td>Path to the directory containing joystick device nodes. -Default is "/dev/input". This directory is monitored with -inotify(7) so unsaver will be aware of hotplug events.</td></tr> -<tr><td class="option-group"> -<kbd><span class="option">-j <var><name></var></span></kbd></td> -<td>Name of joystick device nodes, without any numeric -suffix. Default is "js".</td></tr> -<tr><td class="option-group"> -<kbd><span class="option">-D</span></kbd></td> -<td>Debug mode: run in foreground and print verbose messages.</td></tr> </tbody> </table> <p>A space is required between an option and its argument, as shown above. Use e.g. <strong>-i 300</strong>, not <strong>-i300</strong>.</p> </div> +</div> <div class="section" id="notes"> <h1>NOTES</h1> -<p>unsaver 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>unsaver was tested with xlock(1), xscreensaver(1), and the built-in +Xorg screensaver (see xset(1)). All 4 modes (keycode, mouse click, mouse +motion, command execution) work with xscreensaver. xlock doesn't have a +disable command nor respond to mouse motion, so use the keycode or click +modes with it. The "xset s" screen-blanker works with keycodes, mouse +clicks, and mouse motion. I didn't test with gnome-screensaver, sorry.</p> <p>unsaver 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 -can be changed via the <strong>-d</strong> and <strong>-j</strong> options. Note that (currently) -all the joystick devices have to be in the same directory for unsaver -to detect hotplug events!</p> -<p>Note that it's <em>not</em> an error to give nonexistent joystick device names. -unsaver 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 -done so, pressing a joystick button/direction will just bring up the -password dialog, same as pressing a key or mouse button would.</p> +done so, unsaver can't magically type your password for you.</p> <p>unsaver 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> <p>The fullscreen window monitoring has only been tested on a system with a single monitor, and may not work properly in multi-head environments.</p> </div> +<div class="section" id="joystick-devices"> +<h1>JOYSTICK DEVICES</h1> +<p>It's recommended to let unsaver find the joysticks itself. However, +you can pass one or more device names (or just numbers) if the default +doesn't do the right thing for you.</p> +<p>If you do use them, the <em>joydev</em> arguments can be one of 3 things:</p> +<blockquote> +<ul class="simple"> +<li>The first argument can optionally be a directory, which must exist. +The default is "/dev/input". unsaver will look for joystick devices here. +If there are no more <em>joydev</em> arguments, unsaver will monitor devices +and detect hotplug events on devices js0 through js15 in this directory.</li> +<li>One or more numbers. unsaver will prepend the directory and "js" to each number, +and monitor that device. Hotplug events will be detected <em>only</em> for +the specified devices. You could use this e.g. to not monitor your +2nd joystick, because it sometimes drifts and reports false events.</li> +<li>One or more device nodes (e.g. js0). Use relative paths here (relative +to the directory argument or "/dev/input"). This option only exists +for future-proofing (in case the js name changes someday). Hotplug +events will be detected <em>only</em> for the specified devices.</li> +</ul> +</blockquote> +<p>None of the joystick devices (whether autodetected, named, or numbered) +has to actually exist when unsaver starts up, although their directory +does have to exist. This means unsaver can detect hotplug events, but +you have to be careful not to typo the device names.</p> +</div> <div class="section" id="exit-status"> <h1>EXIT STATUS</h1> -<p>Without the -D option, the exit status is 0 (success) if unsaver +<p>Without the -d option, the exit status is 0 (success) if unsaver successfully forked into the background.</p> <p>A non-zero exit status means an error in the command line arguments, or else fork() failed. No daemon will be running in this case.</p> -<p>With the -D option, unsaver never exits until it's killed.</p> +<p>With the -d option, unsaver never exits until it's killed.</p> </div> <div class="section" id="bugs"> <h1>BUGS</h1> @@ -531,14 +552,19 @@ does go wrong, there's no way to find out what. Probably there should 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>I <em>really</em> need to use the XKB extension rather than the old & deprecated +Xlib keyboard API. This mainly affects the default "find an unused +keycode" mode.</p> <p>unsaver isn't portable. It only works on Linux, at least for now, for three reasons:</p> +<blockquote> <ul class="simple"> <li>It uses the Linux joystick API.</li> <li>It uses inotify(7) to detect joystick hotplug events.</li> <li>I haven't even looked at other OSes to see if it would be possible to port the code.</li> </ul> +</blockquote> <!-- EXAMPLES --> <!-- ======== --> </div> diff --git a/unsaver.rst b/unsaver.rst index 6e6f1dd..b66e2ad 100644 --- a/unsaver.rst +++ b/unsaver.rst @@ -20,40 +20,44 @@ deactivate screensaver on joystick activity SYNOPSIS ======== -unsaver [**-i interval[s|ms]**] [**-m** | **-k keycode** | **-b button** | **-c command** | **-x** ] [**-d dir**] [**-j name**] [**-f**] [**-F**] [**-D**] [**joydev [joydev ...]**] +unsaver [**-i interval[s|ms]**] [**-m** | **-k keycode** | **-b button** | **-c command** | **-x** ] [**-j** | **-f**] [**-d**] [**joydev [joydev ...]**] DESCRIPTION =========== unsaver lets you play games with your joysticks/gamepads without the screen -saver activating due to lack of keyboard/mouse input. It can also prevent +saver activating due to lack of keyboard/mouse input. It also prevents the screensaver from activating when a fullscreen window is in use (e.g. while watching a movie). -Multiple joystick devices can be monitored. By default, unsaver -monitors up to 16 devices, named /dev/input/js0 through js15. -These devices don't have to actually exist: they can come and go -as joysticks are plugged in and unplugged. +unsaver should be started from your **.xinitrc** or whatever X startup +script your window manager or desktop environment uses. By default, it +will exit when the X server does. There's no PID file: use "pkill unsaver" +if you need to kill the daemon. Every *interval* milliseconds (250, or whatever **-i** is set to), unsaver checks to see if there's been any activity on any of the devices it's monitoring. If so, it sends a fake mouse movement, keystroke, or mouse button click, which the screen saver will see as activity. -It's recommended to let unsaver find the joysticks itself. However, -you can pass one or more device names (or just numbers) if the default -doesn't do the right thing for you. In this case, only these devices -will be monitored (no search is done). - -unsaver should be started from your **.xinitrc** or whatever X startup -script your window manager or desktop environment uses. By default, it -will exit when the X server does. There's no PID file: use "pkill unsaver" -if you need to kill the daemon. +Multiple joystick devices can be monitored. By default, unsaver +monitors up to 16 devices, named /dev/input/js0 through js15. +These devices don't have to actually exist: they can come and go +as joysticks are plugged in and unplugged. See JOYSTICK DEVICES +if the defaults don't work for you. OPTIONS ======= ---help Print usage summary +General options +--------------- + +--help Print usage summary and exit. + +-d Debug mode: run in foreground and print verbose messages. + +Monitoring options +------------------ -i <interval> Interval to check for activity. Can be given in seconds with *s* suffix (e.g. **1s**), or milliseconds with *m* @@ -61,6 +65,18 @@ OPTIONS to be in seconds if it's under 100, otherwise it's treated as milliseconds. Default: 250m. +-j Only monitor joysticks; don't try to detect fullscreen windows. + **-j** and **-f** are mutually exclusive. + +-f Only detect fullscreen windows; don't monitor joysticks. + **-j** and **-f** are mutually exclusive. Note that + **joydevs** are ignored with **-f**. + +Deactivation mode options +------------------------- + +Only one of **-k**/**-b**/**-m**/**-c**/**-x** is accepted. + -k <keycode> Send this keycode when activity is detected. Default is to search the keymap for an unused code. If you set this manually, it should be a keycode that *doesn't* map to a keysym @@ -84,54 +100,25 @@ OPTIONS -x Same as **-c "xscreensaver-command -deactivate" -i 1s**. --f Deactivate screensaver if a fullscreen window is detected. - This isn't likely to be 100% reliable yet. - --F Same as **-f**, but also disables joystick monitoring entirely. - Note that **-j**, **-d**, and **joydev** are ignored - with this option. - -These options are intended for developers and *really* shouldn't be -needed for normal use: - --d <dir> Path to the directory containing joystick device nodes. - Default is "/dev/input". This directory is monitored with - inotify(7) so unsaver will be aware of hotplug events. - --j <name> Name of joystick device nodes, without any numeric - suffix. Default is "js". - --D Debug mode: run in foreground and print verbose messages. - A space is required between an option and its argument, as shown above. Use e.g. **-i 300**, not **-i300**. NOTES ===== -unsaver 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. +unsaver was tested with xlock(1), xscreensaver(1), and the built-in +Xorg screensaver (see xset(1)). All 4 modes (keycode, mouse click, mouse +motion, command execution) work with xscreensaver. xlock doesn't have a +disable command nor respond to mouse motion, so use the keycode or click +modes with it. The "xset s" screen-blanker works with keycodes, mouse +clicks, and mouse motion. I didn't test with gnome-screensaver, sorry. unsaver 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 -device basename prepended to it. This is normally "/dev/input/js", but -can be changed via the **-d** and **-j** options. Note that (currently) -all the joystick devices have to be in the same directory for unsaver -to detect hotplug events! - -Note that it's *not* an error to give nonexistent joystick device names. -unsaver will wait for devices to come into existence (e.g. as created -by **udev**). - If the screensaver is configured to lock the screen, and it has already -done so, pressing a joystick button/direction will just bring up the -password dialog, same as pressing a key or mouse button would. +done so, unsaver can't magically type your password for you. unsaver 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 @@ -140,16 +127,46 @@ server documentation to find out how to enable XTest. The fullscreen window monitoring has only been tested on a system with a single monitor, and may not work properly in multi-head environments. +JOYSTICK DEVICES +================ + +It's recommended to let unsaver find the joysticks itself. However, you +can pass one or more joystick numbers if the default doesn't do the right +thing for you. Remember that the first joystick is numbered 0, not 1. + +When you manually set the list of devices, unsaver will only detect +hotplug events on the devices you gave it. If you plug in more joysticks, +they won't be monitored. + +None of the joystick devices (whether autodetected or not) has to +actually exist when unsaver starts up, although their directory does +have to exist. This means unsaver can detect hotplug events, but you +have to be careful not to typo the device names. + +If your system doesn't keep its joystick device nodes in /dev/input, and/or +if they're not named "js<num>", see ENVIRONMENT for a way to override +the default names. + +ENVIRONMENT +=========== + +UNSAVER_JS_DIR Path to joystick device nodes. If your OS keeps them + somewhere besides "/dev/input", set this variable. + +UNSAVER_JS_NODE Base name for joystick device nodes. "js" by default. + *Don't* set this to "event", unsaver doesn't speak the + full Linux event protocol. + EXIT STATUS =========== -Without the -D option, the exit status is 0 (success) if unsaver +Without the -d option, the exit status is 0 (success) if unsaver successfully forked into the background. A non-zero exit status means an error in the command line arguments, or else fork() failed. No daemon will be running in this case. -With the -D option, unsaver never exits until it's killed. +With the -d option, unsaver never exits until it's killed. BUGS ==== @@ -166,15 +183,19 @@ be a log file, or use syslog (or is that overkill?). It should be (but currently isn't) possible to at least work in mouse-motion mode even without the XTest extension, via XWarpPointer(). +I *really* need to use the XKB extension rather than the old & deprecated +Xlib keyboard API. This mainly affects the default "find an unused +keycode" mode. + unsaver isn't portable. It only works on Linux, at least for now, for three reasons: -- It uses the Linux joystick API. + - It uses the Linux joystick API. -- It uses inotify(7) to detect joystick hotplug events. + - It uses inotify(7) to detect joystick hotplug events. -- I haven't even looked at other OSes to see if it would be possible - to port the code. + - I haven't even looked at other OSes to see if it would be possible + to port the code. .. EXAMPLES .. ======== |