xref: /haiku/src/servers/registrar/Registrar.cpp (revision 0b2dbe7d46ee888392907c60131b7f7652314175)
1 // Registrar.cpp
2 
3 #include "Debug.h"
4 
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include <Application.h>
9 #include <Message.h>
10 #include <OS.h>
11 #include <RegistrarDefs.h>
12 #include <RosterPrivate.h>
13 
14 #include "ClipboardHandler.h"
15 #include "EventQueue.h"
16 #include "MessageDeliverer.h"
17 #include "MessageEvent.h"
18 #include "MessageRunnerManager.h"
19 #include "MessagingService.h"
20 #include "MIMEManager.h"
21 #include "Registrar.h"
22 #include "TRoster.h"
23 
24 /*!
25 	\class Registrar
26 	\brief The application class of the registrar.
27 
28 	Glues the registrar services together and dispatches the roster messages.
29 */
30 
31 using namespace BPrivate;
32 
33 //! Name of the event queue.
34 static const char *kEventQueueName = "timer_thread";
35 
36 //! Time interval between two roster sanity checks (1 s).
37 static const bigtime_t kRosterSanityEventInterval = 1000000LL;
38 
39 // constructor
40 /*!	\brief Creates the registrar application class.
41 	\param error Passed to the BApplication constructor for returning an
42 		   error code.
43 */
44 Registrar::Registrar(status_t *error)
45 		 : BServer(kRegistrarSignature, false, error),
46 		   fRoster(NULL),
47 		   fClipboardHandler(NULL),
48 		   fMIMEManager(NULL),
49 		   fEventQueue(NULL),
50 		   fMessageRunnerManager(NULL),
51 		   fSanityEvent(NULL)
52 {
53 	FUNCTION_START();
54 }
55 
56 // destructor
57 /*!	\brief Frees all resources associated with the registrar.
58 
59 	All registrar services, that haven't been shut down earlier, are
60 	terminated.
61 */
62 Registrar::~Registrar()
63 {
64 	FUNCTION_START();
65 	Lock();
66 	fEventQueue->Die();
67 	delete fMessageRunnerManager;
68 	delete fEventQueue;
69 	delete fSanityEvent;
70 	fMIMEManager->Lock();
71 	fMIMEManager->Quit();
72 	RemoveHandler(fClipboardHandler);
73 	delete fClipboardHandler;
74 	delete fRoster;
75 	// Invalidate the global be_roster, so that the BApplication destructor
76 	// won't dead-lock when sending a message to itself.
77 	BRoster::Private().SetTo(BMessenger(), BMessenger());
78 	FUNCTION_END();
79 }
80 
81 // MessageReceived
82 /*!	\brief Overrides the super class version to dispatch roster specific
83 		   messages.
84 	\param message The message to be handled
85 */
86 void
87 Registrar::MessageReceived(BMessage *message)
88 {
89 //	FUNCTION_START();
90 	switch (message->what) {
91 		// general requests
92 		case B_REG_GET_MIME_MESSENGER:
93 		{
94 			PRINT(("B_REG_GET_MIME_MESSENGER\n"));
95 			BMessenger messenger(NULL, fMIMEManager);
96 			BMessage reply(B_REG_SUCCESS);
97 			reply.AddMessenger("messenger", messenger);
98 			message->SendReply(&reply);
99 			break;
100 		}
101 		case B_REG_GET_CLIPBOARD_MESSENGER:
102 		{
103 			PRINT(("B_REG_GET_CLIPBOARD_MESSENGER\n"));
104 			BMessenger messenger(fClipboardHandler);
105 			BMessage reply(B_REG_SUCCESS);
106 			reply.AddMessenger("messenger", messenger);
107 			message->SendReply(&reply);
108 			break;
109 		}
110 		// roster requests
111 		case B_REG_ADD_APP:
112 			fRoster->HandleAddApplication(message);
113 			break;
114 		case B_REG_COMPLETE_REGISTRATION:
115 			fRoster->HandleCompleteRegistration(message);
116 			break;
117 		case B_REG_IS_APP_PRE_REGISTERED:
118 			fRoster->HandleIsAppPreRegistered(message);
119 			break;
120 		case B_REG_REMOVE_PRE_REGISTERED_APP:
121 			fRoster->HandleRemovePreRegApp(message);
122 			break;
123 		case B_REG_REMOVE_APP:
124 			fRoster->HandleRemoveApp(message);
125 			break;
126 		case B_REG_SET_THREAD_AND_TEAM:
127 			fRoster->HandleSetThreadAndTeam(message);
128 			break;
129 		case B_REG_SET_SIGNATURE:
130 			fRoster->HandleSetSignature(message);
131 			break;
132 		case B_REG_GET_APP_INFO:
133 			fRoster->HandleGetAppInfo(message);
134 			break;
135 		case B_REG_GET_APP_LIST:
136 			fRoster->HandleGetAppList(message);
137 			break;
138 		case B_REG_ACTIVATE_APP:
139 			fRoster->HandleActivateApp(message);
140 			break;
141 		case B_REG_BROADCAST:
142 			fRoster->HandleBroadcast(message);
143 			break;
144 		case B_REG_START_WATCHING:
145 			fRoster->HandleStartWatching(message);
146 			break;
147 		case B_REG_STOP_WATCHING:
148 			fRoster->HandleStopWatching(message);
149 			break;
150 		case B_REG_GET_RECENT_DOCUMENTS:
151 			fRoster->HandleGetRecentDocuments(message);
152 			break;
153 		case B_REG_GET_RECENT_FOLDERS:
154 			fRoster->HandleGetRecentFolders(message);
155 			break;
156 		case B_REG_GET_RECENT_APPS:
157 			fRoster->HandleGetRecentApps(message);
158 			break;
159 		case B_REG_ADD_TO_RECENT_DOCUMENTS:
160 			fRoster->HandleAddToRecentDocuments(message);
161 			break;
162 		case B_REG_ADD_TO_RECENT_FOLDERS:
163 			fRoster->HandleAddToRecentFolders(message);
164 			break;
165 		case B_REG_ADD_TO_RECENT_APPS:
166 			fRoster->HandleAddToRecentApps(message);
167 			break;
168 		case B_REG_CLEAR_RECENT_DOCUMENTS:
169 			fRoster->ClearRecentDocuments();
170 			break;
171 		case B_REG_CLEAR_RECENT_FOLDERS:
172 			fRoster->ClearRecentFolders();
173 			break;
174 		case B_REG_CLEAR_RECENT_APPS:
175 			fRoster->ClearRecentApps();
176 			break;
177 		case B_REG_LOAD_RECENT_LISTS:
178 			fRoster->HandleLoadRecentLists(message);
179 			break;
180 		case B_REG_SAVE_RECENT_LISTS:
181 			fRoster->HandleSaveRecentLists(message);
182 			break;
183 		// message runner requests
184 		case B_REG_REGISTER_MESSAGE_RUNNER:
185 			fMessageRunnerManager->HandleRegisterRunner(message);
186 			break;
187 		case B_REG_UNREGISTER_MESSAGE_RUNNER:
188 			fMessageRunnerManager->HandleUnregisterRunner(message);
189 			break;
190 		case B_REG_SET_MESSAGE_RUNNER_PARAMS:
191 			fMessageRunnerManager->HandleSetRunnerParams(message);
192 			break;
193 		case B_REG_GET_MESSAGE_RUNNER_INFO:
194 			fMessageRunnerManager->HandleGetRunnerInfo(message);
195 			break;
196 		// internal messages
197 		case B_REG_ROSTER_SANITY_EVENT:
198 			fRoster->CheckSanity();
199 			fSanityEvent->SetTime(system_time() + kRosterSanityEventInterval);
200 			fEventQueue->AddEvent(fSanityEvent);
201 			break;
202 		default:
203 			BApplication::MessageReceived(message);
204 			break;
205 	}
206 //	FUNCTION_END();
207 }
208 
209 // ReadyToRun
210 /*!	\brief Overrides the super class version to initialize the registrar
211 		   services.
212 */
213 void
214 Registrar::ReadyToRun()
215 {
216 	FUNCTION_START();
217 
218 	// create message deliverer
219 	status_t error = MessageDeliverer::CreateDefault();
220 	if (error != B_OK) {
221 		FATAL(("Registrar::ReadyToRun(): Failed to create the message "
222 			"deliverer: %s\n", strerror(error)));
223 	}
224 
225 	// create event queue
226 	fEventQueue = new EventQueue(kEventQueueName);
227 
228 	// create roster
229 	fRoster = new TRoster;
230 	fRoster->Init();
231 
232 	// create clipboard handler
233 	fClipboardHandler = new ClipboardHandler;
234 	AddHandler(fClipboardHandler);
235 
236 	// create MIME manager
237 	fMIMEManager = new MIMEManager;
238 	fMIMEManager->Run();
239 
240 	// create message runner manager
241 	fMessageRunnerManager = new MessageRunnerManager(fEventQueue);
242 
243 	// init the global be_roster
244 	BRoster::Private().SetTo(be_app_messenger, BMessenger(NULL, fMIMEManager));
245 
246 	// create the messaging service
247 	error = MessagingService::CreateDefault();
248 	if (error != B_OK) {
249 		ERROR(("Registrar::ReadyToRun(): Failed to init messaging service "
250 			"(that's by design when running under R5): %s\n", strerror(error)));
251 	}
252 
253 	// create and schedule the sanity message event
254 	fSanityEvent = new MessageEvent(system_time() + kRosterSanityEventInterval,
255 									this, B_REG_ROSTER_SANITY_EVENT);
256 	fSanityEvent->SetAutoDelete(false);
257 	fEventQueue->AddEvent(fSanityEvent);
258 
259 	FUNCTION_END();
260 }
261 
262 // QuitRequested
263 /*!	\brief Overrides the super class version to avoid termination of the
264 		   registrar until the system shutdown.
265 */
266 bool
267 Registrar::QuitRequested()
268 {
269 	FUNCTION_START();
270 	// The final registrar must not quit. At least not that easily. ;-)
271 	return BApplication::QuitRequested();
272 }
273 
274 // GetEventQueue
275 /*!	\brief Returns the registrar's event queue.
276 	\return The registrar's event queue.
277 */
278 EventQueue*
279 Registrar::GetEventQueue() const
280 {
281 	return fEventQueue;
282 }
283 
284 // App
285 /*!	\brief Returns the Registrar application object.
286 	\return The Registrar application object.
287 */
288 Registrar*
289 Registrar::App()
290 {
291 	return dynamic_cast<Registrar*>(be_app);
292 }
293 
294 
295 // main
296 /*!	\brief Creates and runs the registrar application.
297 
298 	The main thread is renamed.
299 
300 	\return 0.
301 */
302 int
303 main()
304 {
305 	FUNCTION_START();
306 
307 	// create and run the registrar application
308 	status_t error;
309 	Registrar *app = new Registrar(&error);
310 	if (error != B_OK) {
311 		fprintf(stderr, "Failed to create the BApplication: %s\n",
312 			strerror(error));
313 		return 1;
314 	}
315 
316 	// rename the main thread
317 	rename_thread(find_thread(NULL), kRosterThreadName);
318 
319 PRINT(("app->Run()...\n"));
320 	app->Run();
321 
322 PRINT(("delete app...\n"));
323 	delete app;
324 
325 	FUNCTION_END();
326 	return 0;
327 }
328 
329