diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 76b54e3c2f..03539b4c30 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -57,7 +57,6 @@ #include #include #include -#include #include using namespace BPrivate; @@ -70,12 +69,6 @@ BResources *BApplication::_app_resources = NULL; BLocker BApplication::_app_resources_lock("_app_resources_lock"); -// Used by PrivateScreen.cpp -// TODO: This setup won`t let us have multiple screens. Change this. -namespace BPrivate { -BPrivateScreen *gPrivateScreen = NULL; -}; - static property_info sPropertyInfo[] = { { @@ -441,8 +434,6 @@ DBG(OUT("BApplication::InitData(`%s', %p)\n", signature, _error)); #ifndef RUN_WITHOUT_APP_SERVER // Initialize the IK after we have set be_app because of a construction of a // BAppServerLink (which depends on be_app) nested inside the call to get_menu_info. - if (fInitError == B_OK) - get_scs(); if (fInitError == B_OK) fInitError = _init_interface_kit_(); // create global system cursors @@ -1042,13 +1033,6 @@ BApplication::EndRectTracking() } -void -BApplication::get_scs() -{ - gPrivateScreen = new BPrivateScreen(); -} - - void BApplication::setup_server_heaps() { diff --git a/src/kits/interface/PrivateScreen.cpp b/src/kits/interface/PrivateScreen.cpp index 25a19daa69..ac34b3d819 100644 --- a/src/kits/interface/PrivateScreen.cpp +++ b/src/kits/interface/PrivateScreen.cpp @@ -24,9 +24,10 @@ // Description: BPrivateScreen is the class which does the real work // for the proxy class BScreen (it interacts with the app server). //------------------------------------------------------------------------------ +#include +#include #include -#include #include #include "AppServerLink.h" @@ -44,10 +45,11 @@ struct screen_desc { }; -// Defined in Application.cpp -namespace BPrivate { -extern BPrivateScreen *gPrivateScreen; -}; +static BPrivateScreen *sScreen; +static int32 sScreenRefCount; + +// used to synchronize creation/deletion of the sScreen object +static BLocker sScreenLock("screen lock"); using namespace BPrivate; @@ -55,30 +57,55 @@ using namespace BPrivate; BPrivateScreen * BPrivateScreen::CheckOut(BWindow *win) { - // TODO: If we start supporting multiple monitors, we - // should return the right screen for the passed BWindow - return gPrivateScreen; + sScreenLock.Lock(); + + if (atomic_add(&sScreenRefCount, 1) == 0) { + // TODO: If we start supporting multiple monitors, we + // should return the right screen for the passed BWindow + ASSERT(sScreen == NULL); + sScreen = new BPrivateScreen(); + } + + sScreenLock.Unlock(); + + return sScreen; } BPrivateScreen * BPrivateScreen::CheckOut(screen_id id) { - // TODO: If we start supporting multiple monitors, we - // should return the right object for the given screen_id - return gPrivateScreen; + sScreenLock.Lock(); + + if (atomic_add(&sScreenRefCount, 1) == 0) { + // TODO: If we start supporting multiple monitors, we + // should return the right object for the given screen_id + ASSERT(sScreen == NULL); + sScreen = new BPrivateScreen(); + } + + sScreenLock.Unlock(); + + return sScreen; } void BPrivateScreen::Return(BPrivateScreen *screen) { - // Not much to do here. I guess it's some legacy from pre-R5, - // where BScreen could not be used for long time, - // as they blocked the BApplication + sScreenLock.Lock(); + + if (atomic_add(&sScreenRefCount, -1) == 1) { + // TODO: Check if the passed object is the same we are deleting + // here. Not much important for now though, since we only have one. + delete sScreen; + sScreen = NULL; + } + + sScreenLock.Unlock(); } - + status_t BPrivateScreen::SetToNext() { @@ -426,7 +453,7 @@ BPrivateScreen::get_screen_desc(screen_desc *desc) return status; } - + // Private, called by BApplication::get_scs() BPrivateScreen::BPrivateScreen() : @@ -445,7 +472,7 @@ BPrivateScreen::BPrivateScreen() if (reply == SERVER_TRUE) { fColorMap = (color_map *)malloc(sizeof(color_map)); fOwnsColorMap = true; - // TODO: This doesn't work. We probably run into a port + // TODO: This doesn't work. We probably ran into a port // capacity issue ? //link.Read(fColorMap); }