xref: /haiku/src/bin/screen_blanker/ScreenBlanker.cpp (revision e4e2ce4ce38546193ddab428b32a654447a07e19)
17cae4a1eSAxel Dörfler /*
2*e4e2ce4cSPuck Meerburg  * Copyright 2003-2014 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
11*e4e2ce4cSPuck Meerburg  *		Puck Meerburg, puck@puckipedia.nl
127cae4a1eSAxel Dörfler  */
137cae4a1eSAxel Dörfler 
147cae4a1eSAxel Dörfler 
157cae4a1eSAxel Dörfler #include "ScreenBlanker.h"
167cae4a1eSAxel Dörfler 
177cae4a1eSAxel Dörfler #include <Beep.h>
187cae4a1eSAxel Dörfler #include <Debug.h>
197cae4a1eSAxel Dörfler #include <File.h>
207cae4a1eSAxel Dörfler #include <FindDirectory.h>
217cae4a1eSAxel Dörfler #include <Path.h>
227cae4a1eSAxel Dörfler #include <Screen.h>
237cae4a1eSAxel Dörfler #include <StorageDefs.h>
247cae4a1eSAxel Dörfler #include <SupportDefs.h>
257cae4a1eSAxel Dörfler #include <image.h>
267cae4a1eSAxel Dörfler 
277cae4a1eSAxel Dörfler #include <stdio.h>
287cae4a1eSAxel Dörfler #include <string.h>
29af55bae2SAxel Dörfler #include <syslog.h>
307cae4a1eSAxel Dörfler 
31*e4e2ce4cSPuck Meerburg #include "ScreenSaverShared.h"
327cae4a1eSAxel Dörfler 
33af55bae2SAxel Dörfler const static uint32 kMsgTurnOffScreen = 'tofs';
34af55bae2SAxel Dörfler const static uint32 kMsgSuspendScreen = 'suss';
35af55bae2SAxel Dörfler const static uint32 kMsgStandByScreen = 'stbs';
367cae4a1eSAxel Dörfler 
377cae4a1eSAxel Dörfler 
38e22c01afSJohn Scipione //	#pragma mark - ScreenBlanker
39e22c01afSJohn Scipione 
40e22c01afSJohn Scipione 
ScreenBlanker()417cae4a1eSAxel Dörfler ScreenBlanker::ScreenBlanker()
42e22c01afSJohn Scipione 	:
43e22c01afSJohn Scipione 	BApplication(SCREEN_BLANKER_SIG),
447cae4a1eSAxel Dörfler 	fWindow(NULL),
45d34a680cSJohn Scipione 	fSaverRunner(NULL),
467cae4a1eSAxel Dörfler 	fPasswordWindow(NULL),
47*e4e2ce4cSPuck Meerburg 	fTestSaver(false),
48af55bae2SAxel Dörfler 	fResumeRunner(NULL),
49af55bae2SAxel Dörfler 	fStandByScreenRunner(NULL),
50af55bae2SAxel Dörfler 	fSuspendScreenRunner(NULL),
51af55bae2SAxel Dörfler 	fTurnOffScreenRunner(NULL)
527cae4a1eSAxel Dörfler {
537cae4a1eSAxel Dörfler 	fBlankTime = system_time();
547cae4a1eSAxel Dörfler }
557cae4a1eSAxel Dörfler 
567cae4a1eSAxel Dörfler 
~ScreenBlanker()577cae4a1eSAxel Dörfler ScreenBlanker::~ScreenBlanker()
587cae4a1eSAxel Dörfler {
597cae4a1eSAxel Dörfler 	delete fResumeRunner;
60af55bae2SAxel Dörfler 	_TurnOnScreen();
617cae4a1eSAxel Dörfler }
627cae4a1eSAxel Dörfler 
637cae4a1eSAxel Dörfler 
647cae4a1eSAxel Dörfler void
ReadyToRun()657cae4a1eSAxel Dörfler ScreenBlanker::ReadyToRun()
667cae4a1eSAxel Dörfler {
67e22c01afSJohn Scipione 	if (!fSettings.Load())
68cb6a084fSRyan Leavengood 		fprintf(stderr, "could not load settings, using defaults\n");
697cae4a1eSAxel Dörfler 
707cae4a1eSAxel Dörfler 	// create a BDirectWindow and start the render thread.
71af55bae2SAxel Dörfler 	// TODO: we need a window per screen...
727cae4a1eSAxel Dörfler 	BScreen screen(B_MAIN_SCREEN_ID);
73*e4e2ce4cSPuck Meerburg 	fWindow = new ScreenSaverWindow(screen.Frame(), fTestSaver);
747cae4a1eSAxel Dörfler 	fPasswordWindow = new PasswordWindow();
757cae4a1eSAxel Dörfler 
76d34a680cSJohn Scipione 	BView* view = fWindow->ChildAt(0);
771c776bfeSJohn Scipione 	fSaverRunner = new ScreenSaverRunner(fWindow, view, fSettings);
78d34a680cSJohn Scipione 	fWindow->SetSaverRunner(fSaverRunner);
79d34a680cSJohn Scipione 
80d34a680cSJohn Scipione 	BScreenSaver* saver = fSaverRunner->ScreenSaver();
81d34a680cSJohn Scipione 	if (saver != NULL && saver->StartSaver(view, false) == B_OK)
82d34a680cSJohn Scipione 		fSaverRunner->Run();
83d34a680cSJohn Scipione 	else {
847cae4a1eSAxel Dörfler 		fprintf(stderr, "could not load the screensaver addon\n");
85d34a680cSJohn Scipione 		view->SetViewColor(0, 0, 0);
86d34a680cSJohn Scipione 			// needed for Blackness saver
877cae4a1eSAxel Dörfler 	}
887cae4a1eSAxel Dörfler 
897cae4a1eSAxel Dörfler 	fWindow->SetFullScreen(true);
907cae4a1eSAxel Dörfler 	fWindow->Show();
917cae4a1eSAxel Dörfler 	HideCursor();
92af55bae2SAxel Dörfler 
93af55bae2SAxel Dörfler 	_QueueTurnOffScreen();
94af55bae2SAxel Dörfler }
95af55bae2SAxel Dörfler 
96af55bae2SAxel Dörfler 
97af55bae2SAxel Dörfler void
_TurnOnScreen()98af55bae2SAxel Dörfler ScreenBlanker::_TurnOnScreen()
99af55bae2SAxel Dörfler {
100af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
101af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
102af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
103af55bae2SAxel Dörfler 
104af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
105af55bae2SAxel Dörfler 
106af55bae2SAxel Dörfler 	BScreen screen;
107af55bae2SAxel Dörfler 	screen.SetDPMS(B_DPMS_ON);
108af55bae2SAxel Dörfler }
109af55bae2SAxel Dörfler 
110af55bae2SAxel Dörfler 
111af55bae2SAxel Dörfler void
_SetDPMSMode(uint32 mode)112af55bae2SAxel Dörfler ScreenBlanker::_SetDPMSMode(uint32 mode)
113af55bae2SAxel Dörfler {
114af55bae2SAxel Dörfler 	BScreen screen;
115af55bae2SAxel Dörfler 	screen.SetDPMS(mode);
116af55bae2SAxel Dörfler 
117af55bae2SAxel Dörfler 	if (fWindow->Lock()) {
118d34a680cSJohn Scipione 		fSaverRunner->Suspend();
119af55bae2SAxel Dörfler 		fWindow->Unlock();
120af55bae2SAxel Dörfler 	}
1217cae4a1eSAxel Dörfler }
1227cae4a1eSAxel Dörfler 
1237cae4a1eSAxel Dörfler 
1247cae4a1eSAxel Dörfler void
_ShowPasswordWindow()1257cae4a1eSAxel Dörfler ScreenBlanker::_ShowPasswordWindow()
1267cae4a1eSAxel Dörfler {
127af55bae2SAxel Dörfler 	_TurnOnScreen();
128af55bae2SAxel Dörfler 
1297cae4a1eSAxel Dörfler 	if (fWindow->Lock()) {
130d34a680cSJohn Scipione 		fSaverRunner->Suspend();
1317cae4a1eSAxel Dörfler 
1327cae4a1eSAxel Dörfler 		fWindow->Sync();
1337cae4a1eSAxel Dörfler 			// TODO: is that needed?
1347cae4a1eSAxel Dörfler 		ShowCursor();
135cb6a084fSRyan Leavengood 		if (fPasswordWindow->IsHidden())
1367cae4a1eSAxel Dörfler 			fPasswordWindow->Show();
137310a9c9eSAxel Dörfler 
1387cae4a1eSAxel Dörfler 		fWindow->Unlock();
1397cae4a1eSAxel Dörfler 	}
1407cae4a1eSAxel Dörfler 
141af55bae2SAxel Dörfler 	_QueueResumeScreenSaver();
1427cae4a1eSAxel Dörfler }
1437cae4a1eSAxel Dörfler 
1447cae4a1eSAxel Dörfler 
1457cae4a1eSAxel Dörfler void
_QueueResumeScreenSaver()146af55bae2SAxel Dörfler ScreenBlanker::_QueueResumeScreenSaver()
1477cae4a1eSAxel Dörfler {
1487cae4a1eSAxel Dörfler 	delete fResumeRunner;
149d0e9fa68SAxel Dörfler 
150d0e9fa68SAxel Dörfler 	BMessage resume(kMsgResumeSaver);
151d0e9fa68SAxel Dörfler 	fResumeRunner = new BMessageRunner(BMessenger(this), &resume,
15241158aafSAxel Dörfler 		fSettings.BlankTime(), 1);
153af55bae2SAxel Dörfler 	if (fResumeRunner->InitCheck() != B_OK)
154af55bae2SAxel Dörfler 		syslog(LOG_ERR, "resume screen saver runner failed\n");
155af55bae2SAxel Dörfler }
156af55bae2SAxel Dörfler 
157af55bae2SAxel Dörfler 
158af55bae2SAxel Dörfler void
_QueueTurnOffScreen()159af55bae2SAxel Dörfler ScreenBlanker::_QueueTurnOffScreen()
160af55bae2SAxel Dörfler {
161af55bae2SAxel Dörfler 	// stop running notifiers
162af55bae2SAxel Dörfler 
163af55bae2SAxel Dörfler 	delete fStandByScreenRunner;
164af55bae2SAxel Dörfler 	delete fSuspendScreenRunner;
165af55bae2SAxel Dörfler 	delete fTurnOffScreenRunner;
166af55bae2SAxel Dörfler 
167af55bae2SAxel Dörfler 	fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
168af55bae2SAxel Dörfler 
169af55bae2SAxel Dörfler 	// figure out which notifiers we need and which of them are supported
170af55bae2SAxel Dörfler 
17141158aafSAxel Dörfler 	uint32 flags = fSettings.TimeFlags();
172af55bae2SAxel Dörfler 	BScreen screen;
173af55bae2SAxel Dörfler 	uint32 capabilities = screen.DPMSCapabilites();
174af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_OFF) == 0)
175f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_OFF;
176af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_SUSPEND) == 0)
177f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
178af55bae2SAxel Dörfler 	if ((capabilities & B_DPMS_STAND_BY) == 0)
179f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
180af55bae2SAxel Dörfler 
181af55bae2SAxel Dörfler 	if ((flags & ENABLE_DPMS_MASK) == 0)
182af55bae2SAxel Dörfler 		return;
183af55bae2SAxel Dörfler 
184f0d2e760SAxel Dörfler 	if (fSettings.OffTime() == fSettings.SuspendTime()
185e22c01afSJohn Scipione 		&& (flags & (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
186e22c01afSJohn Scipione 			== (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
187f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_SUSPEND;
188f0d2e760SAxel Dörfler 	if (fSettings.SuspendTime() == fSettings.StandByTime()
189e22c01afSJohn Scipione 		&& (flags & (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
190e22c01afSJohn Scipione 			== (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
191f0d2e760SAxel Dörfler 		flags &= ~ENABLE_DPMS_STAND_BY;
192af55bae2SAxel Dörfler 
193af55bae2SAxel Dörfler 	// start them off again
194af55bae2SAxel Dörfler 
195af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_STAND_BY) {
196d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgStandByScreen);
197d0e9fa68SAxel Dörfler 		fStandByScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
198d0e9fa68SAxel Dörfler 			fSettings.StandByTime(), 1);
199af55bae2SAxel Dörfler 		if (fStandByScreenRunner->InitCheck() != B_OK)
200af55bae2SAxel Dörfler 			syslog(LOG_ERR, "standby screen saver runner failed\n");
201af55bae2SAxel Dörfler 	}
202af55bae2SAxel Dörfler 
203af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_SUSPEND) {
204d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgSuspendScreen);
205d0e9fa68SAxel Dörfler 		fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
206d0e9fa68SAxel Dörfler 			fSettings.SuspendTime(), 1);
207af55bae2SAxel Dörfler 		if (fSuspendScreenRunner->InitCheck() != B_OK)
208cb6a084fSRyan Leavengood 			syslog(LOG_ERR, "suspend screen saver runner failed\n");
209af55bae2SAxel Dörfler 	}
210af55bae2SAxel Dörfler 
211af55bae2SAxel Dörfler 	if (flags & ENABLE_DPMS_OFF) {
212d0e9fa68SAxel Dörfler 		BMessage dpms(kMsgTurnOffScreen);
213d0e9fa68SAxel Dörfler 		fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
214d0e9fa68SAxel Dörfler 			fSettings.OffTime(), 1);
215af55bae2SAxel Dörfler 		if (fTurnOffScreenRunner->InitCheck() != B_OK)
216af55bae2SAxel Dörfler 			syslog(LOG_ERR, "turn off screen saver runner failed\n");
2177cae4a1eSAxel Dörfler 	}
2187cae4a1eSAxel Dörfler }
2197cae4a1eSAxel Dörfler 
2207cae4a1eSAxel Dörfler 
2217cae4a1eSAxel Dörfler void
MessageReceived(BMessage * message)2227cae4a1eSAxel Dörfler ScreenBlanker::MessageReceived(BMessage* message)
2237cae4a1eSAxel Dörfler {
2247cae4a1eSAxel Dörfler 	switch (message->what) {
225af55bae2SAxel Dörfler 		case kMsgUnlock:
2267cae4a1eSAxel Dörfler 		{
22741158aafSAxel Dörfler 			if (strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(),
22841158aafSAxel Dörfler 					fSettings.Password())) != 0) {
2297cae4a1eSAxel Dörfler 				beep();
2307cae4a1eSAxel Dörfler 				fPasswordWindow->SetPassword("");
231af55bae2SAxel Dörfler 				_QueueResumeScreenSaver();
2327cae4a1eSAxel Dörfler 			} else  {
2337cae4a1eSAxel Dörfler 				PRINT(("Quitting!\n"));
2347cae4a1eSAxel Dörfler 				_Shutdown();
2357cae4a1eSAxel Dörfler 				Quit();
2367cae4a1eSAxel Dörfler 			}
2377cae4a1eSAxel Dörfler 			break;
2387cae4a1eSAxel Dörfler 		}
2397cae4a1eSAxel Dörfler 
240af55bae2SAxel Dörfler 		case kMsgResumeSaver:
241cb6a084fSRyan Leavengood 		{
2427cae4a1eSAxel Dörfler 			if (fWindow->Lock()) {
2437cae4a1eSAxel Dörfler 				HideCursor();
2440834f79cSRyan Leavengood 				fPasswordWindow->SetPassword("");
2457cae4a1eSAxel Dörfler 				fPasswordWindow->Hide();
2467cae4a1eSAxel Dörfler 
247d34a680cSJohn Scipione 				fSaverRunner->Resume();
2487cae4a1eSAxel Dörfler 				fWindow->Unlock();
2497cae4a1eSAxel Dörfler 			}
250af55bae2SAxel Dörfler 
251cb6a084fSRyan Leavengood 			// Turn on the message filter again
252cb6a084fSRyan Leavengood 			BMessage enable(kMsgEnableFilter);
253d39c5354SRyan Leavengood 			fWindow->PostMessage(&enable);
254cb6a084fSRyan Leavengood 
255af55bae2SAxel Dörfler 			_QueueTurnOffScreen();
256af55bae2SAxel Dörfler 			break;
257cb6a084fSRyan Leavengood 		}
258af55bae2SAxel Dörfler 
259af55bae2SAxel Dörfler 		case kMsgTurnOffScreen:
260af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_OFF);
261af55bae2SAxel Dörfler 			break;
262e22c01afSJohn Scipione 
263af55bae2SAxel Dörfler 		case kMsgSuspendScreen:
264af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_SUSPEND);
265af55bae2SAxel Dörfler 			break;
266e22c01afSJohn Scipione 
267af55bae2SAxel Dörfler 		case kMsgStandByScreen:
268af55bae2SAxel Dörfler 			_SetDPMSMode(B_DPMS_STAND_BY);
2697cae4a1eSAxel Dörfler 			break;
2707cae4a1eSAxel Dörfler 
271*e4e2ce4cSPuck Meerburg 		case kMsgTestSaver:
272*e4e2ce4cSPuck Meerburg 			fTestSaver = true;
273*e4e2ce4cSPuck Meerburg 			break;
274*e4e2ce4cSPuck Meerburg 
2757cae4a1eSAxel Dörfler 		default:
2767cae4a1eSAxel Dörfler 			BApplication::MessageReceived(message);
2777cae4a1eSAxel Dörfler 	}
2787cae4a1eSAxel Dörfler }
2797cae4a1eSAxel Dörfler 
2807cae4a1eSAxel Dörfler 
2817cae4a1eSAxel Dörfler bool
QuitRequested()2827cae4a1eSAxel Dörfler ScreenBlanker::QuitRequested()
2837cae4a1eSAxel Dörfler {
284658491b8SPuck Meerburg 	if (fSettings.LockEnable()) {
285658491b8SPuck Meerburg 		bigtime_t minTime = fSettings.PasswordTime() - fSettings.BlankTime();
286658491b8SPuck Meerburg 		if (minTime == 0)
287658491b8SPuck Meerburg 			minTime = 5000000;
288658491b8SPuck Meerburg 		if (system_time() - fBlankTime > minTime) {
2897cae4a1eSAxel Dörfler 			_ShowPasswordWindow();
2907cae4a1eSAxel Dörfler 			return false;
2917cae4a1eSAxel Dörfler 		}
292658491b8SPuck Meerburg 	}
2937cae4a1eSAxel Dörfler 
2947cae4a1eSAxel Dörfler 	_Shutdown();
2957cae4a1eSAxel Dörfler 	return true;
2967cae4a1eSAxel Dörfler }
2977cae4a1eSAxel Dörfler 
2987cae4a1eSAxel Dörfler 
2990f1162d2SJohn Scipione bool
IsPasswordWindowShown() const3000f1162d2SJohn Scipione ScreenBlanker::IsPasswordWindowShown() const
3010f1162d2SJohn Scipione {
3020f1162d2SJohn Scipione 	return fPasswordWindow != NULL && !fPasswordWindow->IsHidden();
3030f1162d2SJohn Scipione }
3040f1162d2SJohn Scipione 
3050f1162d2SJohn Scipione 
3067cae4a1eSAxel Dörfler void
_Shutdown()3077cae4a1eSAxel Dörfler ScreenBlanker::_Shutdown()
3087cae4a1eSAxel Dörfler {
309e22c01afSJohn Scipione 	if (fWindow != NULL) {
3107cae4a1eSAxel Dörfler 		fWindow->Hide();
311d0e9fa68SAxel Dörfler 
312d0e9fa68SAxel Dörfler 		if (fWindow->Lock())
313d0e9fa68SAxel Dörfler 			fWindow->Quit();
314d0e9fa68SAxel Dörfler 	}
31552bc210dSKarsten Heimrich 
316d34a680cSJohn Scipione 	delete fSaverRunner;
317d34a680cSJohn Scipione 	fSaverRunner = NULL;
3187cae4a1eSAxel Dörfler }
3197cae4a1eSAxel Dörfler 
3207cae4a1eSAxel Dörfler 
321e22c01afSJohn Scipione //	#pragma mark - main
3227cae4a1eSAxel Dörfler 
3237cae4a1eSAxel Dörfler 
3247cae4a1eSAxel Dörfler int
main(int argc,char ** argv)325e22c01afSJohn Scipione main(int argc, char** argv)
3267cae4a1eSAxel Dörfler {
3277cae4a1eSAxel Dörfler 	ScreenBlanker app;
3287cae4a1eSAxel Dörfler 	app.Run();
329e22c01afSJohn Scipione 
3307cae4a1eSAxel Dörfler 	return 0;
3317cae4a1eSAxel Dörfler }
332