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:
@@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user