diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 9219f7a175..ab0a19ac10 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -1,18 +1,24 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. All rights reserved. -// Distributed under the terms of the MIT license. -// -// File Name: Desktop.cpp -// Author: Adi Oanca -// Stephan Aßmus -// Description: Class used to encapsulate desktop management -// -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Adrian Oanca + * Stephan Aßmus + * Axel Dörfler, axeld@pinc-software.de + */ + +/** Class used to encapsulate desktop management */ + + #include #include #include +#include +#include + #include "AppServer.h" #include "DisplayDriverPainter.h" #include "Globals.h" @@ -50,7 +56,6 @@ Desktop::Desktop() : fWinBorderList(64), - fWinLock("desktop window list lock"), fRootLayerList(2), fActiveRootLayer(NULL), fScreenList(2), @@ -402,19 +407,84 @@ Desktop::SetWinBorderFeel(WinBorder *winBorder, uint32 feel) WinBorder * -Desktop::FindWinBorderByServerWindowTokenAndTeamID(int32 token, team_id teamID) +Desktop::FindWinBorderByClientToken(int32 token, team_id teamID) { - WinBorder *wb; + BAutolock locker(this); - Lock(); + WinBorder *wb; for (int32 i = 0; (wb = (WinBorder *)fWinBorderList.ItemAt(i)); i++) { if (wb->Window()->ClientToken() == token && wb->Window()->ClientTeam() == teamID) - break; + return wb; } - Unlock(); - return wb; + return NULL; +} + + +void +Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) +{ + BAutolock locker(this); + + // compute the number of windows + + int32 count = 0; + if (team >= B_OK) { + for (int32 i = 0; i < fWinBorderList.CountItems(); i++) { + WinBorder* border = (WinBorder*)fWinBorderList.ItemAt(i); + + if (border->Window()->ClientTeam() == team) + count++; + } + } else + count = fWinBorderList.CountItems(); + + // write list + + sender.StartMessage(SERVER_TRUE); + sender.Attach(count); + + for (int32 i = 0; i < fWinBorderList.CountItems(); i++) { + WinBorder* border = (WinBorder*)fWinBorderList.ItemAt(i); + + if (team >= B_OK && border->Window()->ClientTeam() != team) + continue; + + sender.Attach(border->Window()->ServerToken()); + } + + sender.Flush(); +} + + +void +Desktop::WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender) +{ + BAutolock locker(this); + BAutolock tokenLocker(BPrivate::gDefaultTokens); + + ServerWindow* window; + if (BPrivate::gDefaultTokens.GetToken(serverToken, + B_SERVER_TOKEN, (void**)&window) != B_OK) { + sender.StartMessage(B_ENTRY_NOT_FOUND); + sender.Flush(); + return; + } + + window_info info; + window->GetInfo(info); + + int32 length = window->Title() ? strlen(window->Title()) : 0; + + sender.StartMessage(B_OK); + sender.Attach(sizeof(window_info) + length + 1); + sender.Attach(&info, sizeof(window_info)); + if (length > 0) + sender.Attach(window->Title(), length + 1); + else + sender.Attach('\0'); + sender.Flush(); } diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index c5ca068019..dde8faaed2 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -1,31 +1,38 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. All rights reserved. -// Distributed under the terms of the MIT license. -// -// File Name: Desktop.h -// Author: Adi Oanca -// Stephan Aßmus -// Description: Class used to encapsulate desktop management -// -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Adrian Oanca + * Stephan Aßmus + * Axel Dörfler, axeld@pinc-software.de + */ #ifndef _DESKTOP_H_ #define _DESKTOP_H_ + #include #include #include #include -#include +#include + +#include "ServerScreen.h" class BMessage; -class BPortLink; + class DisplayDriver; class HWInterface; class Layer; class RootLayer; class WinBorder; -class Desktop { +namespace BPrivate { + class LinkSender; +}; + + +class Desktop : public BLocker { public: // startup methods Desktop(); @@ -64,13 +71,11 @@ class Desktop { inline int32 CountRootLayers() const { return fRootLayerList.CountItems(); } - inline DisplayDriver* GetDisplayDriver() const { return ScreenAt(0)->GetDisplayDriver(); } inline HWInterface* GetHWInterface() const { return ScreenAt(0)->GetHWInterface(); } - // Methods for layer(WinBorder) manipulation. void AddWinBorder(WinBorder *winBorder); void RemoveWinBorder(WinBorder *winBorder); @@ -81,8 +86,9 @@ class Desktop { void RemoveWinBorderFromSubset(WinBorder *winBorder, WinBorder *fromWinBorder); - WinBorder* FindWinBorderByServerWindowTokenAndTeamID(int32 token, - team_id teamID); + WinBorder* FindWinBorderByClientToken(int32 token, team_id teamID); + //WinBorder* FindWinBorderByServerToken(int32 token); + // get list of registed windows const BList& WindowList() const { @@ -91,13 +97,8 @@ class Desktop { return fWinBorderList; } - // locking with regards to registered windows list - bool Lock() - { return fWinLock.Lock(); } - void Unlock() - { return fWinLock.Unlock(); } - bool IsLocked() const - { return fWinLock.IsLocked(); } + void WriteWindowList(team_id team, BPrivate::LinkSender& sender); + void WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender); // Methods for various desktop stuff handled by the server void SetScrollBarInfo(const scroll_bar_info &info); @@ -119,7 +120,6 @@ class Desktop { void _AddGraphicsCard(HWInterface* interface); BList fWinBorderList; - BLocker fWinLock; BList fRootLayerList; RootLayer* fActiveRootLayer; @@ -135,4 +135,4 @@ class Desktop { extern Desktop *gDesktop; -#endif // _DESKTOP_H_ +#endif // _DESKTOP_H_ diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 524da811dd..0b8e2878f1 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -609,6 +609,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // LayerData ld; switch (code) { + case AS_GET_WINDOW_LIST: + team_id team; + link.Read(&team); + + gDesktop->WriteWindowList(team, fLink.Sender()); + break; + + case AS_GET_WINDOW_INFO: + int32 serverToken; + link.Read(&serverToken); + + gDesktop->WriteWindowInfo(serverToken, fLink.Sender()); + break; + case AS_UPDATE_COLORS: { // NOTE: R2: Eventually we will have windows which will notify their children of changes in diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 8755e6ce93..055a1864f3 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "AppServer.h" #include "BGet++.h" @@ -87,6 +89,8 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app, fCurrentLayer(NULL) { STRACE(("ServerWindow(%s)::ServerWindow()\n", title)); + + fServerToken = BPrivate::gDefaultTokens.NewToken(B_SERVER_TOKEN, this); } @@ -102,6 +106,8 @@ ServerWindow::~ServerWindow() free(const_cast(fTitle)); + BPrivate::gDefaultTokens.RemoveToken(fServerToken); + STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle)); } @@ -317,6 +323,31 @@ ServerWindow::NotifyScreenModeChanged(const BRect frame, const color_space color SendMessageToClient(&msg); } + +void +ServerWindow::GetInfo(window_info& info) +{ + info.team = ClientTeam(); + info.server_token = ServerToken(); + + info.thread = Thread(); + info.client_token = ClientToken(); + info.client_port = fClientLooperPort; + info.workspaces = fWinBorder->Workspaces(); + + info.layer = 0; // ToDo: what is this??? + info.type = kNormalWindow; // ToDo: do this for real + info.flags = fWinBorder->WindowFlags(); + info.window_left = (int)floor(fWinBorder->Frame().left); + info.window_top = (int)floor(fWinBorder->Frame().top); + info.window_right = (int)floor(fWinBorder->Frame().right); + info.window_bottom = (int)floor(fWinBorder->Frame().bottom); + + info.show_hide_level = fWinBorder->IsHidden() ? 1 : -1; // ??? + info.is_mini = fWinBorder->IsHidden(); +} + + /*! \brief Sets the font state for a layer \param layer The layer to set the font @@ -1185,15 +1216,15 @@ myRootLayer->Unlock(); case AS_ADD_TO_SUBSET: { STRACE(("ServerWindow %s: Message AS_ADD_TO_SUBSET\n", Title())); - WinBorder *wb; + WinBorder *windowBorder; int32 mainToken; team_id teamID; link.Read(&mainToken); link.Read(&teamID, sizeof(team_id)); - wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID); - if (wb) { + windowBorder = gDesktop->FindWinBorderByClientToken(mainToken, teamID); + if (windowBorder) { fLink.StartMessage(SERVER_TRUE); fLink.Flush(); @@ -1201,7 +1232,7 @@ myRootLayer->Unlock(); BPrivate::PortLink msg(-1, -1); msg.StartMessage(AS_ROOTLAYER_ADD_TO_SUBSET); msg.Attach(fWinBorder); - msg.Attach(wb); + msg.Attach(windowBorder); fWinBorder->GetRootLayer()->EnqueueMessage(msg); } else { fLink.StartMessage(SERVER_FALSE); @@ -1212,22 +1243,22 @@ myRootLayer->Unlock(); case AS_REM_FROM_SUBSET: { STRACE(("ServerWindow %s: Message AS_REM_FROM_SUBSET\n", Title())); - WinBorder *wb; + WinBorder *windowBorder; int32 mainToken; team_id teamID; link.Read(&mainToken); link.Read(&teamID, sizeof(team_id)); - wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID); - if (wb) { + windowBorder = gDesktop->FindWinBorderByClientToken(mainToken, teamID); + if (windowBorder) { fLink.StartMessage(SERVER_TRUE); fLink.Flush(); BPrivate::PortLink msg(-1, -1); msg.StartMessage(AS_ROOTLAYER_REMOVE_FROM_SUBSET); msg.Attach(fWinBorder); - msg.Attach(wb); + msg.Attach(windowBorder); fWinBorder->GetRootLayer()->EnqueueMessage(msg); } else { fLink.StartMessage(SERVER_FALSE); diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index b0b3d0609e..e2e957a754 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -37,6 +37,7 @@ class Workspace; class RootLayer; class Layer; class ServerPicture; +struct window_info; #define AS_UPDATE_DECORATOR 'asud' #define AS_UPDATE_COLORS 'asuc' @@ -103,6 +104,9 @@ public: // server "private" - try not to use. inline int32 ClientToken() const { return fHandlerToken; } + inline int32 ServerToken() const { return fServerToken; } + + void GetInfo(window_info& info); // ToDo: public?? SubWindowList fSubWindowList; @@ -144,6 +148,7 @@ private: BMessage fClientViewsWithInvalidCoords; + int32 fServerToken; int32 fHandlerToken; Layer* fCurrentLayer;