aboutsummaryrefslogtreecommitdiff
path: root/jsmond.c
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 /jsmond.c
parent045f4601b352abc2955050bd273b46ad602f3bad (diff)
downloadunsaver-005fc7dcf69fc112b5ce3d2c4017769cd8e425e8.tar.gz
detect fullscreen windows (-f/-F)
Diffstat (limited to 'jsmond.c')
-rw-r--r--jsmond.c123
1 files changed, 95 insertions, 28 deletions
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();