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