aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2020-05-18 23:59:51 -0400
committerB. Watson <yalhcru@gmail.com>2020-05-18 23:59:51 -0400
commit005fc7dcf69fc112b5ce3d2c4017769cd8e425e8 (patch)
tree88b902b56f30ed80e4ffd0f7dbeeaf62da6cfcaf
parent045f4601b352abc2955050bd273b46ad602f3bad (diff)
downloadunsaver-005fc7dcf69fc112b5ce3d2c4017769cd8e425e8.tar.gz
detect fullscreen windows (-f/-F)
-rw-r--r--jsmond.120
-rw-r--r--jsmond.c123
-rw-r--r--jsmond.html21
-rw-r--r--jsmond.rst20
4 files changed, 134 insertions, 50 deletions
diff --git a/jsmond.1 b/jsmond.1
index fc761bc..8b9513b 100644
--- a/jsmond.1
+++ b/jsmond.1
@@ -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
diff --git a/jsmond.c b/jsmond.c
index ca3c1a0..643287d 100644
--- a/jsmond.c
+++ b/jsmond.c
@@ -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>&lt;command&gt;</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 &quot;xscreensaver-command -deactivate&quot; -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 &quot;X server doesn't support XTest extension&quot; 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>
diff --git a/jsmond.rst b/jsmond.rst
index 89b47a6..4c0a38d 100644
--- a/jsmond.rst
+++ b/jsmond.rst
@@ -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
===========