From 005fc7dcf69fc112b5ce3d2c4017769cd8e425e8 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Mon, 18 May 2020 23:59:51 -0400 Subject: detect fullscreen windows (-f/-F) --- jsmond.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 28 deletions(-) (limited to 'jsmond.c') 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(); -- cgit v1.2.3