2 * Copyright 2001-2016, 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 (%" B_PRId32
").\n",
114 desktop
= _FindDesktop(userID
, targetScreen
);
115 if (desktop
== NULL
) {
116 // we need to create a new desktop object for this user
117 // TODO: test if the user exists on the system
118 // TODO: maybe have a separate AS_START_DESKTOP_SESSION for
119 // authorizing the user
120 desktop
= _CreateDesktop(userID
, targetScreen
);
126 reply
.AddInt32("port", desktop
->MessagePort());
128 reply
.what
= (uint32
)B_ERROR
;
130 message
->SendReply(&reply
);
135 // We don't allow application scripting
136 STRACE(("AppServer received unexpected code %" B_PRId32
"\n",
144 AppServer::QuitRequested()
147 while (fDesktops
.CountItems() > 0) {
148 Desktop
*desktop
= fDesktops
.RemoveItemAt(0);
150 thread_id thread
= desktop
->Thread();
151 desktop
->PostMessage(B_QUIT_REQUESTED
);
153 // we just wait for the desktop to kill itself
155 wait_for_thread(thread
, &status
);
161 return SERVER_BASE::QuitRequested();
169 /*! \brief Creates a desktop object for an authorized user
172 AppServer::_CreateDesktop(uid_t userID
, const char* targetScreen
)
174 BAutolock
locker(fDesktopLock
);
175 Desktop
* desktop
= NULL
;
177 desktop
= new Desktop(userID
, targetScreen
);
179 status_t status
= desktop
->Init();
181 status
= desktop
->Run();
182 if (status
== B_OK
&& !fDesktops
.AddItem(desktop
))
183 status
= B_NO_MEMORY
;
185 if (status
!= B_OK
) {
186 syslog(LOG_ERR
, "Cannot initialize Desktop object: %s\n",
192 // there is obviously no memory left
200 /*! \brief Finds the desktop object that belongs to a certain user
203 AppServer::_FindDesktop(uid_t userID
, const char* targetScreen
)
205 BAutolock
locker(fDesktopLock
);
207 for (int32 i
= 0; i
< fDesktops
.CountItems(); i
++) {
208 Desktop
* desktop
= fDesktops
.ItemAt(i
);
210 if (desktop
->UserID() == userID
211 && ((desktop
->TargetScreen() == NULL
&& targetScreen
== NULL
)
212 || (desktop
->TargetScreen() != NULL
&& targetScreen
!= NULL
213 && strcmp(desktop
->TargetScreen(), targetScreen
) == 0))) {
226 main(int argc
, char** argv
)
228 srand(real_time_clock_usecs());
231 AppServer
* server
= new AppServer(&status
);
235 return status
== B_OK
? EXIT_SUCCESS
: EXIT_FAILURE
;