diff --git a/headers/private/screen_saver/ScreenSaverThread.h b/headers/private/screen_saver/ScreenSaverThread.h index 0e586bc1e5..21c8e3d5ae 100644 --- a/headers/private/screen_saver/ScreenSaverThread.h +++ b/headers/private/screen_saver/ScreenSaverThread.h @@ -12,25 +12,32 @@ class BScreenSaver; class BView; class ScreenSaverPrefs; -class ScreenSaverThread -{ -public: - ScreenSaverThread(BWindow *wnd, BView *vw, ScreenSaverPrefs *p); - void Thread(); - BScreenSaver *LoadAddOn() ; - void Quit(); +class ScreenSaverThread { + public: + ScreenSaverThread(BWindow* window, + BView* view, + ScreenSaverPrefs* prefs); + ~ScreenSaverThread(); - static int32 ThreadFunc(void *data); -private: - BScreenSaver *fSaver; - BWindow *fWin; - BDirectWindow *fDWin; - BView *fView; - ScreenSaverPrefs *fPref; + void Thread(); + BScreenSaver* LoadAddOn(); + void Quit(thread_id thread); - long fFrame; - int fSnoozeCount; - image_id fAddonImage; + static int32 ThreadFunc(void* data); + private: + void _CleanUp(); + + BScreenSaver* fSaver; + BWindow* fWin; + BDirectWindow* fDWin; + BView* fView; + ScreenSaverPrefs* fPref; + + long fFrame; + int fSnoozeCount; + image_id fAddonImage; + + volatile bool fQuitting; }; #endif //SCREEN_SAVER_THREAD_H diff --git a/src/bin/screen_blanker/ScreenSaverApp.cpp b/src/bin/screen_blanker/ScreenSaverApp.cpp index 93b52db175..6050511e09 100644 --- a/src/bin/screen_blanker/ScreenSaverApp.cpp +++ b/src/bin/screen_blanker/ScreenSaverApp.cpp @@ -114,6 +114,7 @@ ScreenSaverApp::MessageReceived(BMessage *message) } else { PRINT(("Quitting!\n")); _Shutdown(); + Quit(); } break; } @@ -144,26 +145,29 @@ ScreenSaverApp::QuitRequested() && (system_time() - fBlankTime > (fPrefs.PasswordTime() - fPrefs.BlankTime()))) { _ShowPasswordWindow(); return false; - } else - _Shutdown(); + } + _Shutdown(); return true; } void -ScreenSaverApp::_Shutdown(void) +ScreenSaverApp::_Shutdown() { - if (fWindow) - fWindow->Hide(); - if (fThreadID > -1) { - // TODO: kill_thread()? How about doing this right?? + if (fThread) { + fThread->Quit(fThreadID); + delete fThread; + } else if (fThreadID > -1) { + // ?!? kill_thread(fThreadID); } - if (fThread) - delete fThread; - Quit(); + fThread = NULL; + fThreadID = -1; + + if (fWindow) + fWindow->Hide(); } diff --git a/src/kits/screensaver/ScreenSaverThread.cpp b/src/kits/screensaver/ScreenSaverThread.cpp index 10777c851f..5dfc39327c 100644 --- a/src/kits/screensaver/ScreenSaverThread.cpp +++ b/src/kits/screensaver/ScreenSaverThread.cpp @@ -17,32 +17,46 @@ int32 ScreenSaverThread::ThreadFunc(void *data) { - ScreenSaverThread *ss=(ScreenSaverThread *)data; + ScreenSaverThread* ss = (ScreenSaverThread*)data; ss->Thread(); return B_OK; } -ScreenSaverThread::ScreenSaverThread(BWindow *wnd, BView *vw, ScreenSaverPrefs *p) +ScreenSaverThread::ScreenSaverThread(BWindow* window, + BView* view, + ScreenSaverPrefs* prefs) : fSaver(NULL), - fWin(wnd), - fView(vw), - fPref(p), + fWin(window), + fView(view), + fPref(prefs), fFrame(0), fSnoozeCount(0), - fAddonImage(0) + fAddonImage(-1), + + fQuitting(false) { - fDWin = dynamic_cast(wnd); + fDWin = dynamic_cast(fWin); +} + + +ScreenSaverThread::~ScreenSaverThread() +{ + _CleanUp(); } void -ScreenSaverThread::Quit() +ScreenSaverThread::Quit(thread_id id) { + fQuitting = true; + if (id >= 0) { + status_t threadRetValue; + wait_for_thread(id, &threadRetValue); + } + if (fSaver) fSaver->StopSaver(); - if (fWin) - fWin->Hide(); } @@ -53,21 +67,24 @@ ScreenSaverThread::Thread() fView->SetViewColor(0,0,0); fView->SetLowColor(0,0,0); if (fSaver) - fSaver->StartSaver(fView,false); + fSaver->StartSaver(fView, false); fWin->Unlock(); } - while (1) { + while (!fQuitting) { snooze(fSaver->TickSize()); - if (fSnoozeCount) { // If we are sleeping, do nothing + if (fSnoozeCount) { + // if we are sleeping, do nothing fSnoozeCount--; return; } else if (fSaver->LoopOnCount() && (fFrame >= fSaver->LoopOnCount())) { // Time to nap fFrame = 0; fSnoozeCount = fSaver->LoopOffCount(); } else if (fWin->Lock()) { - if (fDWin) + // NOTE: R5 really calls DirectDraw() + // and then Draw() for the same frame + if (fDWin) fSaver->DirectDraw(fFrame); - fSaver->Draw(fView,fFrame); + fSaver->Draw(fView, fFrame); fWin->Unlock(); fFrame++; } @@ -75,22 +92,23 @@ ScreenSaverThread::Thread() } -BScreenSaver * +BScreenSaver* ScreenSaverThread::LoadAddOn() { if (strcmp("", fPref->ModuleName()) == 0) return NULL; - BScreenSaver *(*instantiate)(BMessage *, image_id ); - if (fAddonImage) { // This is a new set of preferences. Free up what we did have - unload_add_on(fAddonImage); - } + // This is a new set of preferences. Free up what we did have + _CleanUp(); + + BScreenSaver* (*instantiate)(BMessage*, image_id); + char temp[B_PATH_NAME_LENGTH]; if (B_OK==find_directory(B_BEOS_ADDONS_DIRECTORY, 0, false, temp, B_PATH_NAME_LENGTH)) { sprintf (temp,"%s/Screen Savers/%s", temp, fPref->ModuleName()); fAddonImage = load_add_on(temp); } - if (fAddonImage<0) { + if (fAddonImage < 0) { //printf ("Unable to open add-on: %s\n",temp); sprintf (temp,"%s/Screen Savers/%s", temp, fPref->ModuleName()); if (B_OK==find_directory(B_COMMON_ADDONS_DIRECTORY, 0, false, temp, B_PATH_NAME_LENGTH)) { @@ -98,14 +116,14 @@ ScreenSaverThread::LoadAddOn() fAddonImage = load_add_on(temp); } } - if (fAddonImage<0) { + if (fAddonImage < 0) { //printf ("Unable to open add-on: %s\n",temp); if (B_OK==find_directory(B_USER_ADDONS_DIRECTORY, 0, false, temp, B_PATH_NAME_LENGTH)) { sprintf (temp,"%s/Screen Savers/%s", temp, fPref->ModuleName()); fAddonImage = load_add_on(temp); } } - if (fAddonImage<0) { + if (fAddonImage < 0) { printf ("Unable to open add-on: %s\n",temp); printf ("add on image = %ld!\n", fAddonImage); return NULL; @@ -132,3 +150,14 @@ ScreenSaverThread::LoadAddOn() return fSaver; } + +void +ScreenSaverThread::_CleanUp() +{ + delete fSaver; + fSaver = NULL; + if (fAddonImage >= 0) { + unload_add_on(fAddonImage); + fAddonImage = -1; + } +}