* Copyright 2003-2014 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Jérôme Duval, jerome.duval@free.fr
* Axel Dörfler, axeld@pinc-software.de
* Ryan Leavengood, leavengood@gmail.com
* Michael Phipps
* John Scipione, jscipione@gmail.com
* Puck Meerburg, puck@puckipedia.nl
*/
#include "ScreenBlanker.h"
#include <Beep.h>
#include <Debug.h>
#include <File.h>
#include <FindDirectory.h>
#include <Path.h>
#include <Screen.h>
#include <StorageDefs.h>
#include <SupportDefs.h>
#include <image.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "ScreenSaverShared.h"
const static uint32 kMsgTurnOffScreen = 'tofs';
const static uint32 kMsgSuspendScreen = 'suss';
const static uint32 kMsgStandByScreen = 'stbs';
ScreenBlanker::ScreenBlanker()
:
BApplication(SCREEN_BLANKER_SIG),
fWindow(NULL),
fSaverRunner(NULL),
fPasswordWindow(NULL),
fImmediateLock(false),
fTestSaver(false),
fResumeRunner(NULL),
fStandByScreenRunner(NULL),
fSuspendScreenRunner(NULL),
fTurnOffScreenRunner(NULL)
{
fBlankTime = system_time();
}
ScreenBlanker::~ScreenBlanker()
{
delete fResumeRunner;
_TurnOnScreen();
}
void
ScreenBlanker::ReadyToRun()
{
if (!fSettings.Load())
fprintf(stderr, "could not load settings, using defaults\n");
BScreen screen(B_MAIN_SCREEN_ID);
fWindow = new ScreenSaverWindow(screen.Frame(), fTestSaver);
fPasswordWindow = new PasswordWindow();
BView* view = fWindow->ChildAt(0);
fSaverRunner = new ScreenSaverRunner(fWindow, view, fSettings);
fWindow->SetSaverRunner(fSaverRunner);
BScreenSaver* saver = fSaverRunner->ScreenSaver();
if (saver != NULL && saver->StartSaver(view, false) == B_OK)
fSaverRunner->Run();
else {
fprintf(stderr, "could not load the screensaver addon\n");
view->SetViewColor(0, 0, 0);
}
fWindow->SetFullScreen(true);
fWindow->Show();
HideCursor();
_QueueTurnOffScreen();
}
void
ScreenBlanker::_TurnOnScreen()
{
delete fStandByScreenRunner;
delete fSuspendScreenRunner;
delete fTurnOffScreenRunner;
fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
BScreen screen;
screen.SetDPMS(B_DPMS_ON);
}
void
ScreenBlanker::_SetDPMSMode(uint32 mode)
{
BScreen screen;
screen.SetDPMS(mode);
if (fWindow->Lock()) {
fSaverRunner->Suspend();
fWindow->Unlock();
}
}
void
ScreenBlanker::_ShowPasswordWindow()
{
_TurnOnScreen();
if (fWindow->Lock()) {
fSaverRunner->Suspend();
fWindow->Sync();
ShowCursor();
if (fPasswordWindow->IsHidden())
fPasswordWindow->Show();
fWindow->Unlock();
}
_QueueResumeScreenSaver();
}
void
ScreenBlanker::_QueueResumeScreenSaver()
{
delete fResumeRunner;
BMessage resume(kMsgResumeSaver);
fResumeRunner = new BMessageRunner(BMessenger(this), &resume,
fSettings.BlankTime(), 1);
if (fResumeRunner->InitCheck() != B_OK)
syslog(LOG_ERR, "resume screen saver runner failed\n");
}
void
ScreenBlanker::_QueueTurnOffScreen()
{
delete fStandByScreenRunner;
delete fSuspendScreenRunner;
delete fTurnOffScreenRunner;
fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
uint32 flags = fSettings.TimeFlags();
BScreen screen;
uint32 capabilities = screen.DPMSCapabilites();
if ((capabilities & B_DPMS_OFF) == 0)
flags &= ~ENABLE_DPMS_OFF;
if ((capabilities & B_DPMS_SUSPEND) == 0)
flags &= ~ENABLE_DPMS_SUSPEND;
if ((capabilities & B_DPMS_STAND_BY) == 0)
flags &= ~ENABLE_DPMS_STAND_BY;
if ((flags & ENABLE_DPMS_MASK) == 0)
return;
if (fSettings.OffTime() == fSettings.SuspendTime()
&& (flags & (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
== (ENABLE_DPMS_OFF | ENABLE_DPMS_SUSPEND))
flags &= ~ENABLE_DPMS_SUSPEND;
if (fSettings.SuspendTime() == fSettings.StandByTime()
&& (flags & (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
== (ENABLE_DPMS_SUSPEND | ENABLE_DPMS_STAND_BY))
flags &= ~ENABLE_DPMS_STAND_BY;
if (flags & ENABLE_DPMS_STAND_BY) {
BMessage dpms(kMsgStandByScreen);
fStandByScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
fSettings.StandByTime(), 1);
if (fStandByScreenRunner->InitCheck() != B_OK)
syslog(LOG_ERR, "standby screen saver runner failed\n");
}
if (flags & ENABLE_DPMS_SUSPEND) {
BMessage dpms(kMsgSuspendScreen);
fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
fSettings.SuspendTime(), 1);
if (fSuspendScreenRunner->InitCheck() != B_OK)
syslog(LOG_ERR, "suspend screen saver runner failed\n");
}
if (flags & ENABLE_DPMS_OFF) {
BMessage dpms(kMsgTurnOffScreen);
fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), &dpms,
fSettings.OffTime(), 1);
if (fTurnOffScreenRunner->InitCheck() != B_OK)
syslog(LOG_ERR, "turn off screen saver runner failed\n");
}
}
void
ScreenBlanker::ArgvReceived(int argc, char** argv)
{
if (argc > 1 && strcmp("-l", argv[1]) == 0)
fImmediateLock = true;
}
void
ScreenBlanker::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgUnlock:
{
if (fSettings.Password()[0] != '\0'
&& strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(),
fSettings.Password())) != 0) {
beep();
fPasswordWindow->SetPassword("");
_QueueResumeScreenSaver();
} else {
PRINT(("Quitting!\n"));
_Shutdown();
Quit();
}
break;
}
case kMsgResumeSaver:
{
if (fWindow->Lock()) {
fWindow->Activate();
HideCursor();
fPasswordWindow->SetPassword("");
fPasswordWindow->Hide();
fSaverRunner->Resume();
fWindow->Unlock();
}
BMessage enable(kMsgEnableFilter);
fWindow->PostMessage(&enable);
_QueueTurnOffScreen();
break;
}
case kMsgTurnOffScreen:
_SetDPMSMode(B_DPMS_OFF);
break;
case kMsgSuspendScreen:
_SetDPMSMode(B_DPMS_SUSPEND);
break;
case kMsgStandByScreen:
_SetDPMSMode(B_DPMS_STAND_BY);
break;
case kMsgTestSaver:
fTestSaver = true;
break;
default:
BApplication::MessageReceived(message);
}
}
bool
ScreenBlanker::QuitRequested()
{
if (fSettings.LockEnable()) {
bigtime_t minTime = fSettings.PasswordTime() - fSettings.BlankTime();
if (minTime == 0)
minTime = 5000000;
if (fImmediateLock || system_time() - fBlankTime > minTime) {
_ShowPasswordWindow();
return false;
}
}
_Shutdown();
return true;
}
bool
ScreenBlanker::IsPasswordWindowShown() const
{
return fPasswordWindow != NULL && !fPasswordWindow->IsHidden();
}
void
ScreenBlanker::_Shutdown()
{
if (fWindow != NULL) {
fWindow->Hide();
if (fWindow->Lock())
fWindow->Quit();
}
delete fSaverRunner;
fSaverRunner = NULL;
}
int
main(int argc, char** argv)
{
ScreenBlanker app;
app.Run();
return 0;
}