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