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
This commit is contained in:
Axel Dörfler 2005-10-31 19:35:46 +00:00
parent 0755123f83
commit 36deda69ba
5 changed files with 192 additions and 118 deletions

View File

@ -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<int32>(&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<port_id>(sDesktop->MessagePort());
reply.Attach<port_id>(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<Layer*>(sDesktop->WindowList().ItemAtFast(i)))) {
WinBorder *winBorder = dynamic_cast<WinBorder*>(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));

View File

@ -14,12 +14,15 @@
#include <Application.h>
#include <Window.h>
#include <String.h>
#include <ObjectList.h>
#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<Desktop> fDesktops;
BLocker fDesktopLock;
port_id fISASPort;
port_id fISPort;
};

View File

@ -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<WinBorder> &
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<int32>(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;

View File

@ -22,6 +22,7 @@
#include <Locker.h>
#include <Menu.h>
#include <Autolock.h>
#include <ObjectList.h>
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<WinBorder>& 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<WinBorder> fWinBorderList;
RootLayer* fRootLayer;
Screen* fActiveScreen;

View File

@ -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<WinBorder>& 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)
{