17cae4a1eSAxel Dörfler /* 27cae4a1eSAxel Dörfler * Copyright 2003-2006, 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 97cae4a1eSAxel Dörfler */ 107cae4a1eSAxel Dörfler 117cae4a1eSAxel Dörfler 127cae4a1eSAxel Dörfler #include "ScreenBlanker.h" 137cae4a1eSAxel Dörfler 147cae4a1eSAxel Dörfler #include <Beep.h> 157cae4a1eSAxel Dörfler #include <Debug.h> 167cae4a1eSAxel Dörfler #include <File.h> 177cae4a1eSAxel Dörfler #include <FindDirectory.h> 187cae4a1eSAxel Dörfler #include <Path.h> 197cae4a1eSAxel Dörfler #include <Screen.h> 207cae4a1eSAxel Dörfler #include <StorageDefs.h> 217cae4a1eSAxel Dörfler #include <SupportDefs.h> 227cae4a1eSAxel Dörfler #include <image.h> 237cae4a1eSAxel Dörfler 247cae4a1eSAxel Dörfler #include <stdio.h> 257cae4a1eSAxel Dörfler #include <string.h> 26af55bae2SAxel Dörfler #include <syslog.h> 277cae4a1eSAxel Dörfler 287cae4a1eSAxel Dörfler 29af55bae2SAxel Dörfler const static uint32 kMsgResumeSaver = 'RSSV'; 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 { 60*41158aafSAxel Dörfler if (!fSettings.LoadSettings()) { 617cae4a1eSAxel Dörfler fprintf(stderr, "could not load settings\n"); 627cae4a1eSAxel Dörfler exit(1); 637cae4a1eSAxel Dörfler } 647cae4a1eSAxel Dörfler 657cae4a1eSAxel Dörfler // create a BDirectWindow and start the render thread. 66af55bae2SAxel Dörfler // TODO: we need a window per screen... 677cae4a1eSAxel Dörfler BScreen screen(B_MAIN_SCREEN_ID); 687cae4a1eSAxel Dörfler fWindow = new ScreenSaverWindow(screen.Frame()); 697cae4a1eSAxel Dörfler fPasswordWindow = new PasswordWindow(); 70*41158aafSAxel Dörfler fRunner = new ScreenSaverRunner(fWindow, fWindow->ChildAt(0), false, fSettings); 717cae4a1eSAxel Dörfler 727cae4a1eSAxel Dörfler fSaver = fRunner->ScreenSaver(); 737cae4a1eSAxel Dörfler if (fSaver) { 747cae4a1eSAxel Dörfler fWindow->SetSaver(fSaver); 757cae4a1eSAxel Dörfler fRunner->Run(); 767cae4a1eSAxel Dörfler } else { 777cae4a1eSAxel Dörfler fprintf(stderr, "could not load the screensaver addon\n"); 787cae4a1eSAxel Dörfler } 797cae4a1eSAxel Dörfler 807cae4a1eSAxel Dörfler fWindow->SetFullScreen(true); 817cae4a1eSAxel Dörfler fWindow->Show(); 827cae4a1eSAxel Dörfler HideCursor(); 83af55bae2SAxel Dörfler 84af55bae2SAxel Dörfler _QueueTurnOffScreen(); 85af55bae2SAxel Dörfler } 86af55bae2SAxel Dörfler 87af55bae2SAxel Dörfler 88af55bae2SAxel Dörfler void 89af55bae2SAxel Dörfler ScreenBlanker::_TurnOnScreen() 90af55bae2SAxel Dörfler { 91af55bae2SAxel Dörfler delete fStandByScreenRunner; 92af55bae2SAxel Dörfler delete fSuspendScreenRunner; 93af55bae2SAxel Dörfler delete fTurnOffScreenRunner; 94af55bae2SAxel Dörfler 95af55bae2SAxel Dörfler fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL; 96af55bae2SAxel Dörfler 97af55bae2SAxel Dörfler BScreen screen; 98af55bae2SAxel Dörfler screen.SetDPMS(B_DPMS_ON); 99af55bae2SAxel Dörfler } 100af55bae2SAxel Dörfler 101af55bae2SAxel Dörfler 102af55bae2SAxel Dörfler void 103af55bae2SAxel Dörfler ScreenBlanker::_SetDPMSMode(uint32 mode) 104af55bae2SAxel Dörfler { 105af55bae2SAxel Dörfler BScreen screen; 106af55bae2SAxel Dörfler screen.SetDPMS(mode); 107af55bae2SAxel Dörfler 108af55bae2SAxel Dörfler if (fWindow->Lock()) { 109af55bae2SAxel Dörfler fRunner->Suspend(); 110af55bae2SAxel Dörfler fWindow->Unlock(); 111af55bae2SAxel Dörfler } 1127cae4a1eSAxel Dörfler } 1137cae4a1eSAxel Dörfler 1147cae4a1eSAxel Dörfler 1157cae4a1eSAxel Dörfler void 1167cae4a1eSAxel Dörfler ScreenBlanker::_ShowPasswordWindow() 1177cae4a1eSAxel Dörfler { 118af55bae2SAxel Dörfler _TurnOnScreen(); 119af55bae2SAxel Dörfler 1207cae4a1eSAxel Dörfler if (fWindow->Lock()) { 1217cae4a1eSAxel Dörfler fRunner->Suspend(); 1227cae4a1eSAxel Dörfler 1237cae4a1eSAxel Dörfler if (fWindow->SetFullScreen(false) == B_OK) { 1247cae4a1eSAxel Dörfler fWindow->Sync(); 1257cae4a1eSAxel Dörfler // TODO: is that needed? 1267cae4a1eSAxel Dörfler ShowCursor(); 1277cae4a1eSAxel Dörfler fPasswordWindow->Show(); 1287cae4a1eSAxel Dörfler } 1297cae4a1eSAxel Dörfler fWindow->Unlock(); 1307cae4a1eSAxel Dörfler } 1317cae4a1eSAxel Dörfler 132af55bae2SAxel Dörfler _QueueResumeScreenSaver(); 1337cae4a1eSAxel Dörfler } 1347cae4a1eSAxel Dörfler 1357cae4a1eSAxel Dörfler 1367cae4a1eSAxel Dörfler void 137af55bae2SAxel Dörfler ScreenBlanker::_QueueResumeScreenSaver() 1387cae4a1eSAxel Dörfler { 1397cae4a1eSAxel Dörfler delete fResumeRunner; 140af55bae2SAxel Dörfler fResumeRunner = new BMessageRunner(BMessenger(this), new BMessage(kMsgResumeSaver), 141*41158aafSAxel Dörfler fSettings.BlankTime(), 1); 142af55bae2SAxel Dörfler if (fResumeRunner->InitCheck() != B_OK) 143af55bae2SAxel Dörfler syslog(LOG_ERR, "resume screen saver runner failed\n"); 144af55bae2SAxel Dörfler } 145af55bae2SAxel Dörfler 146af55bae2SAxel Dörfler 147af55bae2SAxel Dörfler void 148af55bae2SAxel Dörfler ScreenBlanker::_QueueTurnOffScreen() 149af55bae2SAxel Dörfler { 150af55bae2SAxel Dörfler // stop running notifiers 151af55bae2SAxel Dörfler 152af55bae2SAxel Dörfler delete fStandByScreenRunner; 153af55bae2SAxel Dörfler delete fSuspendScreenRunner; 154af55bae2SAxel Dörfler delete fTurnOffScreenRunner; 155af55bae2SAxel Dörfler 156af55bae2SAxel Dörfler fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL; 157af55bae2SAxel Dörfler 158af55bae2SAxel Dörfler // figure out which notifiers we need and which of them are supported 159af55bae2SAxel Dörfler 160*41158aafSAxel Dörfler uint32 flags = fSettings.TimeFlags(); 161af55bae2SAxel Dörfler BScreen screen; 162af55bae2SAxel Dörfler uint32 capabilities = screen.DPMSCapabilites(); 163af55bae2SAxel Dörfler if ((capabilities & B_DPMS_OFF) == 0) 164af55bae2SAxel Dörfler flags &= ENABLE_DPMS_OFF; 165af55bae2SAxel Dörfler if ((capabilities & B_DPMS_SUSPEND) == 0) 166af55bae2SAxel Dörfler flags &= ENABLE_DPMS_SUSPEND; 167af55bae2SAxel Dörfler if ((capabilities & B_DPMS_STAND_BY) == 0) 168af55bae2SAxel Dörfler flags &= ENABLE_DPMS_STAND_BY; 169af55bae2SAxel Dörfler 170af55bae2SAxel Dörfler if ((flags & ENABLE_DPMS_MASK) == 0) 171af55bae2SAxel Dörfler return; 172af55bae2SAxel Dörfler 173*41158aafSAxel Dörfler if (fSettings.OffTime() == fSettings.SuspendTime()) 174af55bae2SAxel Dörfler flags &= ENABLE_DPMS_SUSPEND; 175*41158aafSAxel Dörfler if (fSettings.SuspendTime() == fSettings.StandByTime()) 176af55bae2SAxel Dörfler flags &= ENABLE_DPMS_STAND_BY; 177af55bae2SAxel Dörfler 178af55bae2SAxel Dörfler // start them off again 179af55bae2SAxel Dörfler 180af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_STAND_BY) { 181af55bae2SAxel Dörfler fStandByScreenRunner = new BMessageRunner(BMessenger(this), 182*41158aafSAxel Dörfler new BMessage(kMsgStandByScreen), fSettings.StandByTime(), 1); 183af55bae2SAxel Dörfler if (fStandByScreenRunner->InitCheck() != B_OK) 184af55bae2SAxel Dörfler syslog(LOG_ERR, "standby screen saver runner failed\n"); 185af55bae2SAxel Dörfler } 186af55bae2SAxel Dörfler 187af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_SUSPEND) { 188af55bae2SAxel Dörfler fSuspendScreenRunner = new BMessageRunner(BMessenger(this), 189*41158aafSAxel Dörfler new BMessage(kMsgSuspendScreen), fSettings.SuspendTime(), 1); 190af55bae2SAxel Dörfler if (fSuspendScreenRunner->InitCheck() != B_OK) 191af55bae2SAxel Dörfler syslog(LOG_ERR, "turn off screen saver runner failed\n"); 192af55bae2SAxel Dörfler } 193af55bae2SAxel Dörfler 194af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_OFF) { 195af55bae2SAxel Dörfler fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), 196*41158aafSAxel Dörfler new BMessage(kMsgTurnOffScreen), fSettings.OffTime(), 1); 197af55bae2SAxel Dörfler if (fTurnOffScreenRunner->InitCheck() != B_OK) 198af55bae2SAxel Dörfler syslog(LOG_ERR, "turn off screen saver runner failed\n"); 1997cae4a1eSAxel Dörfler } 2007cae4a1eSAxel Dörfler } 2017cae4a1eSAxel Dörfler 2027cae4a1eSAxel Dörfler 2037cae4a1eSAxel Dörfler void 2047cae4a1eSAxel Dörfler ScreenBlanker::MessageReceived(BMessage* message) 2057cae4a1eSAxel Dörfler { 2067cae4a1eSAxel Dörfler switch (message->what) { 207af55bae2SAxel Dörfler case kMsgUnlock: 2087cae4a1eSAxel Dörfler { 209*41158aafSAxel Dörfler if (strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(), 210*41158aafSAxel Dörfler fSettings.Password())) != 0) { 2117cae4a1eSAxel Dörfler beep(); 2127cae4a1eSAxel Dörfler fPasswordWindow->SetPassword(""); 213af55bae2SAxel Dörfler _QueueResumeScreenSaver(); 2147cae4a1eSAxel Dörfler } else { 2157cae4a1eSAxel Dörfler PRINT(("Quitting!\n")); 2167cae4a1eSAxel Dörfler _Shutdown(); 2177cae4a1eSAxel Dörfler Quit(); 2187cae4a1eSAxel Dörfler } 2197cae4a1eSAxel Dörfler break; 2207cae4a1eSAxel Dörfler } 2217cae4a1eSAxel Dörfler 222af55bae2SAxel Dörfler case kMsgResumeSaver: 2237cae4a1eSAxel Dörfler if (fWindow->Lock()) { 2247cae4a1eSAxel Dörfler if (fWindow->SetFullScreen(true) == B_OK) { 2257cae4a1eSAxel Dörfler HideCursor(); 2267cae4a1eSAxel Dörfler fPasswordWindow->Hide(); 2277cae4a1eSAxel Dörfler } 2287cae4a1eSAxel Dörfler 2297cae4a1eSAxel Dörfler fRunner->Resume(); 2307cae4a1eSAxel Dörfler fWindow->Unlock(); 2317cae4a1eSAxel Dörfler } 232af55bae2SAxel Dörfler 233af55bae2SAxel Dörfler _QueueTurnOffScreen(); 234af55bae2SAxel Dörfler break; 235af55bae2SAxel Dörfler 236af55bae2SAxel Dörfler case kMsgTurnOffScreen: 237af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_OFF); 238af55bae2SAxel Dörfler break; 239af55bae2SAxel Dörfler case kMsgSuspendScreen: 240af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_SUSPEND); 241af55bae2SAxel Dörfler break; 242af55bae2SAxel Dörfler case kMsgStandByScreen: 243af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_STAND_BY); 2447cae4a1eSAxel Dörfler break; 2457cae4a1eSAxel Dörfler 2467cae4a1eSAxel Dörfler default: 2477cae4a1eSAxel Dörfler BApplication::MessageReceived(message); 2487cae4a1eSAxel Dörfler break; 2497cae4a1eSAxel Dörfler } 2507cae4a1eSAxel Dörfler } 2517cae4a1eSAxel Dörfler 2527cae4a1eSAxel Dörfler 2537cae4a1eSAxel Dörfler bool 2547cae4a1eSAxel Dörfler ScreenBlanker::QuitRequested() 2557cae4a1eSAxel Dörfler { 256*41158aafSAxel Dörfler if (fSettings.LockEnable() 257*41158aafSAxel Dörfler && system_time() - fBlankTime > fSettings.PasswordTime() - fSettings.BlankTime()) { 2587cae4a1eSAxel Dörfler _ShowPasswordWindow(); 2597cae4a1eSAxel Dörfler return false; 2607cae4a1eSAxel Dörfler } 2617cae4a1eSAxel Dörfler 2627cae4a1eSAxel Dörfler _Shutdown(); 2637cae4a1eSAxel Dörfler return true; 2647cae4a1eSAxel Dörfler } 2657cae4a1eSAxel Dörfler 2667cae4a1eSAxel Dörfler 2677cae4a1eSAxel Dörfler void 2687cae4a1eSAxel Dörfler ScreenBlanker::_Shutdown() 2697cae4a1eSAxel Dörfler { 2707cae4a1eSAxel Dörfler delete fRunner; 2717cae4a1eSAxel Dörfler 2727cae4a1eSAxel Dörfler if (fWindow) 2737cae4a1eSAxel Dörfler fWindow->Hide(); 2747cae4a1eSAxel Dörfler } 2757cae4a1eSAxel Dörfler 2767cae4a1eSAxel Dörfler 2777cae4a1eSAxel Dörfler // #pragma mark - 2787cae4a1eSAxel Dörfler 2797cae4a1eSAxel Dörfler 2807cae4a1eSAxel Dörfler int 2817cae4a1eSAxel Dörfler main(int, char**) 2827cae4a1eSAxel Dörfler { 2837cae4a1eSAxel Dörfler ScreenBlanker app; 2847cae4a1eSAxel Dörfler app.Run(); 2857cae4a1eSAxel Dörfler return 0; 2867cae4a1eSAxel Dörfler } 287