From 36deda69baff1eaaa1ba0693a3e06f03cb6a1839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 31 Oct 2005 19:35:46 +0000 Subject: [PATCH] Got rid of sDesktop. Moved AS_ACTIVATE_APP over to Desktop. _CursorThread() is currently dysfunctional (but not enabled anyway). Minor cleanup (Desktop::WindowList() is now a BObjectList). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14599 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/AppServer.cpp | 168 ++++++++++++++++------------------ src/servers/app/AppServer.h | 17 +++- src/servers/app/Desktop.cpp | 86 +++++++++++++++-- src/servers/app/Desktop.h | 18 ++-- src/servers/app/RootLayer.cpp | 21 +++-- 5 files changed, 192 insertions(+), 118 deletions(-) diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index d796383734..0cb2636963 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -64,10 +64,7 @@ // Globals -static Desktop *sDesktop; - port_id gAppServerPort; - static AppServer *sAppServer; //! System-wide GUI color object @@ -162,13 +159,8 @@ AppServer::AppServer() // Create the bitmap allocator. Object declared in BitmapManager.cpp gBitmapManager = new BitmapManager(); - // Set up the Desktop - sDesktop = new Desktop(); - sDesktop->Init(); - sDesktop->Run(); - #if 0 - LaunchCursorThread(); + _LaunchCursorThread(); #endif } @@ -187,11 +179,22 @@ AppServer::~AppServer() } +/*! + \brief The call that starts it all... +*/ +void +AppServer::RunLooper() +{ + rename_thread(find_thread(NULL), "picasso"); + _message_thread((void *)this); +} + + /*! \brief Starts Input Server */ void -AppServer::LaunchInputServer() +AppServer::_LaunchInputServer() { // We are supposed to start the input_server, but it's a BApplication // that depends on the registrar running, which is started after app_server @@ -250,10 +253,11 @@ AppServer::LaunchInputServer() \brief Starts the Cursor Thread */ void -AppServer::LaunchCursorThread() +AppServer::_LaunchCursorThread() { // Spawn our cursor thread - fCursorThreadID = spawn_thread(CursorThread, "CursorThreadOfTheDeath", B_REAL_TIME_DISPLAY_PRIORITY - 1, this); + fCursorThreadID = spawn_thread(_CursorThread, "CursorThreadOfTheDeath", + B_REAL_TIME_DISPLAY_PRIORITY - 1, this); if (fCursorThreadID >= 0) resume_thread(fCursorThreadID); @@ -263,11 +267,11 @@ AppServer::LaunchCursorThread() \brief The Cursor Thread task */ int32 -AppServer::CursorThread(void* data) +AppServer::_CursorThread(void* data) { AppServer *server = (AppServer *)data; - server->LaunchInputServer(); + server->_LaunchInputServer(); do { while (acquire_sem(server->fCursorSem) == B_OK) { @@ -275,7 +279,7 @@ AppServer::CursorThread(void* data) p.y = *server->fCursorAddr & 0x7fff; p.x = *server->fCursorAddr >> 15 & 0x7fff; - sDesktop->GetHWInterface()->MoveCursorTo(p.x, p.y); + //sDesktop->GetHWInterface()->MoveCursorTo(p.x, p.y); STRACE(("CursorThread : %f, %f\n", p.x, p.y)); } @@ -287,13 +291,48 @@ AppServer::CursorThread(void* data) /*! - \brief The call that starts it all... + \brief Creates a desktop object for an authorized user */ -void -AppServer::RunLooper() +Desktop * +AppServer::_CreateDesktop(uid_t userID) { - rename_thread(find_thread(NULL), "picasso"); - _message_thread((void *)this); + BAutolock locker(fDesktopLock); + Desktop* desktop = NULL; + try { + desktop = new Desktop(userID); + + desktop->Init(); + desktop->Run(); + + if (!fDesktops.AddItem(desktop)) { + delete desktop; + return NULL; + } + } catch (...) { + // there is obviously no memory left + return NULL; + } + + return desktop; +} + + +/*! + \brief Finds the desktop object that belongs to a certain user +*/ +Desktop * +AppServer::_FindDesktop(uid_t userID) +{ + BAutolock locker(fDesktopLock); + + for (int32 i = 0; i < fDesktops.CountItems(); i++) { + Desktop* desktop = fDesktops.ItemAt(i); + + if (desktop->UserID() == userID) + return desktop; + } + + return NULL; } @@ -316,9 +355,17 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) int32 userID; msg.Read(&userID); + Desktop* desktop = _FindDesktop(userID); + if (desktop == NULL) { + // we need to create a new desktop object for this user + // ToDo: test if the user exists on the system + // ToDo: maybe have a separate AS_START_DESKTOP_SESSION for authorizing the user + desktop = _CreateDesktop(userID); + } + BPrivate::LinkSender reply(replyPort); reply.StartMessage(B_OK); - reply.Attach(sDesktop->MessagePort()); + reply.Attach(desktop->MessagePort()); reply.Flush(); break; } @@ -350,18 +397,22 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) #if TEST_MODE case B_QUIT_REQUESTED: { - thread_id thread = sDesktop->Thread(); - // We've been asked to quit, so (for now) broadcast to all - // test apps to quit. This situation will occur only when the server + // desktops to quit. This situation will occur only when the server // is compiled as a regular Be application. - sDesktop->PostMessage(B_QUIT_REQUESTED); fQuitting = true; - // we just wait for the desktop to kill itself - status_t status; - wait_for_thread(thread, &status); + while (fDesktops.CountItems() > 0) { + Desktop *desktop = fDesktops.RemoveItemAt(0); + + thread_id thread = sDesktop->Thread(); + desktop->PostMessage(B_QUIT_REQUESTED); + + // we just wait for the desktop to kill itself + status_t status; + wait_for_thread(thread, &status); + } kill_thread(fCursorThreadID); delete this; @@ -372,67 +423,6 @@ AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) } #endif - case AS_SET_SYSCURSOR_DEFAULTS: - { - sDesktop->GetCursorManager().SetDefaults(); - break; - } - - case AS_ACTIVATE_APP: - { - // Someone is requesting to activation of a certain app. - - // Attached data: - // 1) port_id reply port - // 2) team_id team - - status_t error = B_OK; - - // get the parameters - port_id replyPort; - team_id team; - if (msg.Read(&replyPort) < B_OK - || msg.Read(&team) < B_OK) { - error = B_ERROR; - } - - // activate one of the app's windows. - if (error == B_OK) { - error = B_BAD_TEAM_ID; - if (sDesktop->Lock()) { - // search for an unhidden window to give focus to - int32 windowCount = sDesktop->WindowList().CountItems(); - Layer *layer; - for (int32 i = 0; i < windowCount; ++i) - // is this layer in fact a WinBorder? - if ((layer = static_cast(sDesktop->WindowList().ItemAtFast(i)))) { - WinBorder *winBorder = dynamic_cast(layer); - // if winBorder is valid and not hidden, then we've found our target - if (winBorder && !winBorder->IsHidden() - && winBorder->App()->ClientTeam() == team) { - if (sDesktop->ActiveRootLayer() - && sDesktop->ActiveRootLayer()->Lock()) { - sDesktop->ActiveRootLayer()->SetActive(winBorder); - sDesktop->ActiveRootLayer()->Unlock(); - - if (sDesktop->ActiveRootLayer()->Active() == winBorder) - error = B_OK; - else - error = B_ERROR; - } - } - } - sDesktop->Unlock(); - } - } - - // send the reply - BPrivate::PortLink replyLink(replyPort); - replyLink.StartMessage(error); - replyLink.Flush(); - break; - } - default: STRACE(("Server::MainLoop received unexpected code %ld (offset %ld)\n", code, code - SERVER_TRUE)); diff --git a/src/servers/app/AppServer.h b/src/servers/app/AppServer.h index c8a5be4c61..4200166736 100644 --- a/src/servers/app/AppServer.h +++ b/src/servers/app/AppServer.h @@ -14,12 +14,15 @@ #include #include #include +#include + #include "ServerConfig.h" #include "MessageLooper.h" class ServerApp; class BitmapManager; class ColorSet; +class Desktop; namespace BPrivate { class PortLink; @@ -44,11 +47,14 @@ class AppServer : public MessageLooper { private: virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver& link); - void LaunchCursorThread(); - void LaunchInputServer(); -// static int32 PollerThread(void *data); - static int32 CursorThread(void *data); + Desktop* _CreateDesktop(uid_t userID); + Desktop* _FindDesktop(uid_t userID); + + void _LaunchCursorThread(); + void _LaunchInputServer(); + + static int32 _CursorThread(void *data); private: port_id fMessagePort; @@ -60,6 +66,9 @@ class AppServer : public MessageLooper { area_id fCursorArea; uint32 *fCursorAddr; + BObjectList fDesktops; + BLocker fDesktopLock; + port_id fISASPort; port_id fISPort; }; diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 8235a05f4e..ad3edb7ece 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -56,8 +56,9 @@ #endif -Desktop::Desktop() +Desktop::Desktop(uid_t userID) : MessageLooper("desktop"), + fUserID(userID), fSettings(new DesktopSettings::Private()), fAppListLock("application list"), fShutdownSemaphore(-1), @@ -236,6 +237,38 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) break; } + case AS_ACTIVATE_APP: + { + // Someone is requesting to activation of a certain app. + + // Attached data: + // 1) port_id reply port + // 2) team_id team + + status_t status; + + // get the parameters + port_id replyPort; + team_id team; + if (link.Read(&replyPort) == B_OK + && link.Read(&team) == B_OK) + status = _ActivateApp(team); + else + status = B_ERROR; + + // send the reply + BPrivate::PortLink replyLink(replyPort); + replyLink.StartMessage(status); + replyLink.Flush(); + break; + } + + case AS_SET_SYSCURSOR_DEFAULTS: + { + GetCursorManager().SetDefaults(); + 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 @@ -272,6 +305,39 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) } +/*! + \brief activate one of the app's windows. +*/ +status_t +Desktop::_ActivateApp(team_id team) +{ + status_t status = B_BAD_TEAM_ID; + + // search for an unhidden window to give focus to + int32 windowCount = WindowList().CountItems(); + for (int32 i = 0; i < windowCount; ++i) { + // is this layer in fact a WinBorder? + WinBorder *winBorder = WindowList().ItemAt(i); + + // if winBorder is valid and not hidden, then we've found our target + if (winBorder != NULL && !winBorder->IsHidden() + && winBorder->App()->ClientTeam() == team) { + if (fRootLayer->Lock()) { + fRootLayer->SetActive(winBorder); + fRootLayer->Unlock(); + + if (fRootLayer->Active() == winBorder) + return B_OK; + + status = B_ERROR; + } + } + } + + return status; +} + + /*! \brief Send a quick (no attachments) message to all applications @@ -295,9 +361,7 @@ Desktop::BroadcastToAllApps(int32 code) } -//--------------------------------------------------------------------------- -// Methods for layer(WinBorder) manipulation. -//--------------------------------------------------------------------------- +// #pragma mark - Methods for WinBorder manipulation void @@ -521,6 +585,16 @@ Desktop::FindWinBorderByClientToken(int32 token, team_id teamID) } +const BObjectList & +Desktop::WindowList() const +{ + if (!IsLocked()) + debugger("You must lock before getting registered windows list\n"); + + return fWinBorderList; +} + + void Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) { @@ -531,7 +605,7 @@ Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) int32 count = 0; if (team >= B_OK) { for (int32 i = 0; i < fWinBorderList.CountItems(); i++) { - WinBorder* border = (WinBorder*)fWinBorderList.ItemAt(i); + WinBorder* border = fWinBorderList.ItemAt(i); if (border->Window()->ClientTeam() == team) count++; @@ -545,7 +619,7 @@ Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) sender.Attach(count); for (int32 i = 0; i < fWinBorderList.CountItems(); i++) { - WinBorder* border = (WinBorder*)fWinBorderList.ItemAt(i); + WinBorder* border = fWinBorderList.ItemAt(i); if (team >= B_OK && border->Window()->ClientTeam() != team) continue; diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index cc0dcb001b..c688f3081b 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -22,6 +22,7 @@ #include #include #include +#include class BMessage; @@ -40,10 +41,12 @@ namespace BPrivate { class Desktop : public MessageLooper, public ScreenOwner { public: // startup methods - Desktop(); + Desktop(uid_t userID); virtual ~Desktop(); void Init(); + + uid_t UserID() const { return fUserID; } virtual port_id MessagePort() const { return fMessagePort; } void BroadcastToAllApps(int32 code); @@ -79,18 +82,14 @@ class Desktop : public MessageLooper, public ScreenOwner { WinBorder* FindWinBorderByClientToken(int32 token, team_id teamID); //WinBorder* FindWinBorderByServerToken(int32 token); - // get list of registed windows - const BList& WindowList() const - { - if (!IsLocked()) - debugger("You must lock before getting registered windows list\n"); - return fWinBorderList; - } + // get list of registed windows + const BObjectList& WindowList() const; void WriteWindowList(team_id team, BPrivate::LinkSender& sender); void WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender); private: + status_t _ActivateApp(team_id team); virtual void _GetLooperName(char* name, size_t size); virtual void _PrepareQuit(); virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); @@ -98,6 +97,7 @@ class Desktop : public MessageLooper, public ScreenOwner { private: friend class DesktopSettings; + uid_t fUserID; ::VirtualScreen fVirtualScreen; DesktopSettings::Private* fSettings; port_id fMessagePort; @@ -108,7 +108,7 @@ class Desktop : public MessageLooper, public ScreenOwner { sem_id fShutdownSemaphore; int32 fShutdownCount; - BList fWinBorderList; + BObjectList fWinBorderList; RootLayer* fRootLayer; Screen* fActiveScreen; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index e2f87a4850..13f7c1aee1 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -539,18 +539,18 @@ bool RootLayer::SetActiveWorkspace(int32 index) // we need to lock the window list here so no other window can be created fDesktop->Lock(); - const BList& windowList = fDesktop->WindowList(); + const BObjectList& windowList = fDesktop->WindowList(); + int32 windowCount = windowList.CountItems(); - int32 ptrCount = windowList.CountItems(); - WinBorder **ptrWin = (WinBorder**)windowList.Items(); + for (int32 i = 0; i < windowCount; i++) { + WinBorder* winBorder = windowList.ItemAt(i); - for (int32 i = 0; i < ptrCount; i++) { - if (ptrWin[i]->Workspaces() & (0x00000001UL << index)) { - fWorkspace[index]->AddWinBorder(ptrWin[i]); + // is WinBorder on this workspace? + if (winBorder->Workspaces() & (0x00000001UL << index)) { + fWorkspace[index]->AddWinBorder(winBorder); - if (!ptrWin[i]->IsHidden()) { - fWorkspace[index]->ShowWinBorder(ptrWin[i]); - } + if (!winBorder->IsHidden()) + fWorkspace[index]->ShowWinBorder(winBorder); } } @@ -1679,7 +1679,8 @@ RootLayer::ReadMessageFromPort(bigtime_t tout) return bmsg; } -//------------------------------------------------------------------------------ + + BMessage* RootLayer::ConvertToMessage(void* raw, int32 code) {