The Desktop class now gets its own message processing loop: moved application

creation/deletion (and management) over to that class.
ServerApp now gets a desktop pointer, and no longer uses gDesktop.
Converted private MessageLooper::_MessagePort() to a public method MessagePort()
so that the looper can be addressed from elsewhere without using PostMessage().
Added a real basic message loop to MessageLooper::_MessageLoop().
BApplication now only asks the app_server to get its desktop object which should
now be used for everything that's not in the realm of the application.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13824 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-07-25 21:08:34 +00:00
parent 5845b8c325
commit 770c05d6cc
11 changed files with 320 additions and 260 deletions

View File

@ -21,6 +21,7 @@ enum {
AS_SERVER_SESSION,
AS_SERVER_PORTLINK,
AS_CLIENT_DEAD,
AS_GET_DESKTOP,
// Desktop definitions
AS_GET_WINDOW_LIST,

View File

@ -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<port_id>(clientPort);
fServerLink->Attach<int32>(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<port_id>(&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<port_id>(clientPort);
@ -1096,9 +1110,8 @@ BApplication::connect_to_app_server()
fServerLink->Attach<int32>(_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<port_id>(&serverPort);

View File

@ -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<port_id>(&clientReplyPort);
msg.Read<port_id>(&clientLooperPort);
msg.Read<team_id>(&clientTeamID);
msg.Read<int32>(&htoken);
if (msg.ReadString(&appSignature) != B_OK)
port_id replyPort;
if (msg.Read<port_id>(&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<int32>(&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_id>(&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<port_id>(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

View File

@ -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;

View File

@ -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<port_id>(&clientReplyPort);
link.Read<port_id>(&clientLooperPort);
link.Read<team_id>(&clientTeamID);
link.Read<int32>(&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_id>(&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.
//---------------------------------------------------------------------------

View File

@ -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;

View File

@ -10,6 +10,7 @@
#include "MessageLooper.h"
#include <Autolock.h>
#include <stdio.h>
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();
}
}

View File

@ -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 */

View File

@ -10,6 +10,10 @@
* Axel Dörfler, axeld@pinc-software.de
*/
/*!
\class ServerApp ServerApp.h
\brief Counterpart to BApplication within the app_server
*/
#include <stdio.h>
#include <string.h>
@ -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_id>(Thread());
link.Flush();
@ -560,14 +566,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
team_id team;
link.Read<team_id>(&team);
gDesktop->WriteWindowList(team, fLink.Sender());
fDesktop->WriteWindowList(team, fLink.Sender());
break;
case AS_GET_WINDOW_INFO:
int32 serverToken;
link.Read<int32>(&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<int32>(&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<int32>(&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<int32>(&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<int32>(&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<scroll_bar_info>(&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<menu_info>(&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<mode_mouse>(&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<mode_mouse>(settings.MouseMode());
@ -1160,7 +1165,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<ColorSet>(&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<display_mode>(&target);
link.Read<display_mode>(&low);
link.Read<display_mode>(&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<uint32>(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<accelerant_device_info>(accelerantInfo);
} else
@ -2059,7 +2064,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
screen_id id;
link.Read<screen_id>(&id);
sem_id semaphore = gDesktop->GetHWInterface()->RetraceSemaphore();
sem_id semaphore = fDesktop->GetHWInterface()->RetraceSemaphore();
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<sem_id>(semaphore);
fLink.Flush();
@ -2074,7 +2079,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<screen_id>(&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<display_timing_constraints>(constraints);
} else
@ -2094,7 +2099,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<display_mode>(&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<uint32>(low);
fLink.Attach<uint32>(high);
@ -2114,7 +2119,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
uint32 mode;
link.Read<uint32>(&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<screen_id>(&id);
uint32 state = gDesktop->GetHWInterface()->DPMSMode();
uint32 state = fDesktop->GetHWInterface()->DPMSMode();
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<uint32>(state);
fLink.Flush();
@ -2143,7 +2148,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
screen_id id;
link.Read<screen_id>(&id);
uint32 capabilities = gDesktop->GetHWInterface()->DPMSCapabilities();
uint32 capabilities = fDesktop->GetHWInterface()->DPMSCapabilities();
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<uint32>(capabilities);
fLink.Flush();

View File

@ -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;

View File

@ -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,