2 * Copyright 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Axel Dörfler, axeld@pinc-software.de
8 * Stephan Aßmus <superstippi@gmx.de>
13 #include "AppServer.h"
17 #include <LaunchRoster.h>
20 #include "BitmapManager.h"
22 #include "FontManager.h"
23 #include "InputManager.h"
24 #include "ScreenManager.h"
25 #include "ServerProtocol.h"
28 //#define DEBUG_SERVER
31 # define STRACE(x) printf x
38 port_id gAppServerPort
;
39 BTokenSpace gTokenSpace
;
40 uint32 gAppServerSIMDFlags
= 0;
43 /*! \brief Constructor
45 This loads the default fonts, allocates all the major global variables,
46 spawns the main housekeeping threads, loads user preferences for the UI
47 and decorator, and allocates various locks.
49 AppServer::AppServer(status_t
* status
)
51 SERVER_BASE("application/x-vnd.Haiku-app_server", "picasso", -1, false,
53 fDesktopLock("AppServerDesktopLock")
55 openlog("app_server", 0, LOG_DAEMON
);
57 gInputManager
= new InputManager();
59 // Create the font server and scan the proper directories.
60 gFontManager
= new FontManager
;
61 if (gFontManager
->InitCheck() != B_OK
)
62 debugger("font manager could not be initialized!");
66 gScreenManager
= new ScreenManager();
67 gScreenManager
->Run();
69 // Create the bitmap allocator. Object declared in BitmapManager.cpp
70 gBitmapManager
= new BitmapManager();
72 // TODO: check the attached displays, and launch login session for them
74 data
.AddString("name", "app_server");
75 data
.AddInt32("session", 0);
76 BLaunchRoster().Target("login", data
);
81 Reached only when the server is asked to shut down in Test mode.
83 AppServer::~AppServer()
85 delete gBitmapManager
;
87 gScreenManager
->Lock();
88 gScreenManager
->Quit();
98 AppServer::MessageReceived(BMessage
* message
)
100 switch (message
->what
) {
103 Desktop
* desktop
= NULL
;
105 int32 userID
= message
->GetInt32("user", 0);
106 int32 version
= message
->GetInt32("version", 0);
107 const char* targetScreen
= message
->GetString("target");
109 if (version
!= AS_PROTOCOL_VERSION
) {
110 syslog(LOG_ERR
, "Application for user %" B_PRId32
" does not "
111 "support the current server protocol.\n", userID
);
113 desktop
= _FindDesktop(userID
, targetScreen
);
114 if (desktop
== NULL
) {
115 // we need to create a new desktop object for this user
116 // TODO: test if the user exists on the system
117 // TODO: maybe have a separate AS_START_DESKTOP_SESSION for
118 // authorizing the user
119 desktop
= _CreateDesktop(userID
, targetScreen
);
125 reply
.AddInt32("port", desktop
->MessagePort());
127 reply
.what
= (uint32
)B_ERROR
;
129 message
->SendReply(&reply
);
134 // We don't allow application scripting
135 STRACE(("AppServer received unexpected code %" B_PRId32
"\n",
143 AppServer::QuitRequested()
146 while (fDesktops
.CountItems() > 0) {
147 Desktop
*desktop
= fDesktops
.RemoveItemAt(0);
149 thread_id thread
= desktop
->Thread();
150 desktop
->PostMessage(B_QUIT_REQUESTED
);
152 // we just wait for the desktop to kill itself
154 wait_for_thread(thread
, &status
);
160 return SERVER_BASE::QuitRequested();
168 /*! \brief Creates a desktop object for an authorized user
171 AppServer::_CreateDesktop(uid_t userID
, const char* targetScreen
)
173 BAutolock
locker(fDesktopLock
);
174 Desktop
* desktop
= NULL
;
176 desktop
= new Desktop(userID
, targetScreen
);
178 status_t status
= desktop
->Init();
179 if (status
== B_OK
) {
183 if (status
== B_OK
&& !fDesktops
.AddItem(desktop
))
184 status
= B_NO_MEMORY
;
186 if (status
!= B_OK
) {
187 syslog(LOG_ERR
, "Cannot initialize Desktop object: %s\n",
193 // there is obviously no memory left
201 /*! \brief Finds the desktop object that belongs to a certain user
204 AppServer::_FindDesktop(uid_t userID
, const char* targetScreen
)
206 BAutolock
locker(fDesktopLock
);
208 for (int32 i
= 0; i
< fDesktops
.CountItems(); i
++) {
209 Desktop
* desktop
= fDesktops
.ItemAt(i
);
211 if (desktop
->UserID() == userID
212 && ((desktop
->TargetScreen() == NULL
&& targetScreen
== NULL
)
213 || (desktop
->TargetScreen() != NULL
&& targetScreen
!= NULL
214 && strcmp(desktop
->TargetScreen(), targetScreen
) == 0))) {
227 main(int argc
, char** argv
)
229 srand(real_time_clock_usecs());
232 AppServer
* server
= new AppServer(&status
);
236 return status
== B_OK
? EXIT_SUCCESS
: EXIT_FAILURE
;