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*642090fdSAxel Dörfler if (!fSettings.Load()) { 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(); 7041158aafSAxel 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; 140d0e9fa68SAxel Dörfler 141d0e9fa68SAxel Dörfler BMessage resume(kMsgResumeSaver); 142d0e9fa68SAxel Dörfler fResumeRunner = new BMessageRunner(BMessenger(this), &resume, 14341158aafSAxel Dörfler fSettings.BlankTime(), 1); 144af55bae2SAxel Dörfler if (fResumeRunner->InitCheck() != B_OK) 145af55bae2SAxel Dörfler syslog(LOG_ERR, "resume screen saver runner failed\n"); 146af55bae2SAxel Dörfler } 147af55bae2SAxel Dörfler 148af55bae2SAxel Dörfler 149af55bae2SAxel Dörfler void 150af55bae2SAxel Dörfler ScreenBlanker::_QueueTurnOffScreen() 151af55bae2SAxel Dörfler { 152af55bae2SAxel Dörfler // stop running notifiers 153af55bae2SAxel Dörfler 154af55bae2SAxel Dörfler delete fStandByScreenRunner; 155af55bae2SAxel Dörfler delete fSuspendScreenRunner; 156af55bae2SAxel Dörfler delete fTurnOffScreenRunner; 157af55bae2SAxel Dörfler 158af55bae2SAxel Dörfler fStandByScreenRunner = fSuspendScreenRunner = fTurnOffScreenRunner = NULL; 159af55bae2SAxel Dörfler 160af55bae2SAxel Dörfler // figure out which notifiers we need and which of them are supported 161af55bae2SAxel Dörfler 16241158aafSAxel Dörfler uint32 flags = fSettings.TimeFlags(); 163af55bae2SAxel Dörfler BScreen screen; 164af55bae2SAxel Dörfler uint32 capabilities = screen.DPMSCapabilites(); 165af55bae2SAxel Dörfler if ((capabilities & B_DPMS_OFF) == 0) 166af55bae2SAxel Dörfler flags &= ENABLE_DPMS_OFF; 167af55bae2SAxel Dörfler if ((capabilities & B_DPMS_SUSPEND) == 0) 168af55bae2SAxel Dörfler flags &= ENABLE_DPMS_SUSPEND; 169af55bae2SAxel Dörfler if ((capabilities & B_DPMS_STAND_BY) == 0) 170af55bae2SAxel Dörfler flags &= ENABLE_DPMS_STAND_BY; 171af55bae2SAxel Dörfler 172af55bae2SAxel Dörfler if ((flags & ENABLE_DPMS_MASK) == 0) 173af55bae2SAxel Dörfler return; 174af55bae2SAxel Dörfler 17541158aafSAxel Dörfler if (fSettings.OffTime() == fSettings.SuspendTime()) 176af55bae2SAxel Dörfler flags &= ENABLE_DPMS_SUSPEND; 17741158aafSAxel Dörfler if (fSettings.SuspendTime() == fSettings.StandByTime()) 178af55bae2SAxel Dörfler flags &= ENABLE_DPMS_STAND_BY; 179af55bae2SAxel Dörfler 180af55bae2SAxel Dörfler // start them off again 181af55bae2SAxel Dörfler 182af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_STAND_BY) { 183d0e9fa68SAxel Dörfler BMessage dpms(kMsgStandByScreen); 184d0e9fa68SAxel Dörfler fStandByScreenRunner = new BMessageRunner(BMessenger(this), &dpms, 185d0e9fa68SAxel Dörfler fSettings.StandByTime(), 1); 186af55bae2SAxel Dörfler if (fStandByScreenRunner->InitCheck() != B_OK) 187af55bae2SAxel Dörfler syslog(LOG_ERR, "standby screen saver runner failed\n"); 188af55bae2SAxel Dörfler } 189af55bae2SAxel Dörfler 190af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_SUSPEND) { 191d0e9fa68SAxel Dörfler BMessage dpms(kMsgSuspendScreen); 192d0e9fa68SAxel Dörfler fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms, 193d0e9fa68SAxel Dörfler fSettings.SuspendTime(), 1); 194af55bae2SAxel Dörfler if (fSuspendScreenRunner->InitCheck() != B_OK) 195af55bae2SAxel Dörfler syslog(LOG_ERR, "turn off screen saver runner failed\n"); 196af55bae2SAxel Dörfler } 197af55bae2SAxel Dörfler 198af55bae2SAxel Dörfler if (flags & ENABLE_DPMS_OFF) { 199d0e9fa68SAxel Dörfler BMessage dpms(kMsgTurnOffScreen); 200d0e9fa68SAxel Dörfler fTurnOffScreenRunner = new BMessageRunner(BMessenger(this), &dpms, 201d0e9fa68SAxel Dörfler fSettings.OffTime(), 1); 202af55bae2SAxel Dörfler if (fTurnOffScreenRunner->InitCheck() != B_OK) 203af55bae2SAxel Dörfler syslog(LOG_ERR, "turn off screen saver runner failed\n"); 2047cae4a1eSAxel Dörfler } 2057cae4a1eSAxel Dörfler } 2067cae4a1eSAxel Dörfler 2077cae4a1eSAxel Dörfler 2087cae4a1eSAxel Dörfler void 2097cae4a1eSAxel Dörfler ScreenBlanker::MessageReceived(BMessage* message) 2107cae4a1eSAxel Dörfler { 2117cae4a1eSAxel Dörfler switch (message->what) { 212af55bae2SAxel Dörfler case kMsgUnlock: 2137cae4a1eSAxel Dörfler { 21441158aafSAxel Dörfler if (strcmp(fSettings.Password(), crypt(fPasswordWindow->Password(), 21541158aafSAxel Dörfler fSettings.Password())) != 0) { 2167cae4a1eSAxel Dörfler beep(); 2177cae4a1eSAxel Dörfler fPasswordWindow->SetPassword(""); 218af55bae2SAxel Dörfler _QueueResumeScreenSaver(); 2197cae4a1eSAxel Dörfler } else { 2207cae4a1eSAxel Dörfler PRINT(("Quitting!\n")); 2217cae4a1eSAxel Dörfler _Shutdown(); 2227cae4a1eSAxel Dörfler Quit(); 2237cae4a1eSAxel Dörfler } 2247cae4a1eSAxel Dörfler break; 2257cae4a1eSAxel Dörfler } 2267cae4a1eSAxel Dörfler 227af55bae2SAxel Dörfler case kMsgResumeSaver: 2287cae4a1eSAxel Dörfler if (fWindow->Lock()) { 2297cae4a1eSAxel Dörfler if (fWindow->SetFullScreen(true) == B_OK) { 2307cae4a1eSAxel Dörfler HideCursor(); 2317cae4a1eSAxel Dörfler fPasswordWindow->Hide(); 2327cae4a1eSAxel Dörfler } 2337cae4a1eSAxel Dörfler 2347cae4a1eSAxel Dörfler fRunner->Resume(); 2357cae4a1eSAxel Dörfler fWindow->Unlock(); 2367cae4a1eSAxel Dörfler } 237af55bae2SAxel Dörfler 238af55bae2SAxel Dörfler _QueueTurnOffScreen(); 239af55bae2SAxel Dörfler break; 240af55bae2SAxel Dörfler 241af55bae2SAxel Dörfler case kMsgTurnOffScreen: 242af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_OFF); 243af55bae2SAxel Dörfler break; 244af55bae2SAxel Dörfler case kMsgSuspendScreen: 245af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_SUSPEND); 246af55bae2SAxel Dörfler break; 247af55bae2SAxel Dörfler case kMsgStandByScreen: 248af55bae2SAxel Dörfler _SetDPMSMode(B_DPMS_STAND_BY); 2497cae4a1eSAxel Dörfler break; 2507cae4a1eSAxel Dörfler 2517cae4a1eSAxel Dörfler default: 2527cae4a1eSAxel Dörfler BApplication::MessageReceived(message); 2537cae4a1eSAxel Dörfler break; 2547cae4a1eSAxel Dörfler } 2557cae4a1eSAxel Dörfler } 2567cae4a1eSAxel Dörfler 2577cae4a1eSAxel Dörfler 2587cae4a1eSAxel Dörfler bool 2597cae4a1eSAxel Dörfler ScreenBlanker::QuitRequested() 2607cae4a1eSAxel Dörfler { 26141158aafSAxel Dörfler if (fSettings.LockEnable() 26241158aafSAxel Dörfler && system_time() - fBlankTime > fSettings.PasswordTime() - fSettings.BlankTime()) { 2637cae4a1eSAxel Dörfler _ShowPasswordWindow(); 2647cae4a1eSAxel Dörfler return false; 2657cae4a1eSAxel Dörfler } 2667cae4a1eSAxel Dörfler 2677cae4a1eSAxel Dörfler _Shutdown(); 2687cae4a1eSAxel Dörfler return true; 2697cae4a1eSAxel Dörfler } 2707cae4a1eSAxel Dörfler 2717cae4a1eSAxel Dörfler 2727cae4a1eSAxel Dörfler void 2737cae4a1eSAxel Dörfler ScreenBlanker::_Shutdown() 2747cae4a1eSAxel Dörfler { 2757cae4a1eSAxel Dörfler delete fRunner; 2767cae4a1eSAxel Dörfler 277d0e9fa68SAxel Dörfler if (fWindow) { 2787cae4a1eSAxel Dörfler fWindow->Hide(); 279d0e9fa68SAxel Dörfler 280d0e9fa68SAxel Dörfler if (fWindow->Lock()) 281d0e9fa68SAxel Dörfler fWindow->Quit(); 282d0e9fa68SAxel Dörfler } 2837cae4a1eSAxel Dörfler } 2847cae4a1eSAxel Dörfler 2857cae4a1eSAxel Dörfler 2867cae4a1eSAxel Dörfler // #pragma mark - 2877cae4a1eSAxel Dörfler 2887cae4a1eSAxel Dörfler 2897cae4a1eSAxel Dörfler int 2907cae4a1eSAxel Dörfler main(int, char**) 2917cae4a1eSAxel Dörfler { 2927cae4a1eSAxel Dörfler ScreenBlanker app; 2937cae4a1eSAxel Dörfler app.Run(); 2947cae4a1eSAxel Dörfler return 0; 2957cae4a1eSAxel Dörfler } 296