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