Revamped the screensaver filter

It currently uses the R5 screen_blanker
It monitors screensaver settings, and screen_blanker run by ScreenSaver prefs


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13859 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2005-07-29 16:30:13 +00:00
parent 2826a379d5
commit 80f28ba092
3 changed files with 194 additions and 84 deletions
@@ -2,7 +2,8 @@ SubDir OBOS_TOP src add-ons input_server filters screensaver ;
UsePrivateHeaders screen_saver ; UsePrivateHeaders screen_saver ;
Addon screen_saver : input_server/filters : SSInputFilter.cpp ; Addon screen_saver : input_server/filters :
SSInputFilter.cpp
: false
: be libscreensaver.so <nogrist>input_server ;
LinkSharedOSLibs screen_saver
: be libscreensaver.so /system/servers/input_server ;
@@ -1,96 +1,183 @@
#include "OS.h" /*
#include "Roster.h" * Copyright 2003, Michael Phipps. All rights reserved.
#include "Screen.h" * Distributed under the terms of the MIT License.
#include "Application.h" */
#include <NodeMonitor.h>
#include <OS.h>
#include <Roster.h>
#include <Screen.h>
#include <Application.h>
#include "SSInputFilter.h" #include "SSInputFilter.h"
#include <Debug.h>
#define CALLED() SERIAL_PRINT(("%s\n", __PRETTY_FUNCTION__))
#define SCREEN_BLANKER_SIG "application/x-vnd.Be.screenblanker"
extern "C" _EXPORT BInputServerFilter* instantiate_input_filter(); extern "C" _EXPORT BInputServerFilter* instantiate_input_filter();
SSISFilter *fltr=NULL;
BInputServerFilter* instantiate_input_filter() { // required C func to build the IS Filter BInputServerFilter* instantiate_input_filter() { // required C func to build the IS Filter
return (fltr=new SSISFilter()); return (new SSInputFilter());
} }
int32 threadFunc (void *data) {
while (1) { SSController::SSController(SSInputFilter *filter)
snooze(fltr->getSnoozeTime()*1000000); // snoozeTime is in microseconds : BLooper("screensaver controller", B_LOW_PRIORITY),
fltr->CheckTime(); fFilter(filter)
{
CALLED();
}
void
SSController::MessageReceived(BMessage *msg)
{
CALLED();
SERIAL_PRINT(("what %lx\n", msg->what));
switch (msg->what) {
case B_NODE_MONITOR:
fFilter->ReloadSettings();
break;
case SS_CHECK_TIME:
fFilter->CheckTime();
break;
case B_SOME_APP_LAUNCHED:
{
const char *signature;
if (msg->FindString("be:signature", &signature)==B_OK
&& strcmp(signature, SCREEN_BLANKER_SIG)==0)
fFilter->SetEnabled();
SERIAL_PRINT(("mime_sig %s\n", signature));
break;
}
default:
BHandler::MessageReceived(msg);
} }
return B_OK; // Should never get here...
} }
SSISFilter::SSISFilter() : current(NONE),enabled(false),frameNum(0) {
pref.LoadSettings(); SSInputFilter::SSInputFilter()
blank=pref.GetBlankCorner(); : fCurrent(NONE),
keep=pref.GetNeverBlankCorner(); fEnabled(false),
blankTime=snoozeTime=pref.BlankTime(); fFrameNum(0),
watcher=spawn_thread(threadFunc,"ScreenSaverWatcher",0,NULL); fRunner(NULL) {
resume_thread(watcher); CALLED();
fSSController = new SSController(this);
fSSController->Run();
ReloadSettings();
BEntry entry(fPref.GetPath().Path());
entry.GetNodeRef(&fPrefNodeRef);
watch_node(&fPrefNodeRef, B_WATCH_ALL, NULL, fSSController);
be_roster->StartWatching(fSSController, B_REQUEST_LAUNCHED);
} }
void SSISFilter::Invoke(void) {
if ((current==keep) || enabled) SSInputFilter::~SSInputFilter() {
delete fRunner;
watch_node(&fPrefNodeRef, B_STOP_WATCHING, NULL);
be_roster->StopWatching(fSSController);
delete fSSController;
}
void
SSInputFilter::Invoke()
{
CALLED();
if ((fKeep!=NONE && fCurrent == fKeep) || fEnabled || fPref.TimeFlags()!=1)
return; // If mouse is in this corner, never invoke. return; // If mouse is in this corner, never invoke.
be_roster->Launch("application/x-vnd.OBOS-ScreenSaverApp"); SERIAL_PRINT(("we run screenblanker\n"));
enabled=true; if (be_roster->Launch("application/x-vnd.Be.screenblanker")==B_OK)
fEnabled = true;
} }
void SSISFilter::Banish(void) {
BMessenger ssApp ("application/x-vnd.OBOS-ScreenSaverApp",-1,NULL); // Don't care if it fails void
ssApp.SendMessage('MOO1'); SSInputFilter::ReloadSettings()
enabled=false; {
CALLED();
fPref.LoadSettings();
fBlank = fPref.GetBlankCorner();
fKeep = fPref.GetNeverBlankCorner();
fBlankTime = fSnoozeTime = fPref.BlankTime();
CheckTime();
delete fRunner;
fRunner = new BMessageRunner(BMessenger(NULL, fSSController), new BMessage(SS_CHECK_TIME), fSnoozeTime, -1);
} }
void SSISFilter::CheckTime(void) {
if ((rtc=real_time_clock())>=lastEventTime+blankTime) void
SSInputFilter::Banish()
{
CALLED();
if (!fEnabled)
return;
BMessenger ssApp (SCREEN_BLANKER_SIG,-1,NULL); // Don't care if it fails
ssApp.SendMessage(B_QUIT_REQUESTED);
fEnabled = false;
}
void
SSInputFilter::CheckTime() {
CALLED();
fRtc = system_time();
if (fRtc >= fLastEventTime + fBlankTime)
Invoke(); Invoke();
// If the screen saver is on OR it was time to come on but it didn't (corner), snooze for blankTime // If the screen saver is on OR it was time to come on but it didn't (corner), snooze for blankTime
// Otherwise, there was an event in the middle of the last snooze, so snooze for the remainder // Otherwise, there was an event in the middle of the last snooze, so snooze for the remainder
snoozeTime=(enabled || (lastEventTime+blankTime<=rtc))?blankTime:lastEventTime+blankTime-rtc; if (fEnabled || (fLastEventTime+fBlankTime<=fRtc))
fSnoozeTime = fBlankTime;
else
fSnoozeTime = fLastEventTime + fBlankTime - fRtc;
} }
void SSISFilter::UpdateRectangles(void) { void
BScreen screen; SSInputFilter::UpdateRectangles() {
BRect frame=screen.Frame(); CALLED();
BRect frame = BScreen().Frame();
topLeft.Set(frame.left,frame.top,frame.left+CORNER_SIZE,frame.top+CORNER_SIZE); fTopLeft.Set(frame.left,frame.top,frame.left+CORNER_SIZE,frame.top+CORNER_SIZE);
topRight.Set(frame.right-CORNER_SIZE,frame.top,frame.right,frame.top+CORNER_SIZE); fTopRight.Set(frame.right-CORNER_SIZE,frame.top,frame.right,frame.top+CORNER_SIZE);
bottomLeft.Set(frame.left,frame.bottom-CORNER_SIZE,frame.left+CORNER_SIZE,frame.bottom); fBottomLeft.Set(frame.left,frame.bottom-CORNER_SIZE,frame.left+CORNER_SIZE,frame.bottom);
bottomRight.Set(frame.right-CORNER_SIZE,frame.bottom-CORNER_SIZE,frame.right,frame.bottom); fBottomRight.Set(frame.right-CORNER_SIZE,frame.bottom-CORNER_SIZE,frame.right,frame.bottom);
} }
void SSISFilter::Cornered(arrowDirection pos) {
current=pos; void
if (pos==blank) SSInputFilter::Cornered(arrowDirection pos) {
//CALLED();
fCurrent = pos;
if (fBlank != NONE && pos == fBlank)
Invoke(); Invoke();
} }
filter_result SSISFilter::Filter(BMessage *msg,BList *outList) {
lastEventTime=real_time_clock(); filter_result
SSInputFilter::Filter(BMessage *msg,BList *outList) {
fLastEventTime = system_time();
if (msg->what==B_MOUSE_MOVED) { if (msg->what==B_MOUSE_MOVED) {
BPoint pos; BPoint pos;
msg->FindPoint("where",&pos); msg->FindPoint("where",&pos);
if ((frameNum++ % 32)==0) // Every so many frames, update if ((fFrameNum++ % 32)==0) // Every so many frames, update
UpdateRectangles(); UpdateRectangles();
if (topLeft.Contains(pos)) if (fTopLeft.Contains(pos))
Cornered(UPLEFT); Cornered(UPLEFT);
else if (topRight.Contains(pos)) else if (fTopRight.Contains(pos))
Cornered(UPRIGHT); Cornered(UPRIGHT);
else if (bottomLeft.Contains(pos)) else if (fBottomLeft.Contains(pos))
Cornered(DOWNLEFT); Cornered(DOWNLEFT);
else if (bottomRight.Contains(pos)) else if (fBottomRight.Contains(pos))
Cornered(DOWNRIGHT); Cornered(DOWNRIGHT);
else { else {
Cornered(NONE); Cornered(NONE);
Banish(); Banish();
}
} }
else } else
Banish(); Banish();
return B_DISPATCH_MESSAGE;
} }
SSISFilter::~SSISFilter() {
;
}
@@ -1,37 +1,59 @@
#include "InputServerFilter.h" /*
#include "Rect.h" * Copyright 2003, Michael Phipps. All rights reserved.
#include "Region.h" * Distributed under the terms of the MIT License.
#include "Messenger.h" */
#include "MessageFilter.h"
#include "MessageRunner.h" #include <InputServerFilter.h>
#include <Rect.h>
#include <Region.h>
#include <Messenger.h>
#include <MessageFilter.h>
#include <MessageRunner.h>
#include <Node.h>
#include "ScreenSaverPrefs.h" #include "ScreenSaverPrefs.h"
const int CORNER_SIZE=10; const int CORNER_SIZE = 10;
const int timeUp='TMUP'; const int32 SS_CHECK_TIME = 'SSCT';
int32 threadFunc(void *); class SSInputFilter;
class SSISFilter: public BInputServerFilter class SSController : public BLooper
{ {
public: public:
SSISFilter(); SSController(SSInputFilter *filter);
virtual ~SSISFilter(); void MessageReceived(BMessage *msg);
virtual filter_result Filter(BMessage *msg, BList *outList);
void CheckTime(void);
uint32 getSnoozeTime(void) {return snoozeTime;}
private: private:
uint32 lastEventTime,blankTime,snoozeTime,rtc; SSInputFilter* fFilter;
arrowDirection blank, keep, current; };
bool enabled;
BRect topLeft,topRight,bottomLeft,bottomRight; class SSInputFilter : public BInputServerFilter
ScreenSaverPrefs pref; {
thread_id watcher; public:
char frameNum; // Used so that we don't update the screen coord's so often SSInputFilter();
// Ideally, we would get a message when the screen changes. R5 doesn't do this. virtual ~SSInputFilter();
virtual filter_result Filter(BMessage *msg, BList *outList);
void UpdateRectangles(void); void CheckTime();
void Cornered(arrowDirection pos); uint32 GetSnoozeTime(void) {return fSnoozeTime;}
void Invoke(void); void ReloadSettings();
void Banish(void); void SetEnabled() { fEnabled = true; }
private:
//static int32 ThreadFunc(void *);
bigtime_t fLastEventTime, fBlankTime, fSnoozeTime, fRtc;
arrowDirection fBlank, fKeep, fCurrent;
bool fEnabled;
BRect fTopLeft, fTopRight, fBottomLeft, fBottomRight;
ScreenSaverPrefs fPref;
//thread_id fWatcher;
uint32 fFrameNum; // Used so that we don't update the screen coord's so often
// Ideally, we would get a message when the screen changes. R5 doesn't do this.
SSController *fSSController;
node_ref fPrefNodeRef;
//sem_id fSnoozeSem;
BMessageRunner *fRunner;
void UpdateRectangles();
void Cornered(arrowDirection pos);
void Invoke();
void Banish();
}; };