* Copyright 2001-2016, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel DΓΆrfler, axeld@pinc-software.de
* Stephan AΓmus <superstippi@gmx.de>
* Christian Packmann
*/
#include "AppServer.h"
#include <syslog.h>
#include <AutoDeleter.h>
#include <LaunchRoster.h>
#include <PortLink.h>
#include "BitmapManager.h"
#include "Desktop.h"
#include "GlobalFontManager.h"
#include "InputManager.h"
#include "ScreenManager.h"
#include "ServerProtocol.h"
#ifdef DEBUG_SERVER
# include <stdio.h>
# define STRACE(x) printf x
#else
# define STRACE(x) ;
#endif
port_id gAppServerPort;
BTokenSpace gTokenSpace;
uint32 gAppServerSIMDFlags = 0;
This loads the default fonts, allocates all the major global variables,
spawns the main housekeeping threads, loads user preferences for the UI
and decorator, and allocates various locks.
*/
AppServer::AppServer(status_t* status)
:
SERVER_BASE("application/x-vnd.Haiku-app_server", "picasso", -1, false,
status),
fDesktopLock("AppServerDesktopLock")
{
openlog("app_server", 0, LOG_DAEMON);
gInputManager = new InputManager();
gFontManager = new GlobalFontManager;
if (gFontManager->InitCheck() != B_OK)
debugger("font manager could not be initialized!");
gFontManager->Run();
gScreenManager = new ScreenManager();
gScreenManager->Run();
gBitmapManager = new BitmapManager();
#if 0
#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
BMessage data;
data.AddString("name", "app_server");
data.AddInt32("session", 0);
BLaunchRoster().Target("login", data);
#endif
#endif
}
Reached only when the server is asked to shut down in Test mode.
*/
AppServer::~AppServer()
{
delete gBitmapManager;
gScreenManager->Lock();
gScreenManager->Quit();
gFontManager->Lock();
gFontManager->Quit();
closelog();
}
void
AppServer::MessageReceived(BMessage* message)
{
switch (message->what) {
case AS_GET_DESKTOP:
{
Desktop* desktop = NULL;
int32 userID = message->GetInt32("user", 0);
int32 version = message->GetInt32("version", 0);
const char* targetScreen = message->GetString("target");
if (version != AS_PROTOCOL_VERSION) {
syslog(LOG_ERR, "Application for user %" B_PRId32 " does not "
"support the current server protocol (%" B_PRId32 ").\n",
userID, version);
} else {
desktop = _FindDesktop(userID, targetScreen);
if (desktop == NULL) {
desktop = _CreateDesktop(userID, targetScreen);
}
}
BMessage reply;
if (desktop != NULL)
reply.AddInt32("port", desktop->MessagePort());
else
reply.what = (uint32)B_ERROR;
message->SendReply(&reply);
break;
}
default:
STRACE(("AppServer received unexpected code %" B_PRId32 "\n",
message->what));
break;
}
}
bool
AppServer::QuitRequested()
{
#if TEST_MODE
while (fDesktops.CountItems() > 0) {
Desktop *desktop = fDesktops.RemoveItemAt(0);
thread_id thread = desktop->Thread();
desktop->PostMessage(B_QUIT_REQUESTED);
status_t status;
wait_for_thread(thread, &status);
}
delete this;
exit(0);
return SERVER_BASE::QuitRequested();
#else
return false;
#endif
}
*/
Desktop*
AppServer::_CreateDesktop(uid_t userID, const char* targetScreen)
{
BAutolock locker(fDesktopLock);
ObjectDeleter<Desktop> desktop;
try {
desktop.SetTo(new Desktop(userID, targetScreen));
status_t status = desktop->Init();
if (status == B_OK)
status = desktop->Run();
if (status == B_OK && !fDesktops.AddItem(desktop.Get()))
status = B_NO_MEMORY;
if (status != B_OK) {
syslog(LOG_ERR, "Cannot initialize Desktop object: %s\n",
strerror(status));
return NULL;
}
} catch (...) {
return NULL;
}
return desktop.Detach();
}
*/
Desktop*
AppServer::_FindDesktop(uid_t userID, const char* targetScreen)
{
BAutolock locker(fDesktopLock);
for (int32 i = 0; i < fDesktops.CountItems(); i++) {
Desktop* desktop = fDesktops.ItemAt(i);
if (desktop->UserID() == userID
&& ((desktop->TargetScreen() == NULL && targetScreen == NULL)
|| (desktop->TargetScreen() != NULL && targetScreen != NULL
&& strcmp(desktop->TargetScreen(), targetScreen) == 0))) {
return desktop;
}
}
return NULL;
}
int
main(int argc, char** argv)
{
srand(real_time_clock_usecs());
status_t status;
AppServer* server = new AppServer(&status);
if (status == B_OK)
server->Run();
return status == B_OK ? EXIT_SUCCESS : EXIT_FAILURE;
}