diff options
author | B. Watson <yalhcru@gmail.com> | 2020-05-18 23:59:51 -0400 |
---|---|---|
committer | B. Watson <yalhcru@gmail.com> | 2020-05-18 23:59:51 -0400 |
commit | 005fc7dcf69fc112b5ce3d2c4017769cd8e425e8 (patch) | |
tree | 88b902b56f30ed80e4ffd0f7dbeeaf62da6cfcaf | |
parent | 045f4601b352abc2955050bd273b46ad602f3bad (diff) | |
download | unsaver-005fc7dcf69fc112b5ce3d2c4017769cd8e425e8.tar.gz |
detect fullscreen windows (-f/-F)
-rw-r--r-- | jsmond.1 | 20 | ||||
-rw-r--r-- | jsmond.c | 123 | ||||
-rw-r--r-- | jsmond.html | 21 | ||||
-rw-r--r-- | jsmond.rst | 20 |
4 files changed, 134 insertions, 50 deletions
@@ -36,11 +36,12 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] . .SH SYNOPSIS .sp -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] +jsmond [\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] .SH DESCRIPTION .sp -jsmond lets you play games with your joysticks/gamepads without -the screen saver activating due to lack of keyboard/mouse input. +jsmond lets you play games with your joysticks/gamepads without the screen +saver activating due to lack of keyboard/mouse input. It can also prevent +the screensaver from activating when a fullscreen window is in use. .sp Multiple joystick devices can be monitored. By default, jsmond monitors up to 16 devices, named /dev/input/js0 through js15. @@ -96,18 +97,20 @@ to its starting point. .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. +to set \fIinterval\fP to at least 1 second when using this +option, to avoid excess process\-spawning overhead. .TP .B \-x Same as \fB\-c "xscreensaver\-command \-deactivate" \-i 1s\fP\&. .TP .B \-f -Disable screensaver if a full\-screen window is detected. -This isn\(aqt likely to be 100% reliable. +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 @@ -157,6 +160,9 @@ password dialog, same as pressing a key or mouse button would. 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. +.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 EXIT STATUS .sp Without the \-D option, the exit status is 0 (success) if jsmond @@ -52,6 +52,8 @@ 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 */ /* joystick stuff */ char *joynames[MAX_STICKS + 1]; @@ -260,45 +262,90 @@ void check_inotify() { } } +int get_joystick_activity(void) { + struct js_event e; + int i, active = 0; + + for(i = 0; i < last_joyname; i++) { + if(joyfds[i] < 0) continue; + + if(debug) fprintf(stderr, "reading device %d, fd %d\n", i, joyfds[i]); + + /* count events. any we get here *should* be real, but it doesn't + hurt to mask out synthetic ones again */ + while(read(joyfds[i], &e, sizeof(e)) > 0) { + if(!(e.type & JS_EVENT_INIT)) active++; + } + + /* EAGAIN just means there are no more events to read. + anything else is a problem, though not fatal */ + if(errno != EAGAIN) { + if(debug) fprintf(stderr, "got error on device %d: %s\n", i, strerror(errno)); + } + } + + return active; +} + +int have_fullscreen_window(void) { + Window w; + XWindowAttributes w_attrs, root_attrs; + int revert_to; + + /* TODO: error check? */ + XGetInputFocus(xdisp, &w, &revert_to); + + if(w != None) { + XGetWindowAttributes(xdisp, DefaultRootWindow(xdisp), &root_attrs); + XGetWindowAttributes(xdisp, w, &w_attrs); + + /* + fprintf(stderr, "window id %d has focus, geometry %dx%d\n", + (int)w, w_attrs.width, w_attrs.height); + */ + + if( (w_attrs.map_state == IsViewable) && + (root_attrs.width == w_attrs.width) && + (root_attrs.height == w_attrs.height) ) + { + if(debug) fprintf(stderr, + "window id 0x%x has input focus and looks fullscreen (%dx%d)\n", + (int)w, w_attrs.width, w_attrs.height); + return 1; + } + } + + return 0; +} + /* this is the point of no return. the only way out of main_loop() is process death. */ void main_loop(void) { - struct js_event e; - int i, active, sleep_us; - - fprintf(stderr, "entering main_loop()\n"); + int sleep_us; sleep_us = interval * 1000; + fprintf(stderr, "entering main_loop(), sleep_us %d\n", sleep_us); + while(1) { + int active = 0; + /* Xlib will obligingly kill us, if X goes away */ ping_x_server(); /* check_inotify() will close & reopen the joystick fds as needed */ - check_inotify(); + if(monitor_joysticks) + check_inotify(); /* let the fds gather events as we slumber */ if(debug) fprintf(stderr, "sleeping %dms...\n", interval); usleep(sleep_us); /* now see if any of them got any events while we took a nap */ - active = 0; - for(i = 0; i < last_joyname; i++) { - if(joyfds[i] < 0) continue; - - if(debug) fprintf(stderr, "reading device %d, fd %d\n", i, joyfds[i]); + if(monitor_joysticks) + active += get_joystick_activity(); - /* count events. any we get here *should* be real, but it doesn't - hurt to mask out synthetic ones again */ - while(read(joyfds[i], &e, sizeof(e)) > 0) { - if(!(e.type & JS_EVENT_INIT)) active++; - } - - /* EAGAIN just means there are no more events to read. - anything else is a problem, though not fatal */ - if(errno != EAGAIN) { - if(debug) fprintf(stderr, "got error on device %d: %s\n", i, strerror(errno)); - } - } + if(monitor_fullscreen) + active += have_fullscreen_window(); /* if we got any activity on any of the fds, do our thing */ if(active) { @@ -474,9 +521,10 @@ void parse_args(int argc, char **argv) { set_fake_mode(fm_cmd); c_command = X_COMMAND; break; - case 'f': case 'F': - die("-f and -F not yet implemented"); + monitor_joysticks = 0; /* and fall thru */ + case 'f': + monitor_fullscreen = 1; break; default: die("unrecognized argument, try --help"); @@ -640,16 +688,35 @@ void init_x(void) { send_fake_x_event(); } +void print_banner() { + const char *m; + + if(monitor_joysticks && monitor_fullscreen) { + m = "joysticks and fullscreen"; + } else if(monitor_joysticks) { + m = "joysticks only"; + } else if(monitor_fullscreen) { + m = "fullscreen only"; + } else { + die("nothing to monitor!"); + } + + fprintf(stderr, "%s: v%s monitoring %s, interval %dms\n", + self, VERSION, m, interval); +} + int main(int argc, char **argv) { set_exe_name(argv[0]); parse_args(argc, argv); - if(autodiscover) populate_joynames(); + print_banner(); - init_joysticks(); - - init_inotify(); + if(monitor_joysticks) { + if(autodiscover) populate_joynames(); + init_joysticks(); + init_inotify(); + } init_x(); diff --git a/jsmond.html b/jsmond.html index 4f5d91c..2874b25 100644 --- a/jsmond.html +++ b/jsmond.html @@ -382,12 +382,13 @@ ul.auto-toc { <!-- rst2man.py jsmond.rst > jsmond.1 --> <div class="section" id="synopsis"> <h1>SYNOPSIS</h1> -<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> +<p>jsmond [<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> </div> <div class="section" id="description"> <h1>DESCRIPTION</h1> -<p>jsmond lets you play games with your joysticks/gamepads without -the screen saver activating due to lack of keyboard/mouse input.</p> +<p>jsmond lets you play games with your joysticks/gamepads without the screen +saver activating due to lack of keyboard/mouse input. It can also prevent +the screensaver from activating when a fullscreen window is in use.</p> <p>Multiple joystick devices can be monitored. By default, jsmond monitors up to 16 devices, named /dev/input/js0 through js15. These devices don't have to actually exist: they can come and go @@ -444,18 +445,20 @@ to its starting point.</td></tr> <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> +to set <em>interval</em> to at least 1 second when using this +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>Disable screensaver if a full-screen window is detected. -This isn't likely to be 100% reliable.</td></tr> +<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.</td></tr> +<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 @@ -504,6 +507,8 @@ 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> +<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="exit-status"> <h1>EXIT STATUS</h1> @@ -20,13 +20,14 @@ deactivate screensaver on joystick activity SYNOPSIS ======== -jsmond [**-i interval[s|ms]**] [**-m** | **-k keycode** | **-b button**] [**-d dir**] [**-j name**] [**-D**] [**joydev [joydev ...]**] +jsmond [**-i interval[s|ms]**] [**-m** | **-k keycode** | **-b button** | **-c command** | **-x** ] [**-d dir**] [**-j name**] [**-f**] [**-F**] [**-D**] [**joydev [joydev ...]**] DESCRIPTION =========== -jsmond lets you play games with your joysticks/gamepads without -the screen saver activating due to lack of keyboard/mouse input. +jsmond lets you play games with your joysticks/gamepads without the screen +saver activating due to lack of keyboard/mouse input. It can also prevent +the screensaver from activating when a fullscreen window is in use. Multiple joystick devices can be monitored. By default, jsmond monitors up to 16 devices, named /dev/input/js0 through js15. @@ -77,15 +78,17 @@ OPTIONS -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. + to set *interval* to at least 1 second when using this + option, to avoid excess process-spawning overhead. -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 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: @@ -132,6 +135,9 @@ 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. +The fullscreen window monitoring has only been tested on a system with +a single monitor, and may not work properly in multi-head environments. + EXIT STATUS =========== |