diff options
Diffstat (limited to 'driver/windows.c')
-rw-r--r-- | driver/windows.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/driver/windows.c b/driver/windows.c index 9e47c45..5854c49 100644 --- a/driver/windows.c +++ b/driver/windows.c @@ -35,6 +35,7 @@ #include <X11/Xutil.h> /* for XSetClassHint() */ #include <X11/Xatom.h> #include <X11/Xos.h> /* for time() */ +#include <X11/extensions/scrnsaver.h> #include <signal.h> /* for the signal names */ #include <time.h> #include <sys/time.h> @@ -235,7 +236,7 @@ ungrab_keyboard_and_mouse (saver_info *si) static Bool -grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, +grab_keyboard_and_mouse_real (saver_info *si, Window window, Cursor cursor, int screen_no) { Status mstatus = 0, kstatus = 0; @@ -320,6 +321,32 @@ grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, } +static Bool +grab_keyboard_and_mouse (saver_info *si, Window window, Cursor cursor, + int screen_no) +{ + Bool ret; + char *euc = si->prefs.external_ungrab_command; + char cmd[200]; + if (euc && *euc) + { + snprintf (cmd, sizeof(cmd), "%s %s", euc, "pre"); + exec_and_wait (si, cmd); + } + ret = grab_keyboard_and_mouse_real (si, window, cursor, screen_no); + if (euc && *euc) + { + snprintf (cmd, sizeof(cmd), "%s %s", euc, "post"); + exec_and_wait (si, cmd); + if (ret) { + /* The external command might have generated some x/input events */ + flush_events (si); + } + } + return ret; +} + + int move_mouse_grab (saver_info *si, Window to, Cursor cursor, int to_screen_no) { @@ -1639,6 +1666,17 @@ mouse_screen (saver_info *si) return 0; } +static int +get_idle_time (saver_info *si) +{ + int ret = 0; + XScreenSaverInfo *info; + info = XScreenSaverAllocInfo (); + if (info != NULL && XScreenSaverQueryInfo (si->dpy, DefaultRootWindow (si->dpy), info)) + ret = info->idle / 1000; + XFree (info); + return ret; +} Bool blank_screen (saver_info *si) @@ -1647,7 +1685,16 @@ blank_screen (saver_info *si) Bool ok; Window w; int mscreen; + int idle_s = 0; + Bool screen_on = True; + const char *euc = si->prefs.external_ungrab_command; + if (euc && *euc) + { + screen_on = monitor_powered_on_p (si); + if (screen_on) + idle_s = get_idle_time(si); + } /* Note: we do our grabs on the root window, not on the screensaver window. If we grabbed on the saver window, then the demo mode and lock dialog boxes wouldn't get any events. @@ -1679,6 +1726,31 @@ blank_screen (saver_info *si) if (!ok) return False; + if (euc && *euc) + { + /* ungrab hooks might have messed up idle time -- account for that. + this might look like the math is backwards, but this handles both + cases -- ungrab hook did mess up idle time, and ungrab hook + did *not* mess up idle time. In the latter case the value will be + zero or negative, so it gets clamped to zero. + */ + if (screen_on) + { + saver_preferences *p = &si->prefs; + store_dpms_offset (idle_s - get_idle_time(si)); + sync_server_dpms_settings (si->dpy, + (p->dpms_enabled_p && + p->mode != DONT_BLANK), + p->dpms_quickoff_p, + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); + } + else /* screen was off before, might have been turned on by fake events */ + monitor_power_on (si, False); + } + for (i = 0; i < si->nscreens; i++) { saver_screen_info *ssi = &si->screens[i]; @@ -1719,6 +1791,7 @@ unblank_screen (saver_info *si) Bool unfade_p = (si->fading_possible_p && p->unfade_p); int i; + store_dpms_offset (0); monitor_power_on (si, True); reset_watchdog_timer (si, False); |