diff --git a/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.cpp b/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.cpp index 946843a60e..0d144e95a5 100644 --- a/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.cpp +++ b/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2003-2008, Haiku. + * Copyright 2003-2009, 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 + * Ryan Leavengood, leavengood@gmail.com */ @@ -19,11 +20,8 @@ #include #include -#include - #include - -#define CALLED() SERIAL_PRINT(("%s\n", __PRETTY_FUNCTION__)) +#include static const int32 kNeverBlankCornerSize = 10; @@ -38,8 +36,7 @@ static const int32 kMsgCornerInvoke = 'Scin'; extern "C" _EXPORT BInputServerFilter* instantiate_input_filter(); -/** required C func to build the IS Filter */ - +/** Required C func to build the IS Filter */ BInputServerFilter* instantiate_input_filter() { @@ -54,16 +51,12 @@ ScreenSaverController::ScreenSaverController(ScreenSaverFilter *filter) : BLooper("screensaver controller", B_LOW_PRIORITY), fFilter(filter) { - CALLED(); } void ScreenSaverController::MessageReceived(BMessage *message) { - CALLED(); - SERIAL_PRINT(("what %lx\n", message->what)); - switch (message->what) { case B_NODE_MONITOR: fFilter->ReloadSettings(); @@ -76,14 +69,9 @@ ScreenSaverController::MessageReceived(BMessage *message) && strcasecmp(signature, SCREEN_BLANKER_SIG) == 0) { fFilter->SetEnabled(message->what == B_SOME_APP_LAUNCHED); } - SERIAL_PRINT(("mime_sig %s\n", signature)); break; } - case kMsgSuspendScreenSaver: - //fFilter->Suspend(msg); - break; - case kMsgCheckTime: fFilter->CheckTime(); break; @@ -114,7 +102,6 @@ ScreenSaverFilter::ScreenSaverFilter() fWatchingFile(false), fEnabled(false) { - CALLED(); fController = new (std::nothrow) ScreenSaverController(this); if (fController == NULL) return; @@ -185,40 +172,20 @@ ScreenSaverFilter::_WatchSettings() void ScreenSaverFilter::_Invoke() { - CALLED(); if (fCurrentCorner == fNeverBlankCorner && fNeverBlankCorner != NO_CORNER || fSettings.TimeFlags() == SAVER_DISABLED || fEnabled || be_roster->IsRunning(SCREEN_BLANKER_SIG)) return; - SERIAL_PRINT(("we run screenblanker\n")); if (be_roster->Launch(SCREEN_BLANKER_SIG) == B_OK) fEnabled = true; } -/*! Stops the running screen saver, if any */ -void -ScreenSaverFilter::_Banish() -{ - CALLED(); - if (!fEnabled) - return; - - SERIAL_PRINT(("we quit screenblanker\n")); - - // Don't care if it fails - BMessenger blankerMessenger(SCREEN_BLANKER_SIG, -1, NULL); - blankerMessenger.SendMessage(B_QUIT_REQUESTED); - fEnabled = false; -} - - void ScreenSaverFilter::ReloadSettings() { - CALLED(); BAutolock _(this); bool isFirst = !fWatchingDirectory && !fWatchingFile; @@ -251,7 +218,7 @@ ScreenSaverFilter::ReloadSettings() fRunner = new (std::nothrow) BMessageRunner(fController, &check, fSnoozeTime); if (fRunner == NULL || fRunner->InitCheck() != B_OK) { - SERIAL_PRINT(("screen saver filter runner init failed\n")); + syslog(LOG_ERR, "screen saver filter runner init failed\n"); } } @@ -267,7 +234,6 @@ ScreenSaverFilter::SetEnabled(bool enabled) void ScreenSaverFilter::CheckTime() { - CALLED(); BAutolock _(this); bigtime_t now = system_time(); @@ -307,9 +273,6 @@ ScreenSaverFilter::CheckCornerInvoke() void ScreenSaverFilter::_UpdateRectangles() { - // TODO: make this better if possible at all (in a clean way) - CALLED(); - fBlankRect = _ScreenCorner(fBlankCorner, kBlankCornerSize); fNeverBlankRect = _ScreenCorner(fNeverBlankCorner, kNeverBlankCornerSize); } @@ -382,20 +345,8 @@ ScreenSaverFilter::Filter(BMessage *message, BList *outList) fCurrentCorner = NO_CORNER; break; } - - case B_KEY_UP: - case B_KEY_DOWN: - { - // we ignore the Print-Screen key to make screen shots of - // screen savers possible - int32 key; - if (fEnabled && message->FindInt32("key", &key) == B_OK - && key == 0xe) - return B_DISPATCH_MESSAGE; - } } - _Banish(); return B_DISPATCH_MESSAGE; } diff --git a/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.h b/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.h index 8d70a96054..b98b1aaf89 100644 --- a/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.h +++ b/src/add-ons/input_server/filters/screen_saver/ScreenSaverFilter.h @@ -19,8 +19,6 @@ #include -static const uint32 kMsgSuspendScreenSaver = 'susp'; - class BMessageRunner; class ScreenSaverFilter; @@ -59,7 +57,6 @@ private: uint32 cornerSize); void _Invoke(); - void _Banish(); ScreenSaverSettings fSettings; bigtime_t fLastEventTime; diff --git a/src/bin/screen_blanker/ScreenBlanker.cpp b/src/bin/screen_blanker/ScreenBlanker.cpp index ea3c45985a..59dafbc154 100644 --- a/src/bin/screen_blanker/ScreenBlanker.cpp +++ b/src/bin/screen_blanker/ScreenBlanker.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2003-2007, Haiku. + * Copyright 2003-2009, 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 + * Ryan Leavengood, leavengood@gmail.com */ @@ -58,8 +59,7 @@ void ScreenBlanker::ReadyToRun() { if (!fSettings.Load()) { - fprintf(stderr, "could not load settings\n"); - exit(1); + fprintf(stderr, "could not load settings, using defaults\n"); } // create a BDirectWindow and start the render thread. @@ -123,7 +123,8 @@ ScreenBlanker::_ShowPasswordWindow() fWindow->Sync(); // TODO: is that needed? ShowCursor(); - fPasswordWindow->Show(); + if (fPasswordWindow->IsHidden()) + fPasswordWindow->Show(); fWindow->Unlock(); } @@ -193,7 +194,7 @@ ScreenBlanker::_QueueTurnOffScreen() fSuspendScreenRunner = new BMessageRunner(BMessenger(this), &dpms, fSettings.SuspendTime(), 1); if (fSuspendScreenRunner->InitCheck() != B_OK) - syslog(LOG_ERR, "turn off screen saver runner failed\n"); + syslog(LOG_ERR, "suspend screen saver runner failed\n"); } if (flags & ENABLE_DPMS_OFF) { @@ -226,6 +227,7 @@ ScreenBlanker::MessageReceived(BMessage* message) } case kMsgResumeSaver: + { if (fWindow->Lock()) { HideCursor(); fPasswordWindow->Hide(); @@ -234,8 +236,13 @@ ScreenBlanker::MessageReceived(BMessage* message) fWindow->Unlock(); } + // Turn on the message filter again + BMessage enable(kMsgEnableFilter); + BMessenger(fWindow).SendMessage(&enable); + _QueueTurnOffScreen(); break; + } case kMsgTurnOffScreen: _SetDPMSMode(B_DPMS_OFF); diff --git a/src/bin/screen_blanker/ScreenSaverWindow.cpp b/src/bin/screen_blanker/ScreenSaverWindow.cpp index cd6ba7d922..11cc301ef7 100644 --- a/src/bin/screen_blanker/ScreenSaverWindow.cpp +++ b/src/bin/screen_blanker/ScreenSaverWindow.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2003-2008, Haiku. + * Copyright 2003-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Michael Phipps * Jérôme Duval, jerome.duval@free.fr + * Ryan Leavengood, leavengood@gmail.com */ @@ -15,6 +16,44 @@ #include +#include + + +/* This message filter is what will close the screensaver upon user activity. */ +filter_result +ScreenSaverFilter::Filter(BMessage* message, BHandler** target) +{ + // This guard is used to avoid sending multiple B_QUIT_REQUESTED messages + if (fEnabled) { + switch (message->what) { + case B_KEY_DOWN: + { + // we ignore the Print-Screen key to make screen shots of + // screen savers possible + int32 key; + if (message->FindInt32("key", &key) == B_OK && key == 0xe) + return B_DISPATCH_MESSAGE; + + // Fall through + } + case B_MOUSE_MOVED: + case B_MOUSE_DOWN: + fEnabled = false; + be_app->PostMessage(B_QUIT_REQUESTED); + break; + } + } + + return B_DISPATCH_MESSAGE; +} + + +void +ScreenSaverFilter::SetEnabled(bool enabled) +{ + fEnabled = enabled; +} + /*! This is the BDirectWindow subclass that rendering occurs in. @@ -29,13 +68,31 @@ ScreenSaverWindow::ScreenSaverWindow(BRect frame) frame.OffsetTo(0, 0); fTopView = new BView(frame, "ScreenSaver View", B_FOLLOW_ALL, B_WILL_DRAW); fTopView->SetViewColor(0, 0, 0); + + fFilter = new ScreenSaverFilter(); + fTopView->AddFilter(fFilter); + AddChild(fTopView); + + // Ensure that this view receives keyboard input + fTopView->MakeFocus(true); + fTopView->SetEventMask(B_KEYBOARD_EVENTS, 0); + + // A delay is necessary (250ms was chosen arbitrarily) before enabling the + // message filter because when the window first shows some mouse moved + // messages are sent to it automatically. + BMessage enable(kMsgEnableFilter); + fEnableRunner = new BMessageRunner(BMessenger(this), &enable, 250000LL, 1); + if (fEnableRunner->InitCheck() != B_OK) + syslog(LOG_ERR, "Runner to enable screen saver message filtering failed!\n"); } ScreenSaverWindow::~ScreenSaverWindow() { Hide(); + delete fEnableRunner; + delete fFilter; } @@ -46,6 +103,21 @@ ScreenSaverWindow::SetSaver(BScreenSaver *saver) } +void +ScreenSaverWindow::MessageReceived(BMessage *message) +{ + switch (message->what) { + case kMsgEnableFilter: + fFilter->SetEnabled(true); + break; + + default: + BWindow::MessageReceived(message); + break; + } +} + + bool ScreenSaverWindow::QuitRequested() { diff --git a/src/bin/screen_blanker/ScreenSaverWindow.h b/src/bin/screen_blanker/ScreenSaverWindow.h index bbedf54892..54bfd71ab0 100644 --- a/src/bin/screen_blanker/ScreenSaverWindow.h +++ b/src/bin/screen_blanker/ScreenSaverWindow.h @@ -9,6 +9,26 @@ #include "ScreenSaver.h" #include +#include +#include + + +const static uint32 kMsgEnableFilter = 'eflt'; + + +class ScreenSaverFilter : public BMessageFilter { + public: + ScreenSaverFilter() + : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE), + fEnabled(false) {} + + virtual filter_result Filter(BMessage* message, BHandler** target); + + void SetEnabled(bool enabled); + + private: + bool fEnabled; +}; class ScreenSaverWindow : public BDirectWindow { @@ -18,12 +38,15 @@ class ScreenSaverWindow : public BDirectWindow { void SetSaver(BScreenSaver *saver); + virtual void MessageReceived(BMessage *message); virtual bool QuitRequested(); virtual void DirectConnected(direct_buffer_info *info); private: BView *fTopView; BScreenSaver *fSaver; + ScreenSaverFilter *fFilter; + BMessageRunner *fEnableRunner; }; #endif // SCREEN_SAVER_WINDOW_H