diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index 416da3b8c2..12b733429a 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -21,6 +21,7 @@ enum { AS_SERVER_SESSION, AS_SERVER_PORTLINK, AS_CLIENT_DEAD, + AS_GET_DESKTOP, // Desktop definitions AS_GET_WINDOW_LIST, diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 89dfbc9676..08b92af334 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -1078,6 +1078,21 @@ BApplication::connect_to_app_server() return clientPort; // We can't use AppServerLink because be_app == NULL + fServerLink->SetTo(serverPort, clientPort); + + fServerLink->StartMessage(AS_GET_DESKTOP); + fServerLink->Attach(clientPort); + fServerLink->Attach(getuid()); + + int32 code; + if (fServerLink->FlushWithReply(code) != B_OK || code != B_OK) { + fServerLink->SetSenderPort(-1); + return B_ERROR; + } + + // we talk to the desktop to create our application + fServerLink->Read(&serverPort); + fServerLink->SetSenderPort(serverPort); // AS_CREATE_APP: // @@ -1087,7 +1102,6 @@ BApplication::connect_to_app_server() // 3) team_id - team identification field // 4) int32 - handler ID token of the app // 5) char * - signature of the regular app - fServerLink->SetTo(serverPort, clientPort); fServerLink->StartMessage(AS_CREATE_APP); fServerLink->Attach(clientPort); @@ -1096,9 +1110,8 @@ BApplication::connect_to_app_server() fServerLink->Attach(_get_object_token_(this)); fServerLink->AttachString(fAppName); - int32 code; if (fServerLink->FlushWithReply(code) == B_OK - && code == SERVER_TRUE) { + && code == B_OK) { // We don't need to contact the main app_server anymore // directly; we now talk to our server alter ego only. fServerLink->Read(&serverPort); diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index da4ffe20c1..b7f4185180 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -59,9 +59,6 @@ #endif -static const uint32 kMsgShutdownServer = 'shuT'; - - // Globals Desktop *gDesktop; @@ -83,10 +80,8 @@ AppServer::AppServer() : BApplication (SERVER_SIGNATURE), #else AppServer::AppServer() : #endif - fAppListLock("application list"), fCursorSem(-1), - fCursorArea(-1), - fShutdownSemaphore(-1) + fCursorArea(-1) { fMessagePort = create_port(200, SERVER_PORT_NAME); if (fMessagePort == B_NO_MORE_PORTS) @@ -164,6 +159,7 @@ AppServer::AppServer() : gGUIColorSet.SetToDefaults(); gScreenManager = new ScreenManager(); + gScreenManager->Run(); // the system palette needs to be initialized before the desktop, // since it is used there already @@ -254,11 +250,6 @@ AppServer::PicassoThread(void *data) snooze(1000000); } - // app_server is about to quit - // wait some more, and then make sure it'll shutdown everything - snooze(2000000); - sAppServer->PostMessage(kMsgShutdownServer); - return 0; } @@ -419,94 +410,19 @@ void AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg) { switch (code) { - case AS_CREATE_APP: + case AS_GET_DESKTOP: { - // Create the ServerApp to node monitor a new BApplication - - // Attached data: - // 1) port_id - receiver port of a regular app - // 2) port_id - client looper port - for sending messages to the client - // 2) team_id - app's team ID - // 3) int32 - handler token of the regular app - // 4) char * - signature of the regular app - - // Find the necessary data - team_id clientTeamID = -1; - port_id clientLooperPort = -1; - port_id clientReplyPort = -1; - int32 htoken = B_NULL_TOKEN; - char *appSignature = NULL; - - msg.Read(&clientReplyPort); - msg.Read(&clientLooperPort); - msg.Read(&clientTeamID); - msg.Read(&htoken); - if (msg.ReadString(&appSignature) != B_OK) + port_id replyPort; + if (msg.Read(&replyPort) < B_OK) break; - ServerApp *app = new ServerApp(clientReplyPort, clientLooperPort, - clientTeamID, htoken, appSignature); - if (app->InitCheck() == B_OK - && app->Run()) { - // add the new ServerApp to the known list of ServerApps - fAppListLock.Lock(); - fAppList.AddItem(app); - fAppListLock.Unlock(); - } else { - delete app; + int32 userID; + msg.Read(&userID); - // if everything went well, ServerApp::Run() will notify - // the client - but since it didn't, we do it here - BPrivate::LinkSender reply(clientReplyPort); - reply.StartMessage(SERVER_FALSE); - reply.Flush(); - } - - // This is necessary because BPortLink::ReadString allocates memory - free(appSignature); - break; - } - - case AS_DELETE_APP: - { - // Delete a ServerApp. Received only from the respective ServerApp when a - // BApplication asks it to quit. - - // Attached Data: - // 1) thread_id - thread ID of the ServerApp to be deleted - - thread_id thread = -1; - if (msg.Read(&thread) < B_OK) - break; - - fAppListLock.Lock(); - - // Run through the list of apps and nuke the proper one - - int32 count = fAppList.CountItems(); - ServerApp *removeApp = NULL; - - for (int32 i = 0; i < count; i++) { - ServerApp *app = (ServerApp *)fAppList.ItemAt(i); - - if (app != NULL && app->Thread() == thread) { - fAppList.RemoveItem(i); - removeApp = app; - break; - } - } - - fAppListLock.Unlock(); - - if (removeApp != NULL) - removeApp->Quit(fShutdownSemaphore); - - if (fQuitting && count <= 1) { - // wait for the last app to die - acquire_sem_etc(fShutdownSemaphore, fShutdownCount, B_RELATIVE_TIMEOUT, 500000); - - PostMessage(kMsgShutdownServer); - } + BPrivate::LinkSender reply(replyPort); + reply.StartMessage(B_OK); + reply.Attach(gDesktop->MessagePort()); + reply.Flush(); break; } @@ -543,54 +459,25 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg) #if TEST_MODE case B_QUIT_REQUESTED: + { // We've been asked to quit, so (for now) broadcast to all // test apps to quit. This situation will occur only when the server // is compiled as a regular Be application. - fAppListLock.Lock(); - fShutdownSemaphore = create_sem(0, "app_server shutdown"); - fShutdownCount = fAppList.CountItems(); - fAppListLock.Unlock(); - + gDesktop->PostMessage(B_QUIT_REQUESTED); fQuitting = true; - BroadcastToAllApps(AS_QUIT_APP); - // We now need to process the remaining AS_DELETE_APP messages and - // wait for the kMsgShutdownServer message. - // If an application does not quit as asked, the picasso thread - // will send us this message in 2-3 seconds. - - // if there are no apps to quit, shutdown directly - if (fShutdownCount == 0) - PostMessage(kMsgShutdownServer); - break; - - case kMsgShutdownServer: - { - // let's kill all remaining applications - - fAppListLock.Lock(); - - int32 count = fAppList.CountItems(); - for (int32 i = 0; i < count; i++) { - ServerApp *app = (ServerApp*)fAppList.ItemAt(i); - team_id clientTeam = app->ClientTeam(); - - app->Quit(); - kill_team(clientTeam); - } - - // wait for the last app to die - if (count > 0) - acquire_sem_etc(fShutdownSemaphore, fShutdownCount, B_RELATIVE_TIMEOUT, 250000); + // we just wait for the desktop to kill itself + status_t status; + wait_for_thread(gDesktop->Thread(), &status); kill_thread(fPicassoThreadID); - fAppListLock.Unlock(); - delete gDesktop; delete gBitmapManager; - delete gFontServer; + // TODO: deleting the font server results in an endless loop somewhere + // down in FreeType code - smells like memory corruption + //delete gFontServer; // we are now clear to exit exit(0); @@ -635,7 +522,6 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg) BPrivate::PortLink replyLink(replyPort); replyLink.StartMessage(error); replyLink.Flush(); - break; } @@ -646,58 +532,10 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg) } } -/*! - \brief Finds the application with the given signature - \param sig MIME signature of the application to find - \return the corresponding ServerApp or NULL if not found - - This call should be made only when necessary because it locks the app list - while it does its searching. -*/ -ServerApp * -AppServer::FindApp(const char *signature) -{ - if (!signature) - return NULL; - - BAutolock locker(fAppListLock); - - for (int32 i = 0; i < fAppList.CountItems(); i++) { - ServerApp *app = (ServerApp*)fAppList.ItemAt(i); - if (app && !strcasecmp(app->Signature(), signature)) - return app; - } - - return NULL; -} - // #pragma mark - -/*! - \brief Send a quick (no attachments) message to all applications - - Quite useful for notification for things like server shutdown, system - color changes, etc. -*/ -void -BroadcastToAllApps(const int32 &code) -{ - BAutolock locker(sAppServer->fAppListLock); - - for (int32 i = 0; i < sAppServer->fAppList.CountItems(); i++) { - ServerApp *app = (ServerApp *)sAppServer->fAppList.ItemAt(i); - - if (!app) { - printf("PANIC in Broadcast()\n"); - continue; - } - app->PostMessage(code); - } -} - - /*! \brief Entry function to run the entire server \param argc Number of command-line arguments present diff --git a/src/servers/app/AppServer.h b/src/servers/app/AppServer.h index 0acd20e87d..1cb4740c0e 100644 --- a/src/servers/app/AppServer.h +++ b/src/servers/app/AppServer.h @@ -50,11 +50,8 @@ static int32 PicassoThread(void *data); void PostMessage(int32 code); void DispatchMessage(int32 code, BPrivate::PortLink &link); - ServerApp* FindApp(const char *sig); private: -friend void BroadcastToAllApps(const int32 &code); - void LaunchCursorThread(); void LaunchInputServer(); static int32 CursorThread(void *data); @@ -64,9 +61,6 @@ static int32 CursorThread(void *data); volatile bool fQuitting; - BLocker fAppListLock; - BList fAppList; - thread_id fPicassoThreadID; thread_id fISThreadID; @@ -77,9 +71,6 @@ volatile bool fQuitting; port_id fISASPort; port_id fISPort; - - sem_id fShutdownSemaphore; - int32 fShutdownCount; }; extern BitmapManager *gBitmapManager; diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index ec3181844c..8642df986e 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -59,6 +59,8 @@ Desktop::Desktop() : MessageLooper("desktop"), fSettings(new DesktopSettings::Private()), + fAppListLock("application list"), + fShutdownSemaphore(-1), fWinBorderList(64), fActiveScreen(NULL) { @@ -69,6 +71,8 @@ Desktop::Desktop() fMessagePort = create_port(DEFAULT_MONITOR_PORT_SIZE, name); if (fMessagePort < B_OK) return; + + fLink.SetReceiverPort(fMessagePort); } @@ -113,6 +117,183 @@ Desktop::_GetLooperName(char* name, size_t length) } +void +Desktop::_PrepareQuit() +{ + // let's kill all remaining applications + + fAppListLock.Lock(); + + int32 count = fAppList.CountItems(); + for (int32 i = 0; i < count; i++) { + ServerApp *app = (ServerApp*)fAppList.ItemAt(i); + team_id clientTeam = app->ClientTeam(); + + app->Quit(); + kill_team(clientTeam); + } + + // wait for the last app to die + if (count > 0) + acquire_sem_etc(fShutdownSemaphore, fShutdownCount, B_RELATIVE_TIMEOUT, 250000); + + fAppListLock.Unlock(); +} + + +void +Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) +{ + switch (code) { + case AS_CREATE_APP: + { + // Create the ServerApp to node monitor a new BApplication + + // Attached data: + // 1) port_id - receiver port of a regular app + // 2) port_id - client looper port - for sending messages to the client + // 2) team_id - app's team ID + // 3) int32 - handler token of the regular app + // 4) char * - signature of the regular app + + // Find the necessary data + team_id clientTeamID = -1; + port_id clientLooperPort = -1; + port_id clientReplyPort = -1; + int32 htoken = B_NULL_TOKEN; + char *appSignature = NULL; + + link.Read(&clientReplyPort); + link.Read(&clientLooperPort); + link.Read(&clientTeamID); + link.Read(&htoken); + if (link.ReadString(&appSignature) != B_OK) + break; + + ServerApp *app = new ServerApp(this, clientReplyPort, + clientLooperPort, clientTeamID, htoken, appSignature); + if (app->InitCheck() == B_OK + && app->Run()) { + // add the new ServerApp to the known list of ServerApps + fAppListLock.Lock(); + fAppList.AddItem(app); + fAppListLock.Unlock(); + } else { + delete app; + + // if everything went well, ServerApp::Run() will notify + // the client - but since it didn't, we do it here + BPrivate::LinkSender reply(clientReplyPort); + reply.StartMessage(SERVER_FALSE); + reply.Flush(); + } + + // This is necessary because BPortLink::ReadString allocates memory + free(appSignature); + break; + } + + case AS_DELETE_APP: + { + // Delete a ServerApp. Received only from the respective ServerApp when a + // BApplication asks it to quit. + + // Attached Data: + // 1) thread_id - thread ID of the ServerApp to be deleted + + thread_id thread = -1; + if (link.Read(&thread) < B_OK) + break; + + fAppListLock.Lock(); + + // Run through the list of apps and nuke the proper one + + int32 count = fAppList.CountItems(); + ServerApp *removeApp = NULL; + + for (int32 i = 0; i < count; i++) { + ServerApp *app = (ServerApp *)fAppList.ItemAt(i); + + if (app != NULL && app->Thread() == thread) { + fAppList.RemoveItem(i); + removeApp = app; + break; + } + } + + fAppListLock.Unlock(); + + if (removeApp != NULL) + removeApp->Quit(fShutdownSemaphore); + + if (fQuitting && count <= 1) { + // wait for the last app to die + acquire_sem_etc(fShutdownSemaphore, fShutdownCount, B_RELATIVE_TIMEOUT, 500000); + PostMessage(kMsgQuitLooper); + } + break; + } + + case B_QUIT_REQUESTED: + // We've been asked to quit, so (for now) broadcast to all + // test apps to quit. This situation will occur only when the server + // is compiled as a regular Be application. + + fAppListLock.Lock(); + fShutdownSemaphore = create_sem(0, "desktop shutdown"); + fShutdownCount = fAppList.CountItems(); + fAppListLock.Unlock(); + + fQuitting = true; + BroadcastToAllApps(AS_QUIT_APP); + + // We now need to process the remaining AS_DELETE_APP messages and + // wait for the kMsgShutdownServer message. + // If an application does not quit as asked, the picasso thread + // will send us this message in 2-3 seconds. + + // if there are no apps to quit, shutdown directly + if (fShutdownCount == 0) + PostMessage(kMsgQuitLooper); + break; + + default: + printf("Desktop %d:%s received unexpected code %ld\n", 0, "baron", code); + + if (link.NeedsReply()) { + // the client is now blocking and waiting for a reply! + fLink.StartMessage(B_ERROR); + fLink.Flush(); + } + break; + } +} + + +/*! + \brief Send a quick (no attachments) message to all applications + + Quite useful for notification for things like server shutdown, system + color changes, etc. +*/ +void +Desktop::BroadcastToAllApps(int32 code) +{ + BAutolock locker(fAppListLock); + + for (int32 i = 0; i < fAppList.CountItems(); i++) { + ServerApp *app = (ServerApp *)fAppList.ItemAt(i); + + if (!app) { + printf("PANIC in Broadcast()\n"); + continue; + } + app->PostMessage(code); + } +} + + //--------------------------------------------------------------------------- // Methods for layer(WinBorder) manipulation. //--------------------------------------------------------------------------- diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index d96a6c98e2..7cff98cd28 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -44,6 +44,9 @@ class Desktop : public MessageLooper, public ScreenOwner { virtual ~Desktop(); void Init(); + virtual port_id MessagePort() const { return fMessagePort; } + + void BroadcastToAllApps(int32 code); // Methods for multiple monitors. inline Screen* ScreenAt(int32 index) const @@ -88,7 +91,8 @@ class Desktop : public MessageLooper, public ScreenOwner { private: virtual void _GetLooperName(char* name, size_t size); - virtual port_id _MessagePort() const { return fMessagePort; } + virtual void _PrepareQuit(); + virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); private: friend class DesktopSettings; @@ -96,6 +100,13 @@ class Desktop : public MessageLooper, public ScreenOwner { ::VirtualScreen fVirtualScreen; DesktopSettings::Private* fSettings; port_id fMessagePort; + + BLocker fAppListLock; + BList fAppList; + + sem_id fShutdownSemaphore; + int32 fShutdownCount; + BList fWinBorderList; RootLayer* fRootLayer; diff --git a/src/servers/app/MessageLooper.cpp b/src/servers/app/MessageLooper.cpp index fab93de8c7..576a547752 100644 --- a/src/servers/app/MessageLooper.cpp +++ b/src/servers/app/MessageLooper.cpp @@ -10,6 +10,7 @@ #include "MessageLooper.h" #include +#include MessageLooper::MessageLooper(const char* name) @@ -82,7 +83,7 @@ MessageLooper::Quit() void MessageLooper::PostMessage(int32 code) { - BPrivate::LinkSender link(_MessagePort()); + BPrivate::LinkSender link(MessagePort()); link.StartMessage(code); link.Flush(); } @@ -111,6 +112,26 @@ MessageLooper::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) void MessageLooper::_MessageLooper() { + BPrivate::LinkReceiver& receiver = fLink.Receiver(); + + while (true) { + int32 code; + status_t status = receiver.GetNextMessage(code); + if (status < B_OK) { + // that shouldn't happen, it's our port + printf("Someone deleted our message port!\n"); + break; + } + + Lock(); + + if (code == kMsgQuitLooper) { + Quit(); + } else + _DispatchMessage(code, receiver); + + Unlock(); + } } diff --git a/src/servers/app/MessageLooper.h b/src/servers/app/MessageLooper.h index 5e00a6c88c..80544af972 100644 --- a/src/servers/app/MessageLooper.h +++ b/src/servers/app/MessageLooper.h @@ -24,13 +24,13 @@ class MessageLooper : public BLocker { void PostMessage(int32 code); thread_id Thread() const { return fThread; } + virtual port_id MessagePort() const = 0; private: virtual void _PrepareQuit(); virtual void _GetLooperName(char* name, size_t length); virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); virtual void _MessageLooper(); - virtual port_id _MessagePort() const = 0; static int32 _message_thread(void *_looper); @@ -40,6 +40,6 @@ class MessageLooper : public BLocker { bool fQuitting; }; -static const uint32 kMsgQuitLooper = 'quit'; +static const int32 kMsgQuitLooper = 'quit'; #endif /* MESSAGE_LOOPER_H */ diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 8b01d6c6a5..0c0d94eb58 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -10,6 +10,10 @@ * Axel Dörfler, axeld@pinc-software.de */ +/*! + \class ServerApp ServerApp.h + \brief Counterpart to BApplication within the app_server +*/ #include #include @@ -77,13 +81,15 @@ static const uint32 kMsgAppQuit = 'appQ'; \param fSignature NULL-terminated string which contains the BApplication's MIME fSignature. */ -ServerApp::ServerApp(port_id clientReplyPort, port_id clientLooperPort, - team_id clientTeam, int32 handlerID, const char* signature) +ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, + port_id clientLooperPort, team_id clientTeam, int32 handlerID, + const char* signature) : MessageLooper("application"), fMessagePort(-1), fClientReplyPort(clientReplyPort), fClientLooperPort(clientLooperPort), fClientToken(handlerID), + fDesktop(desktop), fSignature(signature), fClientTeam(clientTeam), fWindowListLock("window list"), @@ -116,7 +122,7 @@ ServerApp::ServerApp(port_id clientReplyPort, port_id clientLooperPort, // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. ServerCursor *defaultCursor = - gDesktop->ActiveRootLayer()->GetCursorManager().GetCursor(B_CURSOR_DEFAULT); + fDesktop->ActiveRootLayer()->GetCursorManager().GetCursor(B_CURSOR_DEFAULT); if (defaultCursor) { fAppCursor = new ServerCursor(defaultCursor); @@ -196,7 +202,7 @@ ServerApp::~ServerApp(void) // although this isn't pretty, ATM we have only one RootLayer. // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. - gDesktop->ActiveRootLayer()->GetCursorManager().RemoveAppCursors(fClientTeam); + fDesktop->ActiveRootLayer()->GetCursorManager().RemoveAppCursors(fClientTeam); STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature())); } @@ -306,7 +312,7 @@ ServerApp::SetAppCursor(void) // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. if (fAppCursor) - gDesktop->GetHWInterface()->SetCursor(fAppCursor); + fDesktop->GetHWInterface()->SetCursor(fAppCursor); } @@ -341,8 +347,8 @@ ServerApp::_MessageLooper() if (err < B_OK || code == B_QUIT_REQUESTED) { STRACE(("ServerApp: application seems to be gone...\n")); - // Tell the app_server to quit us - BPrivate::LinkSender link(gAppServerPort); + // Tell desktop to quit us + BPrivate::LinkSender link(fDesktop->MessagePort()); link.StartMessage(AS_DELETE_APP); link.Attach(Thread()); link.Flush(); @@ -560,14 +566,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) team_id team; link.Read(&team); - gDesktop->WriteWindowList(team, fLink.Sender()); + fDesktop->WriteWindowList(team, fLink.Sender()); break; case AS_GET_WINDOW_INFO: int32 serverToken; link.Read(&serverToken); - gDesktop->WriteWindowInfo(serverToken, fLink.Sender()); + fDesktop->WriteWindowInfo(serverToken, fLink.Sender()); break; case AS_UPDATE_COLORS: @@ -721,15 +727,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { // Received from an application when the user wants to set the window // decorator to a new one - + // Attached Data: // int32 the index of the decorator to use - + int32 index; link.Read(&index); - if(gDecorManager.SetDecorator(index)) - BroadcastToAllApps(AS_UPDATE_DECORATOR); - + if (gDecorManager.SetDecorator(index)) + fDesktop->BroadcastToAllApps(AS_UPDATE_DECORATOR); break; } case AS_COUNT_DECORATORS: @@ -750,9 +755,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { int32 index; link.Read(&index); - + BString str(gDecorManager.GetDecoratorName(index)); - if(str.CountChars() > 0) + if (str.CountChars() > 0) { fLink.StartMessage(SERVER_TRUE); fLink.AttachString(str.String()); @@ -767,19 +772,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { // Sort of supports Tracker's nifty Easter Egg. It was easy to do and // it's kind of neat, so why not? - + // Attached Data: // int32 value of the decorator to use // 0: BeOS // 1: Amiga // 2: Windows // 3: MacOS - + int32 decindex = 0; link.Read(&decindex); - - if(gDecorManager.SetR5Decorator(decindex)) - BroadcastToAllApps(AS_UPDATE_DECORATOR); + + if (gDecorManager.SetR5Decorator(decindex)) + fDesktop->BroadcastToAllApps(AS_UPDATE_DECORATOR); break; } @@ -896,7 +901,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) STRACE(("ServerApp %s: get current workspace\n", Signature())); // TODO: Locking this way is not nice - RootLayer *root = gDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->ActiveRootLayer(); root->Lock(); fLink.StartMessage(SERVER_TRUE); @@ -914,7 +919,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // TODO: See above int32 index; link.Read(&index); - RootLayer *root = gDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->ActiveRootLayer(); root->Lock(); root->SetActiveWorkspace(index); root->Unlock(); @@ -932,7 +937,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. // TODO: support nested showing/hiding - gDesktop->GetHWInterface()->SetCursorVisible(true); + fDesktop->GetHWInterface()->SetCursorVisible(true); fCursorHidden = false; break; } @@ -943,7 +948,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. // TODO: support nested showing/hiding - gDesktop->GetHWInterface()->SetCursorVisible(false); + fDesktop->GetHWInterface()->SetCursorVisible(false); fCursorHidden = true; break; } @@ -953,7 +958,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // although this isn't pretty, ATM we have only one RootLayer. // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. -// gDesktop->GetHWInterface()->ObscureCursor(); +// fDesktop->GetHWInterface()->ObscureCursor(); break; } case AS_QUERY_CURSOR_HIDDEN: @@ -976,16 +981,16 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // otherwise be easy to crash the server by calling SetCursor a // sufficient number of times if(fAppCursor) - gDesktop->ActiveRootLayer()->GetCursorManager().DeleteCursor(fAppCursor->ID()); + fDesktop->ActiveRootLayer()->GetCursorManager().DeleteCursor(fAppCursor->ID()); fAppCursor = new ServerCursor(cdata); fAppCursor->SetOwningTeam(fClientTeam); fAppCursor->SetAppSignature(Signature()); - gDesktop->ActiveRootLayer()->GetCursorManager().AddCursor(fAppCursor); + fDesktop->ActiveRootLayer()->GetCursorManager().AddCursor(fAppCursor); // although this isn't pretty, ATM we have only one RootLayer. // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. - gDesktop->GetHWInterface()->SetCursor(fAppCursor); + fDesktop->GetHWInterface()->SetCursor(fAppCursor); break; } case AS_SET_CURSOR_BCURSOR: @@ -1005,8 +1010,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. ServerCursor *cursor; - if ((cursor = gDesktop->ActiveRootLayer()->GetCursorManager().FindCursor(ctoken))) - gDesktop->GetHWInterface()->SetCursor(cursor); + if ((cursor = fDesktop->ActiveRootLayer()->GetCursorManager().FindCursor(ctoken))) + fDesktop->GetHWInterface()->SetCursor(cursor); if (sync) { // the application is expecting a reply, but plans to do literally nothing @@ -1032,7 +1037,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // although this isn't pretty, ATM we have only one RootLayer. // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. - gDesktop->ActiveRootLayer()->GetCursorManager().AddCursor(fAppCursor); + fDesktop->ActiveRootLayer()->GetCursorManager().AddCursor(fAppCursor); // Synchronous message - BApplication is waiting on the cursor's ID fLink.StartMessage(SERVER_TRUE); @@ -1054,14 +1059,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // although this isn't pretty, ATM we have only one RootLayer. // there should be a way that this ServerApp be attached to a particular // RootLayer to know which RootLayer's cursor to modify. - gDesktop->ActiveRootLayer()->GetCursorManager().DeleteCursor(ctoken); + fDesktop->ActiveRootLayer()->GetCursorManager().DeleteCursor(ctoken); break; } case AS_GET_SCROLLBAR_INFO: { STRACE(("ServerApp %s: Get ScrollBar info\n", Signature())); scroll_bar_info info; - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); settings.GetScrollBarInfo(info); fLink.StartMessage(SERVER_TRUE); @@ -1076,7 +1081,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // 1) scroll_bar_info scroll bar info structure scroll_bar_info info; if (link.Read(&info) == B_OK) { - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); settings.SetScrollBarInfo(info); } @@ -1089,7 +1094,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { STRACE(("ServerApp %s: Get menu info\n", Signature())); menu_info info; - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); settings.GetMenuInfo(info); fLink.StartMessage(B_OK); @@ -1102,7 +1107,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) STRACE(("ServerApp %s: Set menu info\n", Signature())); menu_info info; if (link.Read(&info) == B_OK) { - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); settings.SetMenuInfo(info); // TODO: SetMenuInfo() should do some validity check, so // that the answer we're giving can actually be useful @@ -1120,7 +1125,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // 1) enum mode_mouse FFM mouse mode mode_mouse mouseMode; if (link.Read(&mouseMode) == B_OK) { - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); settings.SetMouseMode(mouseMode); } break; @@ -1128,7 +1133,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) case AS_GET_MOUSE_MODE: { STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature())); - DesktopSettings settings(gDesktop); + DesktopSettings settings(fDesktop); fLink.StartMessage(SERVER_TRUE); fLink.Attach(settings.MouseMode()); @@ -1160,7 +1165,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&gGUIColorSet); gGUIColorSet.Unlock(); - BroadcastToAllApps(AS_UPDATE_COLORS); + fDesktop->BroadcastToAllApps(AS_UPDATE_COLORS); break; } case AS_GET_UI_COLOR: @@ -1378,7 +1383,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) font.SetSize(size); font.SetSpacing(spacing); - width = gDesktop->GetDisplayDriver()->StringWidth(string, length, font); + width = fDesktop->GetDisplayDriver()->StringWidth(string, length, font); // NOTE: The line below will return the exact same thing. However, // the line above uses the AGG rendering backend, for which glyph caching // actually works. It is about 20 times faster! @@ -1901,7 +1906,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // We have the screen_id and the workspace number, with these // we need to find the corresponding "driver", and call getmode on it display_mode mode; - gDesktop->ScreenAt(0)->GetMode(&mode); + fDesktop->ScreenAt(0)->GetMode(&mode); // actually this isn't still enough as different workspaces can // have different display_modes @@ -1935,7 +1940,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping // optionally put this into a message and let the root layer thread handle it. -// status_t ret = gDesktop->ScreenAt(0)->SetMode(mode); +// status_t ret = fDesktop->ScreenAt(0)->SetMode(mode); status_t ret = B_ERROR; fLink.StartMessage(SERVER_TRUE); @@ -1954,7 +1959,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&target); link.Read(&low); link.Read(&high); - status_t status = gDesktop->GetHWInterface()->ProposeMode(&target, &low, &high); + status_t status = fDesktop->GetHWInterface()->ProposeMode(&target, &low, &high); // TODO: We always return SERVER_TRUE and put the real // error code in the message. FIX this. fLink.StartMessage(SERVER_TRUE); @@ -1973,7 +1978,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) display_mode* modeList; uint32 count; - if (gDesktop->GetHWInterface()->GetModeList(&modeList, &count) == B_OK) { + if (fDesktop->GetHWInterface()->GetModeList(&modeList, &count) == B_OK) { fLink.StartMessage(SERVER_TRUE); fLink.Attach(count); fLink.Attach(modeList, sizeof(display_mode) * count); @@ -2016,7 +2021,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // ToDo: locking is probably wrong - why the hell is there no (safe) // way to get to the workspace object directly? - RootLayer *root = gDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->ActiveRootLayer(); root->Lock(); Workspace *workspace = root->WorkspaceAt(workspaceIndex); @@ -2041,7 +2046,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) accelerant_device_info accelerantInfo; // TODO: I wonder if there should be a "desktop" lock... - if (gDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo) == B_OK) { + if (fDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo) == B_OK) { fLink.StartMessage(SERVER_TRUE); fLink.Attach(accelerantInfo); } else @@ -2059,7 +2064,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) screen_id id; link.Read(&id); - sem_id semaphore = gDesktop->GetHWInterface()->RetraceSemaphore(); + sem_id semaphore = fDesktop->GetHWInterface()->RetraceSemaphore(); fLink.StartMessage(SERVER_TRUE); fLink.Attach(semaphore); fLink.Flush(); @@ -2074,7 +2079,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&id); display_timing_constraints constraints; - if (gDesktop->GetHWInterface()->GetTimingConstraints(&constraints) == B_OK) { + if (fDesktop->GetHWInterface()->GetTimingConstraints(&constraints) == B_OK) { fLink.StartMessage(SERVER_TRUE); fLink.Attach(constraints); } else @@ -2094,7 +2099,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&mode); uint32 low, high; - if (gDesktop->GetHWInterface()->GetPixelClockLimits(&mode, &low, &high) == B_OK) { + if (fDesktop->GetHWInterface()->GetPixelClockLimits(&mode, &low, &high) == B_OK) { fLink.StartMessage(SERVER_TRUE); fLink.Attach(low); fLink.Attach(high); @@ -2114,7 +2119,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) uint32 mode; link.Read(&mode); - if (gDesktop->GetHWInterface()->SetDPMSMode(mode) == B_OK) + if (fDesktop->GetHWInterface()->SetDPMSMode(mode) == B_OK) fLink.StartMessage(SERVER_TRUE); else fLink.StartMessage(SERVER_FALSE); @@ -2130,7 +2135,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) screen_id id; link.Read(&id); - uint32 state = gDesktop->GetHWInterface()->DPMSMode(); + uint32 state = fDesktop->GetHWInterface()->DPMSMode(); fLink.StartMessage(SERVER_TRUE); fLink.Attach(state); fLink.Flush(); @@ -2143,7 +2148,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) screen_id id; link.Read(&id); - uint32 capabilities = gDesktop->GetHWInterface()->DPMSCapabilities(); + uint32 capabilities = fDesktop->GetHWInterface()->DPMSCapabilities(); fLink.StartMessage(SERVER_TRUE); fLink.Attach(capabilities); fLink.Flush(); diff --git a/src/servers/app/ServerApp.h b/src/servers/app/ServerApp.h index 81de13ea0b..a1d1e427bc 100644 --- a/src/servers/app/ServerApp.h +++ b/src/servers/app/ServerApp.h @@ -27,26 +27,25 @@ class DisplayDriver; class ServerPicture; class ServerCursor; class ServerBitmap; +class Desktop; namespace BPrivate { class PortLink; }; -/*! - \class ServerApp ServerApp.h - \brief Counterpart to BApplication within the app_server -*/ class ServerApp : public MessageLooper { public: - ServerApp(port_id clientAppPort, port_id clientLooperPort, - team_id clientTeamID, int32 handlerID, - const char* signature); + ServerApp(Desktop* desktop, port_id clientAppPort, + port_id clientLooperPort, team_id clientTeamID, + int32 handlerID, const char* signature); virtual ~ServerApp(); status_t InitCheck(); - virtual bool Run(); void Quit(sem_id shutdownSemaphore = -1); + virtual bool Run(); + virtual port_id MessagePort() const { return fMessagePort; } + /*! \brief Determines whether the application is the active one \return true if active, false if not. @@ -78,7 +77,6 @@ class ServerApp : public MessageLooper { virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); virtual void _MessageLooper(); virtual void _GetLooperName(char* name, size_t size); - virtual port_id _MessagePort() const { return fMessagePort; } port_id fMessagePort; port_id fClientReplyPort; @@ -88,6 +86,7 @@ class ServerApp : public MessageLooper { int32 fClientToken; // To send a BMessage to the client (port + token) + Desktop* fDesktop; BString fSignature; team_id fClientTeam; diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index dfa2fb1d13..e8c5bd2efc 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -55,6 +55,7 @@ public: uint32 feel, uint32 flags, uint32 workspace); virtual bool Run(); + virtual port_id MessagePort() const { return fMessagePort; } void ReplaceDecorator(); void Show(); @@ -113,7 +114,6 @@ private: void _MessageLooper(); virtual void _PrepareQuit(); virtual void _GetLooperName(char* name, size_t size); - virtual port_id _MessagePort() const { return fMessagePort; } // TODO: Move me elsewhere status_t PictureToRegion(ServerPicture *picture,