@@ -45,7 +45,6 @@ limitations under the License.
4545#endif
4646#ifdef HAVE_XCOMPOSITE_EXT
4747#include <X11/extensions/Xcomposite.h> // for XCompositeGetOverlayWindow
48-
4948#include "incompatible_compositor.xbm" // for incompatible_compositor_bits
5049#endif
5150#ifdef HAVE_XSCREENSAVER_EXT
@@ -75,7 +74,7 @@ limitations under the License.
7574 *
7675 * This defines the minimum frequency to call WatchChildren().
7776 */
78- #define WATCH_CHILDREN_HZ 10
77+ #define WATCH_CHILDREN_HZ 1
7978
8079/*! \brief Try to reinstate grabs in regular intervals.
8180 *
@@ -143,115 +142,12 @@ int have_switch_user_command = 0;
143142int force_grab = 0 ;
144143//! If set, print window info about any "conflicting" windows to stderr.
145144int debug_window_info = 0 ;
146- //! If nonnegative, the time in seconds till we blank the screen explicitly.
147- int blank_timeout = -1 ;
148- //! The DPMS state to switch the screen to when blanking.
149- const char * blank_dpms_state = "off" ;
150145//! Whether to reset the saver module when auth closes.
151146int saver_reset_on_auth_close = 0 ;
152147
153148//! The PID of a currently running notify command, or 0 if none is running.
154149pid_t notify_command_pid = 0 ;
155150
156- //! The time when we will blank the screen.
157- struct timeval time_to_blank ;
158-
159- //! Whether the screen is currently blanked by us.
160- int blanked = 0 ;
161-
162- #ifdef HAVE_DPMS_EXT
163- //! Whether DPMS needs to be disabled when unblanking. Set when blanking.
164- int must_disable_dpms = 0 ;
165- #endif
166-
167- void ResetBlankScreenTimer (void ) {
168- if (blank_timeout < 0 ) {
169- return ;
170- }
171- gettimeofday (& time_to_blank , NULL );
172- time_to_blank .tv_sec += blank_timeout ;
173- }
174-
175- void InitBlankScreen (void ) {
176- if (blank_timeout < 0 ) {
177- return ;
178- }
179- blanked = 0 ;
180- ResetBlankScreenTimer ();
181- }
182-
183- void MaybeBlankScreen (Display * display ) {
184- if (blank_timeout < 0 || blanked ) {
185- return ;
186- }
187- struct timeval now ;
188- gettimeofday (& now , NULL );
189- if (now .tv_sec < time_to_blank .tv_sec ||
190- (now .tv_sec == time_to_blank .tv_sec &&
191- now .tv_usec < time_to_blank .tv_usec )) {
192- return ;
193- }
194- // Blank timer expired - blank the screen.
195- blanked = 1 ;
196- XForceScreenSaver (display , ScreenSaverActive );
197- if (!strcmp (blank_dpms_state , "on" )) {
198- // Just X11 blanking.
199- goto done ;
200- }
201- #ifdef HAVE_DPMS_EXT
202- // If we get here, we want to do DPMS blanking.
203- int dummy ;
204- if (!DPMSQueryExtension (display , & dummy , & dummy )) {
205- Log ("DPMS is unavailable and XSECURELOCK_BLANK_DPMS_STATE not on" );
206- goto done ;
207- }
208- CARD16 state ;
209- BOOL onoff ;
210- DPMSInfo (display , & state , & onoff );
211- if (!onoff ) {
212- // DPMS not active by user - so we gotta force it.
213- must_disable_dpms = 1 ;
214- DPMSEnable (display );
215- }
216- if (!strcmp (blank_dpms_state , "standby" )) {
217- DPMSForceLevel (display , DPMSModeStandby );
218- } else if (!strcmp (blank_dpms_state , "suspend" )) {
219- DPMSForceLevel (display , DPMSModeSuspend );
220- } else if (!strcmp (blank_dpms_state , "off" )) {
221- DPMSForceLevel (display , DPMSModeOff );
222- } else {
223- Log ("XSECURELOCK_BLANK_DPMS_STATE not in standby/suspend/off/on" );
224- }
225- #else
226- Log ("DPMS is not compiled in and XSECURELOCK_BLANK_DPMS_STATE not on" );
227- #endif
228- done :
229- // Flush the output buffer so we turn off the display now and not a few ms
230- // later.
231- XFlush (display );
232- }
233-
234- void ScreenNoLongerBlanked (Display * display ) {
235- #ifdef HAVE_DPMS_EXT
236- if (must_disable_dpms ) {
237- DPMSDisable (display );
238- must_disable_dpms = 0 ;
239- // Flush the output buffer so we turn on the display now and not a
240- // few ms later. Makes our and X11's idle timer more consistent.
241- XFlush (display );
242- }
243- #endif
244- blanked = 0 ;
245- }
246-
247- void UnblankScreen (Display * display ) {
248- if (blanked ) {
249- XForceScreenSaver (display , ScreenSaverReset );
250- ScreenNoLongerBlanked (display );
251- }
252- ResetBlankScreenTimer ();
253- }
254-
255151static void HandleSIGTERM (int signo ) {
256152 KillAllSaverChildrenSigHandler (signo ); // Dirty, but quick.
257153 KillAuthChildSigHandler (signo ); // More dirty.
@@ -319,18 +215,34 @@ int WatchChildren(Display *dpy, Window auth_win, Window saver_win,
319215 WatchSaverChild (dpy , saver_win , 0 , saver_executable ,
320216 state != WATCH_CHILDREN_SAVER_DISABLED );
321217
322- if (auth_running ) {
323- // While auth is running, we never blank.
324- UnblankScreen (dpy );
325- } else {
326- // If no auth is running, permit blanking as per timer.
327- MaybeBlankScreen (dpy );
328- }
329-
330218 // Do not terminate the screen lock.
331219 return 0 ;
332220}
333221
222+ /*! \brief Check if screen is blanked by DPMS.
223+ *
224+ * \return If true, the screen is blanked by DPMS.
225+ */
226+ int IsBlankedByDPMS (Display * dpy ) {
227+ #if HAVE_DPMS_EXT
228+ static Bool DPMSExtensionAvailable = -1 ;
229+ if (DPMSExtensionAvailable == -1 ) {
230+ int dummy ;
231+ DPMSExtensionAvailable = (DPMSQueryExtension (dpy , & dummy , & dummy ) != 0 );
232+ }
233+ if (!DPMSExtensionAvailable ) {
234+ return 0 ;
235+ }
236+ /* There is no DPMSSelectInput, so we need to poll */
237+ CARD16 dpms_state ;
238+ BOOL dpms_enabled ;
239+ if (DPMSInfo (dpy , & dpms_state , & dpms_enabled )) {
240+ return (dpms_enabled && dpms_state != DPMSModeOn );
241+ }
242+ #endif
243+ return 0 ;
244+ }
245+
334246/*! \brief Wake up the screen saver in response to a keyboard or mouse event.
335247 *
336248 * \return If true, authentication was successful, and the program should exit.
@@ -425,8 +337,6 @@ void LoadDefaults() {
425337 * GetStringSetting ("XSECURELOCK_SWITCH_USER_COMMAND" , "" );
426338 force_grab = GetIntSetting ("XSECURELOCK_FORCE_GRAB" , 0 );
427339 debug_window_info = GetIntSetting ("XSECURELOCK_DEBUG_WINDOW_INFO" , 0 );
428- blank_timeout = GetIntSetting ("XSECURELOCK_BLANK_TIMEOUT" , 600 );
429- blank_dpms_state = GetStringSetting ("XSECURELOCK_BLANK_DPMS_STATE" , "off" );
430340 saver_reset_on_auth_close =
431341 GetIntSetting ("XSECURELOCK_SAVER_RESET_ON_AUTH_CLOSE" , 0 );
432342}
@@ -1091,13 +1001,12 @@ int main(int argc, char **argv) {
10911001 // Need to flush the display so savers sure can access the window.
10921002 XFlush (display );
10931003
1094- // Figure out the initial Xss saver state. This gets updated by event.
10951004 enum WatchChildrenState xss_requested_saver_state = WATCH_CHILDREN_NORMAL ;
10961005#ifdef HAVE_XSCREENSAVER_EXT
10971006 if (scrnsaver_event_base != 0 ) {
10981007 XScreenSaverInfo * info = XScreenSaverAllocInfo ();
10991008 XScreenSaverQueryInfo (display , root_window , info );
1100- if (info -> state == ScreenSaverOn ) {
1009+ if (info -> state == ScreenSaverOn && info -> kind == ScreenSaverBlanked ) {
11011010 xss_requested_saver_state = WATCH_CHILDREN_SAVER_DISABLED ;
11021011 }
11031012 XFree (info );
@@ -1112,8 +1021,6 @@ int main(int argc, char **argv) {
11121021 xss_sleep_lock_fd = -1 ;
11131022 }
11141023
1115- InitBlankScreen ();
1116-
11171024 int background_window_mapped = 0 , background_window_visible = 0 ,
11181025 auth_window_mapped = 0 , saver_window_mapped = 0 ,
11191026 need_to_reinstate_grabs = 0 , xss_lock_notified = 0 ;
@@ -1129,8 +1036,8 @@ int main(int argc, char **argv) {
11291036 select (x11_fd + 1 , & in_fds , 0 , 0 , & tv );
11301037
11311038 // Make sure to shut down the saver when blanked. Saves power.
1132- enum WatchChildrenState requested_saver_state =
1133- blanked ? WATCH_CHILDREN_SAVER_DISABLED : xss_requested_saver_state ;
1039+ enum WatchChildrenState requested_saver_state = IsBlankedByDPMS ( display ) ?
1040+ WATCH_CHILDREN_SAVER_DISABLED : xss_requested_saver_state ;
11341041
11351042 // Now check status of our children.
11361043 if (WatchChildren (display , auth_window , saver_window , requested_saver_state ,
@@ -1270,14 +1177,12 @@ int main(int argc, char **argv) {
12701177 case MotionNotify :
12711178 case ButtonPress :
12721179 // Mouse events launch the auth child.
1273- ScreenNoLongerBlanked (display );
12741180 if (WakeUp (display , auth_window , saver_window , NULL )) {
12751181 goto done ;
12761182 }
12771183 break ;
12781184 case KeyPress : {
12791185 // Keyboard events launch the auth child.
1280- ScreenNoLongerBlanked (display );
12811186 Status status = XLookupNone ;
12821187 int have_key = 1 ;
12831188 int do_wake_up = 1 ;
@@ -1375,9 +1280,6 @@ int main(int argc, char **argv) {
13751280 } break ;
13761281 case KeyRelease :
13771282 case ButtonRelease :
1378- // Known to wake up screen blanking.
1379- ScreenNoLongerBlanked (display );
1380- break ;
13811283 case MappingNotify :
13821284 case EnterNotify :
13831285 case LeaveNotify :
@@ -1493,7 +1395,7 @@ int main(int argc, char **argv) {
14931395 priv .ev .type == scrnsaver_event_base + ScreenSaverNotify ) {
14941396 XScreenSaverNotifyEvent * xss_ev =
14951397 (XScreenSaverNotifyEvent * )& priv .ev ;
1496- if (xss_ev -> state == ScreenSaverOn ) {
1398+ if (xss_ev -> state == ScreenSaverOn && xss_ev -> kind == ScreenSaverBlanked ) {
14971399 xss_requested_saver_state = WATCH_CHILDREN_SAVER_DISABLED ;
14981400 } else {
14991401 xss_requested_saver_state = WATCH_CHILDREN_NORMAL ;
@@ -1513,8 +1415,6 @@ int main(int argc, char **argv) {
15131415 }
15141416
15151417done :
1516- // Make sure no DPMS changes persist.
1517- UnblankScreen (display );
15181418
15191419 if (previous_focused_window != None ) {
15201420 XSetErrorHandler (SilentlyIgnoreErrorsHandler );
0 commit comments