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