xref: /haiku/src/bin/screen_blanker/ScreenBlanker.cpp (revision 0834f79c8ce6e973204ff08a16ffaa3e97d8a1ff)
17cae4a1eSAxel Dörfler /*
2cb6a084fSRyan Leavengood  * Copyright 2003-2009, Haiku.
37cae4a1eSAxel Dörfler  * Distributed under the terms of the MIT License.
47cae4a1eSAxel Dörfler  *
57cae4a1eSAxel Dörfler  * Authors:
67cae4a1eSAxel Dörfler  *		Michael Phipps
77cae4a1eSAxel Dörfler  *		Jérôme Duval, jerome.duval@free.fr
8af55bae2SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
9cb6a084fSRyan Leavengood  *		Ryan Leavengood, leavengood@gmail.com
107cae4a1eSAxel Dörfler  */
117cae4a1eSAxel Dörfler 
127cae4a1eSAxel Dörfler 
137cae4a1eSAxel Dörfler #include "ScreenBlanker.h"
147cae4a1eSAxel Dörfler 
157cae4a1eSAxel Dörfler #include <Beep.h>
167cae4a1eSAxel Dörfler #include <Debug.h>
177cae4a1eSAxel Dörfler #include <File.h>
187cae4a1eSAxel Dörfler #include <FindDirectory.h>
197cae4a1eSAxel Dörfler #include <Path.h>
207cae4a1eSAxel Dörfler #include <Screen.h>
217cae4a1eSAxel Dörfler #include <StorageDefs.h>
227cae4a1eSAxel Dörfler #include <SupportDefs.h>
237cae4a1eSAxel Dörfler #include <image.h>
247cae4a1eSAxel Dörfler 
257cae4a1eSAxel Dörfler #include <stdio.h>
267cae4a1eSAxel Dörfler #include <string.h>
27af55bae2SAxel Dörfler #include <syslog.h>
287cae4a1eSAxel Dörfler 
297cae4a1eSAxel Dörfler 
30af55bae2SAxel Dörfler const static uint32 kMsgTurnOffScreen = 'tofs';
31af55bae2SAxel Dörfler const static uint32 kMsgSuspendScreen = 'suss';
32af55bae2SAxel Dörfler const static uint32 kMsgStandByScreen = 'stbs';
337cae4a1eSAxel Dörfler 
347cae4a1eSAxel Dörfler 
357cae4a1eSAxel Dörfler ScreenBlanker::ScreenBlanker()
367cae4a1eSAxel Dörfler 	: BApplication(SCREEN_BLANKER_SIG),
377cae4a1eSAxel Dörfler 	fWindow(NULL),
387cae4a1eSAxel Dörfler 	fSaver(NULL),
397cae4a1eSAxel Dörfler 	fRunner(NULL),
407cae4a1eSAxel Dörfler 	fPasswordWindow(NULL),
41af55bae2SAxel Dörfler 	fResumeRunner(NULL),
42af55bae2SAxel Dörfler 	fStandByScreenRunner(NULL),
43af55bae2SAxel Dörfler 	fSuspendScreenRunner(NULL),
44af55bae2SAxel Dörfler 	fTurnOffScreenRunner(NULL)
457cae4a1eSAxel Dörfler {
467cae4a1eSAxel Dörfler 	fBlankTime = system_time();
477cae4a1eSAxel Dörfler }
487cae4a1eSAxel Dörfler 
497cae4a1eSAxel Dörfler 
507cae4a1eSAxel Dörfler ScreenBlanker::~ScreenBlanker()
517cae4a1eSAxel Dörfler {
527cae4a1eSAxel Dörfler 	delete fResumeRunner;
53af55bae2SAxel Dörfler 	_TurnOnScreen();
547cae4a1eSAxel Dörfler }
557cae4a1eSAxel Dörfler 
567cae4a1eSAxel Dörfler 
577cae4a1eSAxel Dörfler void
587cae4a1eSAxel Dörfler ScreenBlanker::ReadyToRun()
597cae4a1eSAxel Dörfler {
60642090fdSAxel Dörfler 	if (!fSettings.Load()) {
61cb6a084fSRyan Leavengood 		fprintf(stderr, "could not load settings, using defaults\n");
627cae4a1eSAxel Dörfler 	}
637cae4a1eSAxel Dörfler 
647cae4a1eSAxel Dörfler 	// create a BDirectWindow and start the render thread.
65af55bae2SAxel Dörfler 	// TODO: we need a window per screen...
667cae4a1eSAxel Dörfler 	BScreen screen(B_MAIN_SCREEN_ID);
677cae4a1eSAxel Dörfler 	fWindow = new ScreenSaverWindow(screen.Frame());
687cae4a1eSAxel Dörfler 	fPasswordWindow = new PasswordWindow();
6941158aafSAxel Dörfler 	fRunner = new ScreenSaverRunner(fWindow, fWindow->ChildAt(0), false, fSettings);
707cae4a1eSAxel Dörfler 
717cae4a1eSAxel Dörfler 	fSaver = fRunner->ScreenSaver();
727cae4a1eSAxel Dörfler 	if (fSaver) {
737cae4a1eSAxel Dörfler 		fWindow->SetSaver(fSaver);
747cae4a1eSAxel Dörfler 		fRunner->Run();
757cae4a1eSAxel Dörfler 	} else {
767cae4a1eSAxel Dörfler 		fprintf(stderr, "could not load the screensaver addon\n");
777cae4a1eSAxel Dörfler 	}
787cae4a1eSAxel Dörfler 
797cae4a1eSAxel Dörfler 	fWindow->SetFullScreen(true);
807cae4a1eSAxel Dörfler 	fWindow->Show();
817cae4a1eSAxel Dörfler 	HideCursor();
82af55bae2SAxel Dörfler 
83af55bae2SAxel Dörfler 	_QueueTurnOffScreen();
84af55bae2SAxel Dörfler }
85af55bae2SAxel Dörfler 
86af55bae2SAxel Dörfler 
87af55bae2SAxel Dörfler void
88af55bae2SAxel Dörfler ScreenBlanker::_TurnOnScreen()
89af55bae2SAxel Dörfler {
90af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
91af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
92af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
93af55bae2SAxel Dörfler 
94af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
95af55bae2SAxel Dörfler 
96af55bae2SAxel Dörfler 	BScreen screen;
97af55bae2SAxel Dörfler 	screen.SetDPMS(B_DPMS_ON);
98af55bae2SAxel Dörfler }
99af55bae2SAxel Dörfler 
100af55bae2SAxel Dörfler 
101af55bae2SAxel Dörfler void
102af55bae2SAxel Dörfler ScreenBlanker::_SetDPMSMode(uint32 mode)
103af55bae2SAxel Dörfler {
104af55bae2SAxel Dörfler 	BScreen screen;
105af55bae2SAxel Dörfler 	screen.SetDPMS(mode);
106af55bae2SAxel Dörfler 
107af55bae2SAxel Dörfler 	if (fWindow->Lock()) {
108af55bae2SAxel Dörfler 		fRunner->Suspend();
109af55bae2SAxel Dörfler 		fWindow->Unlock();
110af55bae2SAxel Dörfler 	}
1117cae4a1eSAxel Dörfler }
1127cae4a1eSAxel Dörfler 
1137cae4a1eSAxel Dörfler 
1147cae4a1eSAxel Dörfler void
1157cae4a1eSAxel Dörfler ScreenBlanker::_ShowPasswordWindow()
1167cae4a1eSAxel Dörfler {
117af55bae2SAxel Dörfler 	_TurnOnScreen();
118af55bae2SAxel Dörfler 
1197cae4a1eSAxel Dörfler 	if (fWindow->Lock()) {
1207cae4a1eSAxel Dörfler 		fRunner->Suspend();
1217cae4a1eSAxel Dörfler 
1227cae4a1eSAxel Dörfler 		fWindow->Sync();
1237cae4a1eSAxel Dörfler 			// TODO: is that needed?
1247cae4a1eSAxel Dörfler 		ShowCursor();
125cb6a084fSRyan Leavengood 		if (fPasswordWindow->IsHidden())
1267cae4a1eSAxel Dörfler 			fPasswordWindow->Show();
127310a9c9eSAxel Dörfler 
1287cae4a1eSAxel Dörfler 		fWindow->Unlock();
1297cae4a1eSAxel Dörfler 	}
1307cae4a1eSAxel Dörfler 
131af55bae2SAxel Dörfler 	_QueueResumeScreenSaver();
1327cae4a1eSAxel Dörfler }
1337cae4a1eSAxel Dörfler 
1347cae4a1eSAxel Dörfler 
1357cae4a1eSAxel Dörfler void
136af55bae2SAxel Dörfler ScreenBlanker::_QueueResumeScreenSaver()
1377cae4a1eSAxel Dörfler {
1387cae4a1eSAxel Dörfler 	delete fResumeRunner;
139d0e9fa68SAxel Dörfler 
140d0e9fa68SAxel Dörfler 	BMessage resume(kMsgResumeSaver);
141d0e9fa68SAxel Dörfler 	fResumeRunner = new BMessageRunner(BMessenger(this), &resume,
14241158aafSAxel Dörfler 		fSettings.BlankTime(), 1);
143af55bae2SAxel Dörfler 	if (fResumeRunner->InitCheck() != B_OK)
144af55bae2SAxel Dörfler 		syslog(LOG_ERR, "resume screen saver runner failed\n");
145af55bae2SAxel Dörfler }
146af55bae2SAxel Dörfler 
147af55bae2SAxel Dörfler 
148af55bae2SAxel Dörfler void
149af55bae2SAxel Dörfler ScreenBlanker::_QueueTurnOffScreen()
150af55bae2SAxel Dörfler {
151af55bae2SAxel Dörfler 	// stop running notifiers
152af55bae2SAxel Dörfler 
153af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
154af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
155af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
156af55bae2SAxel Dörfler 
157af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
158af55bae2SAxel Dörfler 
159af55bae2SAxel Dörfler 	// figure out which notifiers we need and which of them are supported
160af55bae2SAxel Dörfler 
16141158aafSAxel Dörfler 	uint32 flags = fSettings.TimeFlags();
162af55bae2SAxel Dörfler 	BScreen screen;
163af55bae2SAxel Dörfler 	uint32 capabilities = screen.DPMSCapabilites();
164af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_OFF) == 0)
165f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_OFF;
166af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_SUSPEND) == 0)
167f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
168af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_STAND_BY) == 0)
169f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
170af55bae2SAxel Dörfler 
171af55bae2SAxel Dörfler 	if ((flags & ENABLE_DPMS_MASK) == 0)
172af55bae2SAxel Dörfler 		return;
173af55bae2SAxel Dörfler 
174f0d2e760SAxel Dörfler 	if (fSettings.OffTime() == fSettings.SuspendTime()
175d0eaec30SMichael Lotz 		&& (flags & (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND)) == (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
176f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
177f0d2e760SAxel Dörfler 	if (fSettings.SuspendTime() == fSettings.StandByTime()
178d0eaec30SMichael Lotz 		&& (flags & (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY)) == (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
179f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
180af55bae2SAxel Dörfler 
181af55bae2SAxel Dörfler 	// start them off again
182af55bae2SAxel Dörfler 
183af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_STAND_BY) {
184d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgStandByScreen);
185d0e9fa68SAxel Dörfler 		fStandByScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
186d0e9fa68SAxel Dörfler 			fSettings.StandByTime(), 1);
187af55bae2SAxel Dörfler 		if (fStandByScreenRunner->InitCheck() != B_OK)
188af55bae2SAxel Dörfler 			syslog(LOG_ERR, "standby screen saver runner failed\n");
189af55bae2SAxel Dörfler 	}
190af55bae2SAxel Dörfler 
191af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_SUSPEND) {
192d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgSuspendScreen);
193d0e9fa68SAxel Dörfler 		fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
194d0e9fa68SAxel Dörfler 			fSettings.SuspendTime(), 1);
195af55bae2SAxel Dörfler 		if (fSuspendScreenRunner->InitCheck() != B_OK)
196cb6a084fSRyan Leavengood 			syslog(LOG_ERR, "suspend screen saver runner failed\n");
197af55bae2SAxel Dörfler 	}
198af55bae2SAxel Dörfler 
199af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_OFF) {
200d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgTurnOffScreen);
201d0e9fa68SAxel Dörfler 		fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
202d0e9fa68SAxel Dörfler 			fSettings.OffTime(), 1);
203af55bae2SAxel Dörfler 		if (fTurnOffScreenRunner->InitCheck() != B_OK)
204af55bae2SAxel Dörfler 			syslog(LOG_ERR, "turn off screen saver runner failed\n");
2057cae4a1eSAxel Dörfler 	}
2067cae4a1eSAxel Dörfler }
2077cae4a1eSAxel Dörfler 
2087cae4a1eSAxel Dörfler 
2097cae4a1eSAxel Dörfler void
2107cae4a1eSAxel Dörfler ScreenBlanker::MessageReceived(BMessage* message)
2117cae4a1eSAxel Dörfler {
2127cae4a1eSAxel Dörfler 	switch (message->what) {
213af55bae2SAxel Dörfler 		case kMsgUnlock:
2147cae4a1eSAxel Dörfler 		{
21541158aafSAxel Dörfler 			if (strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(),
21641158aafSAxel Dörfler 					fSettings.Password())) != 0) {
2177cae4a1eSAxel Dörfler 				beep();
2187cae4a1eSAxel Dörfler 				fPasswordWindow->SetPassword("");
219af55bae2SAxel Dörfler 				_QueueResumeScreenSaver();
2207cae4a1eSAxel Dörfler 			} else  {
2217cae4a1eSAxel Dörfler 				PRINT(("Quitting!\n"));
2227cae4a1eSAxel Dörfler 				_Shutdown();
2237cae4a1eSAxel Dörfler 				Quit();
2247cae4a1eSAxel Dörfler 			}
2257cae4a1eSAxel Dörfler 			break;
2267cae4a1eSAxel Dörfler 		}
2277cae4a1eSAxel Dörfler 
228af55bae2SAxel Dörfler 		case kMsgResumeSaver:
229cb6a084fSRyan Leavengood 		{
2307cae4a1eSAxel Dörfler 			if (fWindow->Lock()) {
2317cae4a1eSAxel Dörfler 				HideCursor();
232*0834f79cSRyan Leavengood 				fPasswordWindow->SetPassword("");
2337cae4a1eSAxel Dörfler 				fPasswordWindow->Hide();
2347cae4a1eSAxel Dörfler 
2357cae4a1eSAxel Dörfler 				fRunner->Resume();
2367cae4a1eSAxel Dörfler 				fWindow->Unlock();
2377cae4a1eSAxel Dörfler 			}
238af55bae2SAxel Dörfler 
239cb6a084fSRyan Leavengood 			// Turn on the message filter again
240cb6a084fSRyan Leavengood 			BMessage enable(kMsgEnableFilter);
241d39c5354SRyan Leavengood 			fWindow->PostMessage(&enable);
242cb6a084fSRyan Leavengood 
243af55bae2SAxel Dörfler 			_QueueTurnOffScreen();
244af55bae2SAxel Dörfler 			break;
245cb6a084fSRyan Leavengood 		}
246af55bae2SAxel Dörfler 
247af55bae2SAxel Dörfler 		case kMsgTurnOffScreen:
248af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_OFF);
249af55bae2SAxel Dörfler 			break;
250af55bae2SAxel Dörfler 		case kMsgSuspendScreen:
251af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_SUSPEND);
252af55bae2SAxel Dörfler 			break;
253af55bae2SAxel Dörfler 		case kMsgStandByScreen:
254af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_STAND_BY);
2557cae4a1eSAxel Dörfler 			break;
2567cae4a1eSAxel Dörfler 
2577cae4a1eSAxel Dörfler 		default:
2587cae4a1eSAxel Dörfler 			BApplication::MessageReceived(message);
2597cae4a1eSAxel Dörfler  			break;
2607cae4a1eSAxel Dörfler 	}
2617cae4a1eSAxel Dörfler }
2627cae4a1eSAxel Dörfler 
2637cae4a1eSAxel Dörfler 
2647cae4a1eSAxel Dörfler bool
2657cae4a1eSAxel Dörfler ScreenBlanker::QuitRequested()
2667cae4a1eSAxel Dörfler {
26741158aafSAxel Dörfler 	if (fSettings.LockEnable()
26841158aafSAxel Dörfler 		&& system_time() - fBlankTime > fSettings.PasswordTime() - fSettings.BlankTime()) {
2697cae4a1eSAxel Dörfler 		_ShowPasswordWindow();
2707cae4a1eSAxel Dörfler 		return false;
2717cae4a1eSAxel Dörfler 	}
2727cae4a1eSAxel Dörfler 
2737cae4a1eSAxel Dörfler 	_Shutdown();
2747cae4a1eSAxel Dörfler 	return true;
2757cae4a1eSAxel Dörfler }
2767cae4a1eSAxel Dörfler 
2777cae4a1eSAxel Dörfler 
2787cae4a1eSAxel Dörfler void
2797cae4a1eSAxel Dörfler ScreenBlanker::_Shutdown()
2807cae4a1eSAxel Dörfler {
2817cae4a1eSAxel Dörfler 	delete fRunner;
2827cae4a1eSAxel Dörfler 
283d0e9fa68SAxel Dörfler 	if (fWindow) {
2847cae4a1eSAxel Dörfler 		fWindow->Hide();
285d0e9fa68SAxel Dörfler 
286d0e9fa68SAxel Dörfler 		if (fWindow->Lock())
287d0e9fa68SAxel Dörfler 			fWindow->Quit();
288d0e9fa68SAxel Dörfler 	}
2897cae4a1eSAxel Dörfler }
2907cae4a1eSAxel Dörfler 
2917cae4a1eSAxel Dörfler 
2927cae4a1eSAxel Dörfler //	#pragma mark -
2937cae4a1eSAxel Dörfler 
2947cae4a1eSAxel Dörfler 
2957cae4a1eSAxel Dörfler int
2967cae4a1eSAxel Dörfler main(int, char**)
2977cae4a1eSAxel Dörfler {
2987cae4a1eSAxel Dörfler 	ScreenBlanker app;
2997cae4a1eSAxel Dörfler 	app.Run();
3007cae4a1eSAxel Dörfler 	return 0;
3017cae4a1eSAxel Dörfler }
302