1 // ParameterWindowManager.cpp 2 3 #include "ParameterWindowManager.h" 4 #include "ParameterWindow.h" 5 // NodeManager 6 #include "NodeRef.h" 7 8 // Application Kit 9 #include <AppDefs.h> 10 // Media Kit 11 #include <MediaRoster.h> 12 // Support Kit 13 #include <List.h> 14 15 __USE_CORTEX_NAMESPACE 16 17 #include <Debug.h> 18 #define D_ACCESS(x) //PRINT (x) 19 #define D_ALLOC(x) //PRINT (x) 20 #define D_INTERNAL(x) //PRINT (x) 21 #define D_MESSAGE(x) //PRINT (x) 22 #define D_WINDOW(x) //PRINT (x) 23 24 // -------------------------------------------------------- // 25 // internal types 26 // -------------------------------------------------------- // 27 28 // used to remember the list of ParameterWindows 29 struct window_map_entry { 30 31 public: // *** ctor/dtor 32 33 window_map_entry( 34 const NodeRef *ref, 35 BWindow *window) 36 : ref(ref), 37 window(window) 38 { } 39 40 public: // *** data members 41 42 const NodeRef *ref; 43 44 BWindow *window; 45 }; 46 47 // used to remember the list of ControlPanels 48 struct panel_map_entry { 49 50 public: // *** ctor/dtor 51 52 panel_map_entry( 53 int32 id, 54 const BMessenger &messenger) 55 : id(id), 56 messenger(messenger) 57 { } 58 59 public: // *** data members 60 61 int32 id; 62 63 const BMessenger messenger; 64 }; 65 66 // -------------------------------------------------------- // 67 // static member init 68 // -------------------------------------------------------- // 69 70 const BPoint ParameterWindowManager::M_DEFAULT_OFFSET = BPoint(20.0, 20.0); 71 const BPoint ParameterWindowManager::M_INIT_POSITION = BPoint(90.0, 90.0); 72 73 ParameterWindowManager *ParameterWindowManager::s_instance = 0; 74 75 // -------------------------------------------------------- // 76 // *** ctor/dtor 77 // -------------------------------------------------------- // 78 79 /* hidden */ 80 ParameterWindowManager::ParameterWindowManager() 81 : BLooper("ParameterWindowManager", 82 B_NORMAL_PRIORITY), 83 m_windowList(0), 84 m_panelList(0), 85 m_lastWindowPosition(M_INIT_POSITION - M_DEFAULT_OFFSET) { 86 D_ALLOC(("ParameterWindowManager::ParameterWindowManager()\n")); 87 88 m_windowList = new BList(); 89 m_panelList = new BList(); 90 Run(); 91 } 92 93 ParameterWindowManager::~ParameterWindowManager() { 94 D_ALLOC(("ParameterWindowManager::~ParameterWindowManager()\n")); 95 96 while (m_windowList->CountItems() > 0) { 97 window_map_entry *entry = static_cast<window_map_entry *> 98 (m_windowList->ItemAt(0)); 99 if (entry && entry->window) { 100 remove_observer(this, entry->ref); 101 entry->window->Lock(); 102 entry->window->Quit(); 103 } 104 m_windowList->RemoveItem(reinterpret_cast<void *>(entry)); 105 delete entry; 106 } 107 delete m_windowList; 108 109 while (m_panelList->CountItems() > 0) { 110 panel_map_entry *entry = static_cast<panel_map_entry *> 111 (m_panelList->ItemAt(0)); 112 if (entry && entry->messenger.IsValid()) { 113 entry->messenger.SendMessage(B_QUIT_REQUESTED); 114 } 115 m_panelList->RemoveItem(reinterpret_cast<void *>(entry)); 116 delete entry; 117 } 118 delete m_panelList; 119 120 s_instance = 0; 121 } 122 123 // -------------------------------------------------------- // 124 // *** singleton access 125 // -------------------------------------------------------- // 126 127 /*static*/ 128 ParameterWindowManager *ParameterWindowManager::Instance() { 129 D_ACCESS(("ParameterWindowManager::Instance()\n")); 130 131 if (!s_instance) { 132 D_ACCESS((" -> create instance\n")); 133 s_instance = new ParameterWindowManager(); 134 } 135 136 return s_instance; 137 } 138 139 /* static */ 140 void ParameterWindowManager::shutDown() { 141 D_WINDOW(("ParameterWindowManager::shutDown()\n")); 142 143 if (s_instance) { 144 s_instance->Lock(); 145 s_instance->Quit(); 146 } 147 } 148 149 // -------------------------------------------------------- // 150 // *** operations 151 // -------------------------------------------------------- // 152 153 status_t ParameterWindowManager::openWindowFor( 154 const NodeRef *ref) { 155 D_WINDOW(("ParameterWindowManager::openWindowFor()\n")); 156 157 // make absolutely sure we're locked 158 if (!IsLocked()) { 159 debugger("The looper must be locked !"); 160 } 161 162 // make sure the ref is valid 163 if (!ref) { 164 return B_ERROR; 165 } 166 167 BWindow *window = 0; 168 if (_findWindowFor(ref->id(), &window)) { 169 // window for this node already exists, activate it 170 window->SetWorkspaces(B_CURRENT_WORKSPACE); 171 window->Activate(); 172 return B_OK; 173 } 174 175 BMessenger messenger(0, this); 176 live_node_info nodeInfo = ref->nodeInfo(); 177 m_lastWindowPosition += M_DEFAULT_OFFSET; 178 window = new ParameterWindow(m_lastWindowPosition, 179 nodeInfo, &messenger); 180 if (_addWindowFor(ref, window)) { 181 window->Show(); 182 return B_OK; 183 } 184 delete window; 185 186 return B_ERROR; 187 } 188 189 status_t ParameterWindowManager::startControlPanelFor( 190 const NodeRef *ref) { 191 D_WINDOW(("ParameterWindowManager::startControlPanelFor()\n")); 192 193 // make absolutely sure we're locked 194 if (!IsLocked()) { 195 debugger("The looper must be locked !"); 196 } 197 198 BMediaRoster *roster = BMediaRoster::CurrentRoster(); 199 if (!roster) { 200 D_WINDOW((" -> MediaRoster not available\n")); 201 return B_ERROR; 202 } 203 204 BMessenger messenger; 205 if (_findPanelFor(ref->id(), &messenger)) { 206 // find out if the messengers target still exists 207 if (messenger.IsValid()) { 208 return B_OK; 209 } 210 else { 211 _removePanelFor(ref->id()); 212 } 213 } 214 215 status_t error = roster->StartControlPanel(ref->node(), 216 &messenger); 217 if (error) { 218 D_INTERNAL((" -> StartControlPanel() failed (%s)\n", 219 strerror(error))); 220 return error; 221 } 222 223 _addPanelFor(ref->id(), messenger); 224 return B_OK; 225 } 226 227 // -------------------------------------------------------- // 228 // *** BLooper impl 229 // -------------------------------------------------------- // 230 231 void ParameterWindowManager::MessageReceived( 232 BMessage *message) { 233 D_MESSAGE(("ParameterWindowManager::MessageReceived()\n")); 234 235 switch (message->what) { 236 case ParameterWindow::M_CLOSED: { 237 D_MESSAGE((" -> ParameterWindow::M_CLOSED\n")); 238 int32 nodeID; 239 if (message->FindInt32("nodeID", &nodeID) != B_OK) { 240 return; 241 } 242 _removeWindowFor(nodeID); 243 break; 244 } 245 case ParameterWindow::M_CONTROL_PANEL_STARTED: { 246 D_MESSAGE((" -> ParameterWindow::M_CONTROL_PANEL_STARTED\n")); 247 int32 nodeID; 248 if (message->FindInt32("nodeID", &nodeID) != B_OK) { 249 return; 250 } 251 BMessenger messenger; 252 if (message->FindMessenger("messenger", &messenger) != B_OK) { 253 return; 254 } 255 _addPanelFor(nodeID, messenger); 256 break; 257 } 258 case NodeRef::M_RELEASED: { 259 D_MESSAGE((" -> NodeRef::M_RELEASED\n")); 260 int32 nodeID; 261 if (message->FindInt32("nodeID", &nodeID) != B_OK) { 262 return; 263 } 264 BWindow *window; 265 if (_findWindowFor(nodeID, &window)) { 266 window->Lock(); 267 window->Quit(); 268 _removeWindowFor(nodeID); 269 } 270 break; 271 } 272 default: { 273 BLooper::MessageReceived(message); 274 } 275 } 276 } 277 278 // -------------------------------------------------------- // 279 // *** internal operations 280 // -------------------------------------------------------- // 281 282 bool ParameterWindowManager::_addWindowFor( 283 const NodeRef *ref, 284 BWindow *window) { 285 D_INTERNAL(("ParameterWindowManager::_addWindowFor()\n")); 286 287 window_map_entry *entry = new window_map_entry(ref, 288 window); 289 if (m_windowList->AddItem(reinterpret_cast<void *>(entry))) { 290 add_observer(this, entry->ref); 291 return true; 292 } 293 294 return false; 295 } 296 297 bool ParameterWindowManager::_findWindowFor( 298 int32 id, 299 BWindow **outWindow) { 300 D_INTERNAL(("ParameterWindowManager::_findWindowFor()\n")); 301 302 for (int32 i = 0; i < m_windowList->CountItems(); i++) { 303 window_map_entry *entry = static_cast<window_map_entry *> 304 (m_windowList->ItemAt(i)); 305 if (entry->ref->id() == id) { 306 *outWindow = entry->window; 307 return true; 308 } 309 } 310 311 return false; 312 } 313 314 void ParameterWindowManager::_removeWindowFor( 315 int32 id) { 316 D_INTERNAL(("ParameterWindowManager::_removeWindowFor()\n")); 317 318 for (int32 i = 0; i < m_windowList->CountItems(); i++) { 319 window_map_entry *entry = static_cast<window_map_entry *> 320 (m_windowList->ItemAt(i)); 321 if (entry->ref->id() == id) { 322 m_windowList->RemoveItem(reinterpret_cast<void *>(entry)); 323 remove_observer(this, entry->ref); 324 delete entry; 325 } 326 } 327 328 // try to shutdown 329 if (m_windowList->CountItems() == 0) { 330 int32 i = 0; 331 while (true) { 332 // take all invalid messengers out of the panel list 333 panel_map_entry *entry = static_cast<panel_map_entry *> 334 (m_panelList->ItemAt(i)); 335 if (!entry) { 336 // end of list 337 break; 338 } 339 if (!entry->messenger.IsValid()) { 340 // this control panel doesn't exist anymore 341 m_panelList->RemoveItem(entry); 342 continue; 343 } 344 } 345 if (m_panelList->CountItems() == 0) { 346 // neither windows nor panels to manage, go to sleep 347 PostMessage(B_QUIT_REQUESTED); 348 } 349 } 350 } 351 352 bool ParameterWindowManager::_addPanelFor( 353 int32 id, 354 const BMessenger &messenger) { 355 D_INTERNAL(("ParameterWindowManager::_addPanelFor()\n")); 356 357 panel_map_entry *entry = new panel_map_entry(id, 358 messenger); 359 if (m_panelList->AddItem(reinterpret_cast<void *>(entry))) { 360 return true; 361 } 362 363 return false; 364 } 365 366 bool ParameterWindowManager::_findPanelFor( 367 int32 id, 368 BMessenger *outMessenger) { 369 D_INTERNAL(("ParameterWindowManager::_findPanelFor()\n")); 370 371 for (int32 i = 0; i < m_panelList->CountItems(); i++) { 372 panel_map_entry *entry = static_cast<panel_map_entry *> 373 (m_panelList->ItemAt(i)); 374 if (entry->id == id) { 375 *outMessenger = entry->messenger; 376 return true; 377 } 378 } 379 380 return false; 381 } 382 383 void ParameterWindowManager::_removePanelFor( 384 int32 id) { 385 D_INTERNAL(("ParameterWindowManager::_removeWindowFor()\n")); 386 387 for (int32 i = 0; i < m_panelList->CountItems(); i++) { 388 panel_map_entry *entry = static_cast<panel_map_entry *> 389 (m_panelList->ItemAt(i)); 390 if (entry->id == id) { 391 m_panelList->RemoveItem(reinterpret_cast<void *>(entry)); 392 delete entry; 393 } 394 } 395 } 396 397 // END -- ParameterWindowManager.cpp -- 398