usb_ecm: Use the current configuration instead of a fixed one.
[haiku.git] / src / servers / app / AppServer.cpp
blob9090086e728e41616ed434b43d0f1604aa57df2f
1 /*
2 * Copyright 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Axel Dörfler, axeld@pinc-software.de
8 * Stephan Aßmus <superstippi@gmx.de>
9 * Christian Packmann
13 #include "AppServer.h"
15 #include <syslog.h>
17 #include <LaunchRoster.h>
18 #include <PortLink.h>
20 #include "BitmapManager.h"
21 #include "Desktop.h"
22 #include "FontManager.h"
23 #include "InputManager.h"
24 #include "ScreenManager.h"
25 #include "ServerProtocol.h"
28 //#define DEBUG_SERVER
29 #ifdef DEBUG_SERVER
30 # include <stdio.h>
31 # define STRACE(x) printf x
32 #else
33 # define STRACE(x) ;
34 #endif
37 // Globals
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,
52 status),
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!");
64 gFontManager->Run();
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
73 BMessage data;
74 data.AddString("name", "app_server");
75 data.AddInt32("session", 0);
76 BLaunchRoster().Target("login", data);
80 /*! \brief Destructor
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();
90 gFontManager->Lock();
91 gFontManager->Quit();
93 closelog();
97 void
98 AppServer::MessageReceived(BMessage* message)
100 switch (message->what) {
101 case AS_GET_DESKTOP:
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);
112 } else {
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);
123 BMessage reply;
124 if (desktop != NULL)
125 reply.AddInt32("port", desktop->MessagePort());
126 else
127 reply.what = (uint32)B_ERROR;
129 message->SendReply(&reply);
130 break;
133 default:
134 // We don't allow application scripting
135 STRACE(("AppServer received unexpected code %" B_PRId32 "\n",
136 message->what));
137 break;
142 bool
143 AppServer::QuitRequested()
145 #if TEST_MODE
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
153 status_t status;
154 wait_for_thread(thread, &status);
157 delete this;
158 exit(0);
160 return SERVER_BASE::QuitRequested();
161 #else
162 return false;
163 #endif
168 /*! \brief Creates a desktop object for an authorized user
170 Desktop*
171 AppServer::_CreateDesktop(uid_t userID, const char* targetScreen)
173 BAutolock locker(fDesktopLock);
174 Desktop* desktop = NULL;
175 try {
176 desktop = new Desktop(userID, targetScreen);
178 status_t status = desktop->Init();
179 if (status == B_OK) {
180 if (!desktop->Run())
181 status = B_ERROR;
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",
188 strerror(status));
189 delete desktop;
190 return NULL;
192 } catch (...) {
193 // there is obviously no memory left
194 return NULL;
197 return desktop;
201 /*! \brief Finds the desktop object that belongs to a certain user
203 Desktop*
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))) {
215 return desktop;
219 return NULL;
223 // #pragma mark -
227 main(int argc, char** argv)
229 srand(real_time_clock_usecs());
231 status_t status;
232 AppServer* server = new AppServer(&status);
233 if (status == B_OK)
234 server->Run();
236 return status == B_OK ? EXIT_SUCCESS : EXIT_FAILURE;