haiku/src/bin/screen_blanker/ScreenBlanker.cpp
Axel Dörfler f0d2e76081 * Fixed missing "not" operator in all those flags changing lines; turning off the
screen is now working as expected.
* Only remove DPMS runners when the time is actually supported (previous code would
  not have always worked correctly in case the graphics card would not support all
  DPMS modes).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19724 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-01-06 15:50:26 +00:00

298 lines
5.9 KiB
C++

/*
* Copyright 2003-2007, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Phipps
* Jérôme Duval, jerome.duval@free.fr
* Axel Dörfler, axeld@pinc-software.de
*/
#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>
const static uint32 kMsgResumeSaver = 'RSSV';
const static uint32 kMsgTurnOffScreen = 'tofs';
const static uint32 kMsgSuspendScreen = 'suss';
const static uint32 kMsgStandByScreen = 'stbs';
ScreenBlanker::ScreenBlanker()
: BApplication(SCREEN_BLANKER_SIG),
fWindow(NULL),
fSaver(NULL),
fRunner(NULL),
fPasswordWindow(NULL),
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\n");
exit(1);
}
// create a BDirectWindow and start the render thread.
// TODO: we need a window per screen...
BScreen screen(B_MAIN_SCREEN_ID);
fWindow = new ScreenSaverWindow(screen.Frame());
fPasswordWindow = new PasswordWindow();
fRunner = new ScreenSaverRunner(fWindow, fWindow->ChildAt(0), false, fSettings);
fSaver = fRunner->ScreenSaver();
if (fSaver) {
fWindow->SetSaver(fSaver);
fRunner->Run();
} else {
fprintf(stderr, "could not load the screensaver addon\n");
}
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()) {
fRunner->Suspend();
fWindow->Unlock();
}
}
void
ScreenBlanker::_ShowPasswordWindow()
{
_TurnOnScreen();
if (fWindow->Lock()) {
fRunner->Suspend();
if (fWindow->SetFullScreen(false) == B_OK) {
fWindow->Sync();
// TODO: is that needed?
ShowCursor();
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()
{
// stop running notifiers
delete fStandByScreenRunner;
delete fSuspendScreenRunner;
delete fTurnOffScreenRunner;
fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL;
// figure out which notifiers we need and which of them are supported
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;
// start them off again
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, "turn off 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::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgUnlock:
{
if (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()) {
if (fWindow->SetFullScreen(true) == B_OK) {
HideCursor();
fPasswordWindow->Hide();
}
fRunner->Resume();
fWindow->Unlock();
}
_QueueTurnOffScreen();
break;
case kMsgTurnOffScreen:
_SetDPMSMode(B_DPMS_OFF);
break;
case kMsgSuspendScreen:
_SetDPMSMode(B_DPMS_SUSPEND);
break;
case kMsgStandByScreen:
_SetDPMSMode(B_DPMS_STAND_BY);
break;
default:
BApplication::MessageReceived(message);
break;
}
}
bool
ScreenBlanker::QuitRequested()
{
if (fSettings.LockEnable()
&& system_time() - fBlankTime > fSettings.PasswordTime() - fSettings.BlankTime()) {
_ShowPasswordWindow();
return false;
}
_Shutdown();
return true;
}
void
ScreenBlanker::_Shutdown()
{
delete fRunner;
if (fWindow) {
fWindow->Hide();
if (fWindow->Lock())
fWindow->Quit();
}
}
// #pragma mark -
int
main(int, char**)
{
ScreenBlanker app;
app.Run();
return 0;
}