diff --git a/src/servers/screensaver/Jamfile b/src/servers/screensaver/Jamfile index 2a92ac1148..6bf81d1afa 100644 --- a/src/servers/screensaver/Jamfile +++ b/src/servers/screensaver/Jamfile @@ -2,9 +2,8 @@ SubDir OBOS_TOP src servers screensaver ; Server OBOSscreensaver : ScreenSaverApp.cpp + ScreenSaverPrefs.cpp SSAwindow.cpp - SSthread.cpp -# Was in the makefile sources list, but it didn't make because of that. -# pwWindow.cpp + ScreenSaverThread.cpp ; -LinkSharedOSLibs OBOSscreensaver : be game ; +LinkSharedOSLibs OBOSscreensaver : be game screensaver ; diff --git a/src/servers/screensaver/SSAwindow.cpp b/src/servers/screensaver/SSAwindow.cpp index 7fcc21e3a8..d3c7f9b7c2 100644 --- a/src/servers/screensaver/SSAwindow.cpp +++ b/src/servers/screensaver/SSAwindow.cpp @@ -3,38 +3,36 @@ #include "View.h" #include #include - -extern void callDirectConnected(direct_buffer_info *); -extern BView *view; +#include // This is the BDirectWindow subclass that rendering occurs in. // A view is added to it so that BView based screensavers will work. -SSAwindow::SSAwindow(BRect frame) : BDirectWindow(frame, "ScreenSaver Window", - B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE) - { - frame.OffsetTo(0.0,0.0); +SSAwindow::SSAwindow(BRect frame,BScreenSaver *saverIn) : BDirectWindow(frame, "ScreenSaver Window", + B_BORDERED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE) { + frame.OffsetTo(0,0); view=new BView(frame,"ScreenSaver View",B_FOLLOW_ALL,B_WILL_DRAW); AddChild (view); - view->Frame().PrintToStream(); - view->SetOrigin(0.0,0.0); - - // SetFullScreen(true); + saver=saverIn; } -SSAwindow::~SSAwindow() - { - int32 result; - +SSAwindow::~SSAwindow() { Hide(); Sync(); } -bool SSAwindow::QuitRequested(void) - { +bool SSAwindow::QuitRequested(void) { return true; } -void SSAwindow::DirectConnected(direct_buffer_info *info) - { - callDirectConnected(info); +void SSAwindow::DirectConnected(direct_buffer_info *info) { + /* + int i=info->buffer_state; + printf ("direct connected; bufState=%d; bits = %x, bpr=%d, bottom=%d\n",i,info->bits,info->bytes_per_row,info->window_bounds.bottom); + if (!(i&B_DIRECT_STOP)) { + printf ("ready to clear; bits = %x, bpr=%d, bottom=%d\n",info->bits,info->bytes_per_row,info->window_bounds.bottom); + memset(info->bits,0,info->bytes_per_row*info->window_bounds.bottom); + } + */ + if (saver) + saver->DirectConnected(info); } diff --git a/src/servers/screensaver/SSAwindow.h b/src/servers/screensaver/SSAwindow.h index 94c7e5d95d..179692377a 100644 --- a/src/servers/screensaver/SSAwindow.h +++ b/src/servers/screensaver/SSAwindow.h @@ -1,9 +1,13 @@ #include "DirectWindow.h" +#include "ScreenSaver.h" class SSAwindow : public BDirectWindow { public: - SSAwindow(BRect frame); + SSAwindow(BRect frame,BScreenSaver *saverIn); ~SSAwindow(); virtual bool QuitRequested(); virtual void DirectConnected(direct_buffer_info *info); + BView *view; +private: + BScreenSaver *saver; }; diff --git a/src/servers/screensaver/ScreenSaverApp.cpp b/src/servers/screensaver/ScreenSaverApp.cpp index 4ae719d30b..368ac417b1 100755 --- a/src/servers/screensaver/ScreenSaverApp.cpp +++ b/src/servers/screensaver/ScreenSaverApp.cpp @@ -6,258 +6,96 @@ #include "image.h" #include "StorageDefs.h" #include "FindDirectory.h" +#include "SupportDefs.h" #include "File.h" #include "Path.h" #include "string.h" +#include "Alert.h" -extern int32 screenSaverThread(void *); -class BScreenSaver; - -// Yes, these are all global variables. They are shared between the thread -// and this app. -SSstates nextAction; -int32 frame; -BView *view; -BScreenSaver *saver; -sem_id ssSem; -SSAwindow *win; - -extern void callSaverDelete (void); - -/* General note on how this works: - * The semaphore (ssSem) is used to start and stop the render thread. - * When it is time to go blank, the ScreenSaver app thread releases - * the semaphore. The render thread was blocked waiting for it. - * When it is time to stop, the shared variable (nextAction) is set to STOP. - * The thread stops and acquires the semaphore, so that it waits... -*/ // Start the server application. Set pulse to fire once per second. // Run until the application quits. -int main(int, char**) -{ +int main(int, char**) { ScreenSaverApp myApplication; - myApplication.SetPulseRate(1000000); // Fire once per second. - ssSem=create_sem(0,"ScreenSaverSemaphore"); - nextAction=STOP; myApplication.Run(); return(0); } // Construct the server app. Doesn't do much, at this point. -ScreenSaverApp::ScreenSaverApp() : BApplication("application/x-vnd.OBOS-ScreenSaverApp") -{ - addon_image=0; - currentTime=0; - win=NULL; +ScreenSaverApp::ScreenSaverApp() : BApplication("application/x-vnd.OBOS-ScreenSaverApp"),addon_image(0),win(NULL) { } - -// This is the main message loop. It spawns a thread that actually runs the screen saver. -void ScreenSaverApp::DispatchMessage(BMessage *msg,BHandler *target) -{ - switch (msg->what) - { - case B_READY_TO_RUN: - { - threadID=spawn_thread(screenSaverThread,"Screen Saver Thread",0,NULL); - LoadSettings(); - // If everything works OK, create a BDirectWindow and start the render thread. - BScreen theScreen(B_MAIN_SCREEN_ID); - win=new SSAwindow(theScreen.Frame()); - resume_thread(threadID); - } - break; - case 'TOPL': - case 'TOPR': - case 'BOTL': - case 'BOTR': - case 'ENDC': - { - if (cornerNow==msg->what) - goBlank(); - else if (cornerNever==msg->what) - disabled=true; - else // We are in the middle or some other corner - { - disabled=false; - unBlank(); - } - } - case 'INPT': - unBlank(); - break; - case NEWDURATION: - int32 dur; - msg->FindInt32("duration",&dur); - setNewDuration(dur); - break; - case B_PULSE: - if (++currentTime==blankTime) - goBlank(); - break; - case B_QUIT_REQUESTED: - nextAction=EXIT; - status_t dummy; // The thread has no return value - wait_for_thread(threadID,&dummy); - BApplication::QuitRequested(); - break; - default: - printf ("Unknown message! %d\n",msg->what); - break; +void ScreenSaverApp::ReadyToRun(void) { + if (!pref.LoadSettings() || (!LoadAddOn())) + exit(1); + else { // If everything works OK, create a BDirectWindow and start the render thread. + BScreen theScreen(B_MAIN_SCREEN_ID); + win=new SSAwindow(theScreen.Frame(),saver); + thrd=new ScreenSaverThread(saver,win,win->view,&pref); + threadID=spawn_thread(threadFunc,"ScreenSaverRenderer",0,thrd); + resume_thread(threadID); + HideCursor(); } } -// Load the flattened settings BMessage from disk and parse it. -void ScreenSaverApp::LoadSettings(void) -{ - bool ok=false; - char pathAndFile[1024]; // Yes, this is very long... - BPath path; - - status_t found=find_directory(B_USER_SETTINGS_DIRECTORY,&path); - if (found==B_OK) - { - strncpy(pathAndFile,path.Path(),1023); - strncat(pathAndFile,"/ScreenSaver_settings",1023); - BFile ssSettings(pathAndFile,B_READ_ONLY); - if (B_OK==ssSettings.InitCheck()) - { // File exists. Unflatten the message and call the settings parser. - BMessage settings; - settings.Unflatten(&ssSettings); - parseSettings (&settings); - ok=true; - } - } - if (!ok)// If we can not find a settings file, post quit so that the app will quit right away... - Quit(); +bool ScreenSaverApp::QuitRequested(void) { + kill_thread(threadID); + delete thrd; + return true; } -void ScreenSaverApp::LoadAddOn(BMessage *msg) -{ +bool ScreenSaverApp::LoadAddOn() { BScreenSaver *(*instantiate)(BMessage *, image_id ); - image_id addon_image; - char temp[2048]; // Yes, this is a lot... - sprintf (temp,"/boot/beos/system/add-ons/Screen Savers/%s",moduleName); - if (addon_image) // This is a new set of preferences. Free up what we did have - { + if (addon_image) { // This is a new set of preferences. Free up what we did have unload_add_on(addon_image); - callSaverDelete(); + if (saver) + delete saver; } - addon_image = load_add_on(temp); - if (addon_image<0) - { - blankTime=-1; - printf ("Unable to open the add-on\n"); - printf ("add on image = %x!\n",addon_image); + char temp[B_PATH_NAME_LENGTH]; // Yes, this is a lot... + if (B_OK==find_directory(B_BEOS_ADDONS_DIRECTORY,NULL,false,temp,B_PATH_NAME_LENGTH)) { + sprintf (temp,"%s/Screen Savers/%s",temp,pref.ModuleName()); + //printf ("Trying to open add-on: %s\n",temp); + addon_image = load_add_on(temp); } - else + if (addon_image<0) { + //printf ("Unable to open add-on: %s\n",temp); + sprintf (temp,"%s/Screen Savers/%s",temp,pref.ModuleName()); + if (B_OK==find_directory(B_COMMON_ADDONS_DIRECTORY,NULL,false,temp,B_PATH_NAME_LENGTH)) { + sprintf (temp,"%s/Screen Savers/%s",temp,pref.ModuleName()); + //printf ("Trying to open add-on: %s\n",temp); + addon_image = load_add_on(temp); + } + } + if (addon_image<0) { + //printf ("Unable to open add-on: %s\n",temp); + if (B_OK==find_directory(B_USER_ADDONS_DIRECTORY,NULL,false,temp,B_PATH_NAME_LENGTH)) { + sprintf (temp,"%s/Screen Savers/%s",temp,pref.ModuleName()); + //printf ("Trying to open add-on: %s\n",temp); + addon_image = load_add_on(temp); + } + } + if (addon_image<0) { + printf ("Unable to open add-on: %s\n",temp); + printf ("add on image = %ld!\n",addon_image); + return false; + } + else { // Look for the one C function that should exist. - if (B_OK != get_image_symbol(addon_image, "instantiate_screen_saver", B_SYMBOL_TYPE_TEXT,(void **) &instantiate)) - { - blankTime=-1; + status_t retVal; + if (B_OK != (retVal=get_image_symbol(addon_image, "instantiate_screen_saver", B_SYMBOL_TYPE_TEXT,(void **) &instantiate))) { printf ("Unable to find the instantiator\n"); - printf ("Error = %d\n",get_image_symbol(addon_image, "instantiate_screen_saver", B_SYMBOL_TYPE_TEXT,(void **) &instantiate)); + printf ("Error = %ld\n",retVal); + return false; } else - saver=instantiate(msg,addon_image); -} - -// Blank the screen. -void ScreenSaverApp::goBlank(void) -{ - if (win && (blankTime> -1) && !disabled) - { - win->SetFullScreen(true); - win->Show(); - win->Sync(); - HideCursor(); - nextAction=DIRECTDRAW; - release_sem(ssSem); // Tell the drawing thread to go and draw. - } -} - -// Unblank. Only works for direct draws. -void ScreenSaverApp::unBlank(void) -{ - if (passwordTime > 0) - { - - } - resetTimer(); - if (win && (nextAction == DIRECTDRAW)) - { - win->SetFullScreen(false); - win->Hide(); - win->Sync(); - ShowCursor(); - nextAction=STOP; - } -} - -// Reset the timer. Keyboard or mouse event. -void ScreenSaverApp::resetTimer(void) -{ - currentTime=0; -} - -// Set a new duration for blanking -void ScreenSaverApp::setNewDuration(int newTimer) -{ - blankTime=newTimer; -} - -void setOnValue(BMessage *msg, char *name, int &result) -{ - int32 value; - if (B_OK == msg->FindInt32(name,&value)) // If screen saving is even enabled - result=value; - // printf ("Read parameter %s, setting it to:%d\n",name,result); -} - -void ScreenSaverApp::parseSettings (BMessage *msg) -{ - int temp; - const char *strPtr,*passwordPointer; - char pathAndFile[1024]; // Yes, this is very long... - BPath path; - - passwordPointer=password; - setOnValue(msg,"timeflags",temp); - if (temp) // If screen saver is enabled, set blanktime. - setOnValue(msg,"timefade",blankTime); - else - blankTime=-1; - // timestandby is not used, for now. - setOnValue(msg,"cornernow",cornerNow); - setOnValue(msg,"cornernever",cornerNever); - passwordTime=-1; // This is pessimistic - assume that password is off OR that a settings load will fail. - setOnValue(msg,"lockenable",temp); - if (temp && (B_OK == msg->FindString("lockmethod",&strPtr))) - { // Get the password. Either from the settings file (that's secure) or the networking file (also secure). - if (strcmp(strPtr,"network")) // Not network, therefore from the settings file - if (B_OK == msg->FindString("lockpassword",&passwordPointer)) - setOnValue(msg,"lockdelay",passwordTime); - else // Get from the network file - { - status_t found=find_directory(B_USER_SETTINGS_DIRECTORY,&path); - if (found==B_OK) - { - FILE *networkFile=NULL; - char buffer[512],*start; - strncpy(pathAndFile,path.Path(),1023); - strncat(pathAndFile,"/network",1023); - // This ugly piece opens the networking file and reads the password, if it exists. - if (networkFile=fopen(pathAndFile,"r")) - while (buffer==fgets(buffer,512,networkFile)) - if (start=strstr(buffer,"PASSWORD =")) - strncpy(password, start+10,strlen(start-11)); + saver=instantiate(pref.GetState(),addon_image); + if (B_OK!=saver->InitCheck()) { + unload_add_on(addon_image); + delete saver; + saver=NULL; + return false; } - } - setOnValue(msg,"lockdelay",passwordTime); } - if (B_OK != msg->FindString("modulename",&strPtr)) - blankTime=-1; // If the module doesn't exist, never blank. - strcpy(moduleName,strPtr); - LoadAddOn(msg); + return true; } + diff --git a/src/servers/screensaver/ScreenSaverApp.h b/src/servers/screensaver/ScreenSaverApp.h index ce13e13eff..c3bc2a2c30 100755 --- a/src/servers/screensaver/ScreenSaverApp.h +++ b/src/servers/screensaver/ScreenSaverApp.h @@ -5,33 +5,25 @@ #include #endif #include "SSAwindow.h" - -enum screenSaverWhat {GOBLANK=48, UNBLANK=49, RESET=50, NEWDURATION=51, SETNEWSAVER=52}; -enum SSstates {STOP,EXIT,DRAW,DIRECTDRAW}; +#include "ScreenSaverPrefs.h" +#include "ScreenSaverThread.h" class ScreenSaverApp : public BApplication { public: ScreenSaverApp(); - virtual void DispatchMessage(BMessage *msg,BHandler *target); - void goBlank(void); - void unBlank(void); - void resetTimer(void); - void LoadSettings(void); - void LoadAddOn(BMessage *msg); - void setNewDuration(int newTimer); - void parseSettings(BMessage *newSSMessage); + bool LoadAddOn(void); + void ReadyToRun(void); + bool QuitRequested(void); private: - int blankTime; - int currentTime; - int cornerNow; - int cornerNever; - int passwordTime; - bool disabled; - char moduleName[1024]; - char password[1024]; - thread_id threadID; + ScreenSaverPrefs pref; image_id addon_image; + SSAwindow *win; + BScreenSaver *saver; + ScreenSaverThread *thrd; + + thread_id threadID; + }; #endif //SCREEN_SAVER_H diff --git a/src/servers/screensaver/ScreenSaverPrefs.cpp b/src/servers/screensaver/ScreenSaverPrefs.cpp new file mode 100755 index 0000000000..a3544c46bc --- /dev/null +++ b/src/servers/screensaver/ScreenSaverPrefs.cpp @@ -0,0 +1,84 @@ +#include "ScreenSaverPrefs.h" +#include "StorageDefs.h" +#include "FindDirectory.h" +#include "File.h" +#include "Path.h" +#include "string.h" // Posix string functions +#include "String.h" // BString def +#include + +ScreenSaverPrefs::ScreenSaverPrefs(void) { +} + +// Load the flattened settings BMessage from disk and parse it. +bool ScreenSaverPrefs::LoadSettings(void) { + bool ok; + char pathAndFile[B_PATH_NAME_LENGTH]; + BPath path; + + status_t found=find_directory(B_USER_SETTINGS_DIRECTORY,&path); + if (ok=(found==B_OK)) { + strncpy(pathAndFile,path.Path(),B_PATH_NAME_LENGTH-1); + strncat(pathAndFile,"/ScreenSaver_settings",B_PATH_NAME_LENGTH-1); + BFile ssSettings(pathAndFile,B_READ_ONLY); + if (B_OK==ssSettings.InitCheck()) + { // File exists. Unflatten the message and call the settings parser. + BMessage settings; + settings.Unflatten(&ssSettings); + ok=parseSettings (&settings); + } + } + return ok; +} + +void setOnValue(BMessage *msg, char *name, int &result) { + int32 value; + if (B_OK == msg->FindInt32(name,&value)) // If screen saving is even enabled + result=value; + // printf ("Read parameter %s, setting it to:%d\n",name,result); +} + +bool ScreenSaverPrefs::parseSettings (BMessage *msg) { + int temp; + const char *strPtr,*passwordPointer; + char pathAndFile[B_PATH_NAME_LENGTH]; // Yes, this is very long... + BPath path; + + passwordPointer=password; + setOnValue(msg,"timeflags",temp); + if (temp) // If screen saver is enabled, set blanktime. + setOnValue(msg,"timefade",blankTime); + else + blankTime=-1; + passwordTime=-1; // This is pessimistic - assume that password is off OR that a settings load will fail. + setOnValue(msg,"lockenable",temp); + if (temp && (B_OK == msg->FindString("lockmethod",&strPtr))) + { // Get the password. Either from the settings file (that's secure) or the networking file (also secure). + if (strcmp(strPtr,"network")) // Not network, therefore from the settings file + if (B_OK == msg->FindString("lockpassword",&passwordPointer)) + setOnValue(msg,"lockdelay",passwordTime); + else // Get from the network file + { + status_t found=find_directory(B_USER_SETTINGS_DIRECTORY,&path); + if (found==B_OK) { + FILE *networkFile=NULL; + char buffer[512],*start; + strncpy(pathAndFile,path.Path(),B_PATH_NAME_LENGTH-1); + strncat(pathAndFile,"/network",B_PATH_NAME_LENGTH-1); + // This ugly piece opens the networking file and reads the password, if it exists. + if ((networkFile=fopen(pathAndFile,"r"))) + while (buffer==fgets(buffer,512,networkFile)) + if ((start=strstr(buffer,"PASSWORD ="))) + strncpy(password, start+10,strlen(start-11)); + } + } + setOnValue(msg,"lockdelay",passwordTime); + } + if (B_OK != msg->FindString("modulename",&strPtr)) + blankTime=-1; // If the module doesn't exist, never blank. + strcpy(moduleName,strPtr); + BString stateMsgName("modulesettings_"); + stateMsgName+=moduleName; + msg->FindMessage(stateMsgName.String(),&stateMsg); // Doesn't matter if it fails - stateMsg would just continue to be empty + return true; +} diff --git a/src/servers/screensaver/ScreenSaverPrefs.h b/src/servers/screensaver/ScreenSaverPrefs.h new file mode 100755 index 0000000000..0fd2ba6b83 --- /dev/null +++ b/src/servers/screensaver/ScreenSaverPrefs.h @@ -0,0 +1,32 @@ +#ifndef SCREEN_SAVER_PREFS_H +#define SCREEN_SAVER_PREFS_H +#include "Message.h" + +class ScreenSaverPrefs +{ +public: + ScreenSaverPrefs(void); + bool LoadSettings(void); + int BlankTime(void) {return blankTime;} + int CurrentTime(void) {return currentTime;} + int PasswordTime(void) {return passwordTime;} + char *ModuleName(void) {return moduleName;} + char *Password(void) {return password;} + BMessage *GetState(void) {return &stateMsg;} + void SetBlankTime(int ); + void SetCurrentTime(int ); + void SetPasswordTime(int ); + void SetModuleName(char *); + void SetPassword(char *); + void SetState(BMessage *); +private: + bool parseSettings(BMessage *newSSMessage); + int blankTime; + int currentTime; + int passwordTime; + char moduleName[B_PATH_NAME_LENGTH]; + char password[B_PATH_NAME_LENGTH]; + BMessage stateMsg; +}; + +#endif //SCREEN_SAVER_PREFS_H diff --git a/src/servers/screensaver/ScreenSaverThread.cpp b/src/servers/screensaver/ScreenSaverThread.cpp new file mode 100755 index 0000000000..c5a116c5c2 --- /dev/null +++ b/src/servers/screensaver/ScreenSaverThread.cpp @@ -0,0 +1,59 @@ +#ifndef SCREEN_SAVER_THREAD_H +#include "ScreenSaverThread.h" +#endif +#include +#include "Screen.h" +#include "ScreenSaver.h" +#include "SSAwindow.h" +#include "ScreenSaverPrefs.h" + +int32 threadFunc(void *data) { + ScreenSaverThread *ss=(ScreenSaverThread *)data; + ss->thread(); +} + +ScreenSaverThread::ScreenSaverThread(BScreenSaver *svr, SSAwindow *wnd, BView *vw, ScreenSaverPrefs *p) : + saver(svr),win(wnd),view(vw), pref(p), frame(0),snoozeCount(0) { + if (win) { // Running in full screen mode + saver->StartSaver(win->view,false); + win->SetFullScreen(true); + win->Show(); + win->Lock(); + win->view->SetViewColor(0,0,0); + win->view->SetLowColor(0,0,0); + win->Unlock(); + win->Sync(); + } +} + +void ScreenSaverThread::quit(void) { + saver->StopSaver(); + if (win) + win->Hide(); +} + +void ScreenSaverThread::thread() { + while (1) { + snooze(saver->TickSize()); + if (snoozeCount) { // If we are sleeping, do nothing + snoozeCount--; + return; + } else if (saver->LoopOnCount() && (frame>=saver->LoopOnCount())) { // Time to nap + frame=0; + snoozeCount=saver->LoopOffCount(); + } + else { + if (win) { + saver->DirectDraw(frame); + win->Lock(); + } + saver->Draw(view,frame); + if (win) { + win->Unlock(); + win->Sync(); + } + frame++; + } + } +} + diff --git a/src/servers/screensaver/ScreenSaverThread.h b/src/servers/screensaver/ScreenSaverThread.h new file mode 100644 index 0000000000..ec271c1c91 --- /dev/null +++ b/src/servers/screensaver/ScreenSaverThread.h @@ -0,0 +1,29 @@ +#ifndef SCREEN_SAVER_THREAD_H +#define SCREEN_SAVER_THREAD_H +#include "SupportDefs.h" + +class BScreenSaver; +class SSAwindow; +class BView; +class ScreenSaverPrefs; + +int32 threadFunc(void *data); + +class ScreenSaverThread +{ +public: + ScreenSaverThread(BScreenSaver *svr, SSAwindow *wnd, BView *vw, ScreenSaverPrefs *p); + void thread(void); + void quit(void); +private: + BScreenSaver *saver; + SSAwindow *win; + BView *view; + ScreenSaverPrefs *pref; + + long frame; + int snoozeCount; + +}; + +#endif //SCREEN_SAVER_THREAD_H