xref: /haiku/src/bin/screen_blanker/ScreenBlanker.cpp (revision 1c776bfe37a7c1a382f9720112f19de00c7cff07)
17cae4a1eSAxel Dörfler /*
2e22c01afSJohn Scipione  * Copyright 2003-2013 Haiku, Inc. All rights reserved.
37cae4a1eSAxel Dörfler  * Distributed under the terms of the MIT License.
47cae4a1eSAxel Dörfler  *
57cae4a1eSAxel Dörfler  * Authors:
67cae4a1eSAxel Dörfler  *		Jérôme Duval, jerome.duval@free.fr
7af55bae2SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
8cb6a084fSRyan Leavengood  *		Ryan Leavengood, leavengood@gmail.com
9e22c01afSJohn Scipione  *		Michael Phipps
10e22c01afSJohn Scipione  *		John Scipione, jscipione@gmail.com
117cae4a1eSAxel Dörfler  */
127cae4a1eSAxel Dörfler 
137cae4a1eSAxel Dörfler 
147cae4a1eSAxel Dörfler #include "ScreenBlanker.h"
157cae4a1eSAxel Dörfler 
167cae4a1eSAxel Dörfler #include <Beep.h>
177cae4a1eSAxel Dörfler #include <Debug.h>
187cae4a1eSAxel Dörfler #include <File.h>
197cae4a1eSAxel Dörfler #include <FindDirectory.h>
207cae4a1eSAxel Dörfler #include <Path.h>
217cae4a1eSAxel Dörfler #include <Screen.h>
227cae4a1eSAxel Dörfler #include <StorageDefs.h>
237cae4a1eSAxel Dörfler #include <SupportDefs.h>
247cae4a1eSAxel Dörfler #include <image.h>
257cae4a1eSAxel Dörfler 
267cae4a1eSAxel Dörfler #include <stdio.h>
277cae4a1eSAxel Dörfler #include <string.h>
28af55bae2SAxel Dörfler #include <syslog.h>
297cae4a1eSAxel Dörfler 
307cae4a1eSAxel Dörfler 
31af55bae2SAxel Dörfler const static uint32 kMsgTurnOffScreen = 'tofs';
32af55bae2SAxel Dörfler const static uint32 kMsgSuspendScreen = 'suss';
33af55bae2SAxel Dörfler const static uint32 kMsgStandByScreen = 'stbs';
347cae4a1eSAxel Dörfler 
357cae4a1eSAxel Dörfler 
36e22c01afSJohn Scipione //	#pragma mark - ScreenBlanker
37e22c01afSJohn Scipione 
38e22c01afSJohn Scipione 
397cae4a1eSAxel Dörfler ScreenBlanker::ScreenBlanker()
40e22c01afSJohn Scipione 	:
41e22c01afSJohn Scipione 	BApplication(SCREEN_BLANKER_SIG),
427cae4a1eSAxel Dörfler 	fWindow(NULL),
43d34a680cSJohn Scipione 	fSaverRunner(NULL),
447cae4a1eSAxel Dörfler 	fPasswordWindow(NULL),
45af55bae2SAxel Dörfler 	fResumeRunner(NULL),
46af55bae2SAxel Dörfler 	fStandByScreenRunner(NULL),
47af55bae2SAxel Dörfler 	fSuspendScreenRunner(NULL),
48af55bae2SAxel Dörfler 	fTurnOffScreenRunner(NULL)
497cae4a1eSAxel Dörfler {
507cae4a1eSAxel Dörfler 	fBlankTime = system_time();
517cae4a1eSAxel Dörfler }
527cae4a1eSAxel Dörfler 
537cae4a1eSAxel Dörfler 
547cae4a1eSAxel Dörfler ScreenBlanker::~ScreenBlanker()
557cae4a1eSAxel Dörfler {
567cae4a1eSAxel Dörfler 	delete fResumeRunner;
57af55bae2SAxel Dörfler 	_TurnOnScreen();
587cae4a1eSAxel Dörfler }
597cae4a1eSAxel Dörfler 
607cae4a1eSAxel Dörfler 
617cae4a1eSAxel Dörfler void
627cae4a1eSAxel Dörfler ScreenBlanker::ReadyToRun()
637cae4a1eSAxel Dörfler {
64e22c01afSJohn Scipione 	if (!fSettings.Load())
65cb6a084fSRyan Leavengood 		fprintf(stderr, "could not load settings, using defaults\n");
667cae4a1eSAxel Dörfler 
677cae4a1eSAxel Dörfler 	// create a BDirectWindow and start the render thread.
68af55bae2SAxel Dörfler 	// TODO: we need a window per screen...
697cae4a1eSAxel Dörfler 	BScreen screen(B_MAIN_SCREEN_ID);
707cae4a1eSAxel Dörfler 	fWindow = new ScreenSaverWindow(screen.Frame());
717cae4a1eSAxel Dörfler 	fPasswordWindow = new PasswordWindow();
727cae4a1eSAxel Dörfler 
73d34a680cSJohn Scipione 	BView* view = fWindow->ChildAt(0);
74*1c776bfeSJohn Scipione 	fSaverRunner = new ScreenSaverRunner(fWindow, view, fSettings);
75d34a680cSJohn Scipione 	fWindow->SetSaverRunner(fSaverRunner);
76d34a680cSJohn Scipione 
77d34a680cSJohn Scipione 	BScreenSaver* saver = fSaverRunner->ScreenSaver();
78d34a680cSJohn Scipione 	if (saver != NULL && saver->StartSaver(view, false) == B_OK)
79d34a680cSJohn Scipione 		fSaverRunner->Run();
80d34a680cSJohn Scipione 	else {
817cae4a1eSAxel Dörfler 		fprintf(stderr, "could not load the screensaver addon\n");
82d34a680cSJohn Scipione 		view->SetViewColor(0, 0, 0);
83d34a680cSJohn Scipione 			// needed for Blackness saver
847cae4a1eSAxel Dörfler 	}
857cae4a1eSAxel Dörfler 
867cae4a1eSAxel Dörfler 	fWindow->SetFullScreen(true);
877cae4a1eSAxel Dörfler 	fWindow->Show();
887cae4a1eSAxel Dörfler 	HideCursor();
89af55bae2SAxel Dörfler 
90af55bae2SAxel Dörfler 	_QueueTurnOffScreen();
91af55bae2SAxel Dörfler }
92af55bae2SAxel Dörfler 
93af55bae2SAxel Dörfler 
94af55bae2SAxel Dörfler void
95af55bae2SAxel Dörfler ScreenBlanker::_TurnOnScreen()
96af55bae2SAxel Dörfler {
97af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
98af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
99af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
100af55bae2SAxel Dörfler 
101af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
102af55bae2SAxel Dörfler 
103af55bae2SAxel Dörfler 	BScreen screen;
104af55bae2SAxel Dörfler 	screen.SetDPMS(B_DPMS_ON);
105af55bae2SAxel Dörfler }
106af55bae2SAxel Dörfler 
107af55bae2SAxel Dörfler 
108af55bae2SAxel Dörfler void
109af55bae2SAxel Dörfler ScreenBlanker::_SetDPMSMode(uint32 mode)
110af55bae2SAxel Dörfler {
111af55bae2SAxel Dörfler 	BScreen screen;
112af55bae2SAxel Dörfler 	screen.SetDPMS(mode);
113af55bae2SAxel Dörfler 
114af55bae2SAxel Dörfler 	if (fWindow->Lock()) {
115d34a680cSJohn Scipione 		fSaverRunner->Suspend();
116af55bae2SAxel Dörfler 		fWindow->Unlock();
117af55bae2SAxel Dörfler 	}
1187cae4a1eSAxel Dörfler }
1197cae4a1eSAxel Dörfler 
1207cae4a1eSAxel Dörfler 
1217cae4a1eSAxel Dörfler void
1227cae4a1eSAxel Dörfler ScreenBlanker::_ShowPasswordWindow()
1237cae4a1eSAxel Dörfler {
124af55bae2SAxel Dörfler 	_TurnOnScreen();
125af55bae2SAxel Dörfler 
1267cae4a1eSAxel Dörfler 	if (fWindow->Lock()) {
127d34a680cSJohn Scipione 		fSaverRunner->Suspend();
1287cae4a1eSAxel Dörfler 
1297cae4a1eSAxel Dörfler 		fWindow->Sync();
1307cae4a1eSAxel Dörfler 			// TODO: is that needed?
1317cae4a1eSAxel Dörfler 		ShowCursor();
132cb6a084fSRyan Leavengood 		if (fPasswordWindow->IsHidden())
1337cae4a1eSAxel Dörfler 			fPasswordWindow->Show();
134310a9c9eSAxel Dörfler 
1357cae4a1eSAxel Dörfler 		fWindow->Unlock();
1367cae4a1eSAxel Dörfler 	}
1377cae4a1eSAxel Dörfler 
138af55bae2SAxel Dörfler 	_QueueResumeScreenSaver();
1397cae4a1eSAxel Dörfler }
1407cae4a1eSAxel Dörfler 
1417cae4a1eSAxel Dörfler 
1427cae4a1eSAxel Dörfler void
143af55bae2SAxel Dörfler ScreenBlanker::_QueueResumeScreenSaver()
1447cae4a1eSAxel Dörfler {
1457cae4a1eSAxel Dörfler 	delete fResumeRunner;
146d0e9fa68SAxel Dörfler 
147d0e9fa68SAxel Dörfler 	BMessage resume(kMsgResumeSaver);
148d0e9fa68SAxel Dörfler 	fResumeRunner = new BMessageRunner(BMessenger(this), &resume,
14941158aafSAxel Dörfler 		fSettings.BlankTime(), 1);
150af55bae2SAxel Dörfler 	if (fResumeRunner->InitCheck() != B_OK)
151af55bae2SAxel Dörfler 		syslog(LOG_ERR, "resume screen saver runner failed\n");
152af55bae2SAxel Dörfler }
153af55bae2SAxel Dörfler 
154af55bae2SAxel Dörfler 
155af55bae2SAxel Dörfler void
156af55bae2SAxel Dörfler ScreenBlanker::_QueueTurnOffScreen()
157af55bae2SAxel Dörfler {
158af55bae2SAxel Dörfler 	// stop running notifiers
159af55bae2SAxel Dörfler 
160af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
161af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
162af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
163af55bae2SAxel Dörfler 
164af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
165af55bae2SAxel Dörfler 
166af55bae2SAxel Dörfler 	// figure out which notifiers we need and which of them are supported
167af55bae2SAxel Dörfler 
16841158aafSAxel Dörfler 	uint32 flags = fSettings.TimeFlags();
169af55bae2SAxel Dörfler 	BScreen screen;
170af55bae2SAxel Dörfler 	uint32 capabilities = screen.DPMSCapabilites();
171af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_OFF) == 0)
172f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_OFF;
173af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_SUSPEND) == 0)
174f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
175af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_STAND_BY) == 0)
176f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
177af55bae2SAxel Dörfler 
178af55bae2SAxel Dörfler 	if ((flags & ENABLE_DPMS_MASK) == 0)
179af55bae2SAxel Dörfler 		return;
180af55bae2SAxel Dörfler 
181f0d2e760SAxel Dörfler 	if (fSettings.OffTime() == fSettings.SuspendTime()
182e22c01afSJohn Scipione 		&& (flags & (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
183e22c01afSJohn Scipione 			== (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
184f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
185f0d2e760SAxel Dörfler 	if (fSettings.SuspendTime() == fSettings.StandByTime()
186e22c01afSJohn Scipione 		&& (flags & (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
187e22c01afSJohn Scipione 			== (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
188f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
189af55bae2SAxel Dörfler 
190af55bae2SAxel Dörfler 	// start them off again
191af55bae2SAxel Dörfler 
192af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_STAND_BY) {
193d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgStandByScreen);
194d0e9fa68SAxel Dörfler 		fStandByScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
195d0e9fa68SAxel Dörfler 			fSettings.StandByTime(), 1);
196af55bae2SAxel Dörfler 		if (fStandByScreenRunner->InitCheck() != B_OK)
197af55bae2SAxel Dörfler 			syslog(LOG_ERR, "standby screen saver runner failed\n");
198af55bae2SAxel Dörfler 	}
199af55bae2SAxel Dörfler 
200af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_SUSPEND) {
201d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgSuspendScreen);
202d0e9fa68SAxel Dörfler 		fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
203d0e9fa68SAxel Dörfler 			fSettings.SuspendTime(), 1);
204af55bae2SAxel Dörfler 		if (fSuspendScreenRunner->InitCheck() != B_OK)
205cb6a084fSRyan Leavengood 			syslog(LOG_ERR, "suspend screen saver runner failed\n");
206af55bae2SAxel Dörfler 	}
207af55bae2SAxel Dörfler 
208af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_OFF) {
209d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgTurnOffScreen);
210d0e9fa68SAxel Dörfler 		fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
211d0e9fa68SAxel Dörfler 			fSettings.OffTime(), 1);
212af55bae2SAxel Dörfler 		if (fTurnOffScreenRunner->InitCheck() != B_OK)
213af55bae2SAxel Dörfler 			syslog(LOG_ERR, "turn off screen saver runner failed\n");
2147cae4a1eSAxel Dörfler 	}
2157cae4a1eSAxel Dörfler }
2167cae4a1eSAxel Dörfler 
2177cae4a1eSAxel Dörfler 
2187cae4a1eSAxel Dörfler void
2197cae4a1eSAxel Dörfler ScreenBlanker::MessageReceived(BMessage* message)
2207cae4a1eSAxel Dörfler {
2217cae4a1eSAxel Dörfler 	switch (message->what) {
222af55bae2SAxel Dörfler 		case kMsgUnlock:
2237cae4a1eSAxel Dörfler 		{
22441158aafSAxel Dörfler 			if (strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(),
22541158aafSAxel Dörfler 					fSettings.Password())) != 0) {
2267cae4a1eSAxel Dörfler 				beep();
2277cae4a1eSAxel Dörfler 				fPasswordWindow->SetPassword("");
228af55bae2SAxel Dörfler 				_QueueResumeScreenSaver();
2297cae4a1eSAxel Dörfler 			} else  {
2307cae4a1eSAxel Dörfler 				PRINT(("Quitting!\n"));
2317cae4a1eSAxel Dörfler 				_Shutdown();
2327cae4a1eSAxel Dörfler 				Quit();
2337cae4a1eSAxel Dörfler 			}
2347cae4a1eSAxel Dörfler 			break;
2357cae4a1eSAxel Dörfler 		}
2367cae4a1eSAxel Dörfler 
237af55bae2SAxel Dörfler 		case kMsgResumeSaver:
238cb6a084fSRyan Leavengood 		{
2397cae4a1eSAxel Dörfler 			if (fWindow->Lock()) {
2407cae4a1eSAxel Dörfler 				HideCursor();
2410834f79cSRyan Leavengood 				fPasswordWindow->SetPassword("");
2427cae4a1eSAxel Dörfler 				fPasswordWindow->Hide();
2437cae4a1eSAxel Dörfler 
244d34a680cSJohn Scipione 				fSaverRunner->Resume();
2457cae4a1eSAxel Dörfler 				fWindow->Unlock();
2467cae4a1eSAxel Dörfler 			}
247af55bae2SAxel Dörfler 
248cb6a084fSRyan Leavengood 			// Turn on the message filter again
249cb6a084fSRyan Leavengood 			BMessage enable(kMsgEnableFilter);
250d39c5354SRyan Leavengood 			fWindow->PostMessage(&enable);
251cb6a084fSRyan Leavengood 
252af55bae2SAxel Dörfler 			_QueueTurnOffScreen();
253af55bae2SAxel Dörfler 			break;
254cb6a084fSRyan Leavengood 		}
255af55bae2SAxel Dörfler 
256af55bae2SAxel Dörfler 		case kMsgTurnOffScreen:
257af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_OFF);
258af55bae2SAxel Dörfler 			break;
259e22c01afSJohn Scipione 
260af55bae2SAxel Dörfler 		case kMsgSuspendScreen:
261af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_SUSPEND);
262af55bae2SAxel Dörfler 			break;
263e22c01afSJohn Scipione 
264af55bae2SAxel Dörfler 		case kMsgStandByScreen:
265af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_STAND_BY);
2667cae4a1eSAxel Dörfler 			break;
2677cae4a1eSAxel Dörfler 
2687cae4a1eSAxel Dörfler 		default:
2697cae4a1eSAxel Dörfler 			BApplication::MessageReceived(message);
2707cae4a1eSAxel Dörfler 	}
2717cae4a1eSAxel Dörfler }
2727cae4a1eSAxel Dörfler 
2737cae4a1eSAxel Dörfler 
2747cae4a1eSAxel Dörfler bool
2757cae4a1eSAxel Dörfler ScreenBlanker::QuitRequested()
2767cae4a1eSAxel Dörfler {
27741158aafSAxel Dörfler 	if (fSettings.LockEnable()
278e22c01afSJohn Scipione 		&& system_time() - fBlankTime > fSettings.PasswordTime()
279e22c01afSJohn Scipione 			- fSettings.BlankTime()) {
2807cae4a1eSAxel Dörfler 		_ShowPasswordWindow();
2817cae4a1eSAxel Dörfler 		return false;
2827cae4a1eSAxel Dörfler 	}
2837cae4a1eSAxel Dörfler 
2847cae4a1eSAxel Dörfler 	_Shutdown();
2857cae4a1eSAxel Dörfler 	return true;
2867cae4a1eSAxel Dörfler }
2877cae4a1eSAxel Dörfler 
2887cae4a1eSAxel Dörfler 
2890f1162d2SJohn Scipione bool
2900f1162d2SJohn Scipione ScreenBlanker::IsPasswordWindowShown() const
2910f1162d2SJohn Scipione {
2920f1162d2SJohn Scipione 	return fPasswordWindow != NULL && !fPasswordWindow->IsHidden();
2930f1162d2SJohn Scipione }
2940f1162d2SJohn Scipione 
2950f1162d2SJohn Scipione 
2967cae4a1eSAxel Dörfler void
2977cae4a1eSAxel Dörfler ScreenBlanker::_Shutdown()
2987cae4a1eSAxel Dörfler {
299e22c01afSJohn Scipione 	if (fWindow != NULL) {
3007cae4a1eSAxel Dörfler 		fWindow->Hide();
301d0e9fa68SAxel Dörfler 
302d0e9fa68SAxel Dörfler 		if (fWindow->Lock())
303d0e9fa68SAxel Dörfler 			fWindow->Quit();
304d0e9fa68SAxel Dörfler 	}
30552bc210dSKarsten Heimrich 
306d34a680cSJohn Scipione 	delete fSaverRunner;
307d34a680cSJohn Scipione 	fSaverRunner = NULL;
3087cae4a1eSAxel Dörfler }
3097cae4a1eSAxel Dörfler 
3107cae4a1eSAxel Dörfler 
311e22c01afSJohn Scipione //	#pragma mark - main
3127cae4a1eSAxel Dörfler 
3137cae4a1eSAxel Dörfler 
3147cae4a1eSAxel Dörfler int
315e22c01afSJohn Scipione main(int argc, char** argv)
3167cae4a1eSAxel Dörfler {
3177cae4a1eSAxel Dörfler 	ScreenBlanker app;
3187cae4a1eSAxel Dörfler 	app.Run();
319e22c01afSJohn Scipione 
3207cae4a1eSAxel Dörfler 	return 0;
3217cae4a1eSAxel Dörfler }
322