xref: /haiku/src/apps/cortex/InfoView/InfoWindowManager.cpp (revision 19ae20e67e91fc09cc9fc5c0e60e21e24e7a53eb)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // InfoWindowManager.cpp
33 
34 #include "InfoWindowManager.h"
35 // InfoWindow
36 #include "AppNodeInfoView.h"
37 #include "ConnectionInfoView.h"
38 #include "DormantNodeInfoView.h"
39 #include "EndPointInfoView.h"
40 #include "FileNodeInfoView.h"
41 #include "LiveNodeInfoView.h"
42 #include "InfoWindow.h"
43 // NodeManager
44 #include "AddOnHostProtocol.h"
45 #include "Connection.h"
46 #include "NodeRef.h"
47 
48 // Application Kit
49 #include <Application.h>
50 #include <AppDefs.h>
51 #include <Roster.h>
52 // Media Kit
53 #include <MediaAddOn.h>
54 #include <MediaRoster.h>
55 // Support Kit
56 #include <List.h>
57 
58 __USE_CORTEX_NAMESPACE
59 
60 #include <Debug.h>
61 #define D_ACCESS(x) //PRINT (x)
62 #define D_ALLOC(x) //PRINT (x)
63 #define D_INTERNAL(x) //PRINT (x)
64 #define D_MESSAGE(x) //PRINT (x)
65 #define D_WINDOW(x) //PRINT (x)
66 
67 // -------------------------------------------------------- //
68 // internal types
69 // -------------------------------------------------------- //
70 
71 // used to remember window for live nodes
72 struct live_node_window {
73 
74 public:						// *** ctor/dtor
75 
live_node_windowlive_node_window76 							live_node_window(
77 								const NodeRef *ref,
78 								BWindow *window)
79 								: ref(ref),
80 								  window(window)
81 							{ }
82 
83 public:						// *** data members
84 
85 	const NodeRef		   *ref;
86 
87 	BWindow				   *window;
88 };
89 
90 // used to remember windows for dormant nodes
91 struct dormant_node_window {
92 
93 public:						// *** ctor/dtor
94 
dormant_node_windowdormant_node_window95 							dormant_node_window(
96 								const dormant_node_info &info,
97 								BWindow *window)
98 								: info(info),
99 								  window(window)
100 							{ }
101 
102 public:						// *** data members
103 
104 	const dormant_node_info	info;
105 
106 	BWindow				   *window;
107 };
108 
109 // used to remember windows for connections
110 struct connection_window {
111 
112 public:						// *** ctor/dtor
113 
connection_windowconnection_window114 							connection_window(
115 								const media_source &source,
116 								const media_destination &destination,
117 								BWindow *window)
118 								: source(source),
119 								  destination(destination),
120 								  window(window)
121 							{ }
122 
123 public:						// *** data members
124 
125 	media_source			source;
126 
127 	media_destination		destination;
128 
129 	BWindow				   *window;
130 };
131 
132 // used to remember windows for media_inputs
133 struct input_window {
134 
135 public:						// *** ctor/dtor
136 
input_windowinput_window137 							input_window(
138 								const media_destination &destination,
139 								BWindow *window)
140 								: destination(destination),
141 								  window(window)
142 							{ }
143 
144 public:						// *** data members
145 
146 	media_destination		destination;
147 
148 	BWindow				   *window;
149 };
150 
151 // used to remember windows for media_outputs
152 struct output_window {
153 
154 public:						// *** ctor/dtor
155 
output_windowoutput_window156 							output_window(
157 								const media_source &source,
158 								BWindow *window)
159 								: source(source),
160 								  window(window)
161 							{ }
162 
163 public:						// *** data members
164 
165 	media_source			source;
166 
167 	BWindow				   *window;
168 };
169 
170 // -------------------------------------------------------- //
171 // static member init
172 // -------------------------------------------------------- //
173 
174 const BPoint InfoWindowManager::M_DEFAULT_OFFSET	= BPoint(20.0, 20.0);
175 const BPoint InfoWindowManager::M_INIT_POSITION	= BPoint(90.0, 90.0);
176 
177 InfoWindowManager *InfoWindowManager::s_instance = 0;
178 
179 // -------------------------------------------------------- //
180 // *** ctor/dtor
181 // -------------------------------------------------------- //
182 
183 /* hidden */
InfoWindowManager()184 InfoWindowManager::InfoWindowManager()
185 	: BLooper("InfoWindowManager",
186 			  B_NORMAL_PRIORITY),
187 	  m_liveNodeWindows(0),
188 	  m_dormantNodeWindows(0),
189 	  m_connectionWindows(0),
190 	  m_inputWindows(0),
191 	  m_outputWindows(0),
192 	  m_nextWindowPosition(M_INIT_POSITION) {
193 	D_ALLOC(("InfoWindowManager::InfoWindowManager()\n"));
194 
195 	Run();
196 
197 	BMediaRoster *roster = BMediaRoster::CurrentRoster();
198 	if (roster) {
199 		roster->StartWatching(BMessenger(0, this),
200 							  B_MEDIA_CONNECTION_BROKEN);
201 	}
202 }
203 
~InfoWindowManager()204 InfoWindowManager::~InfoWindowManager() {
205 	D_ALLOC(("InfoWindowManager::~InfoWindowManager()\n"));
206 
207 	BMediaRoster *roster = BMediaRoster::CurrentRoster();
208 	if (roster) {
209 		roster->StopWatching(BMessenger(0, this),
210 							  B_MEDIA_CONNECTION_BROKEN);
211 	}
212 
213 	if (m_liveNodeWindows) {
214 		while (m_liveNodeWindows->CountItems() > 0) {
215 			live_node_window *entry = static_cast<live_node_window *>
216 									  (m_liveNodeWindows->ItemAt(0));
217 			if (entry && entry->window) {
218 				remove_observer(this, entry->ref);
219 				BMessenger messenger(0, entry->window);
220 				messenger.SendMessage(B_QUIT_REQUESTED);
221 			}
222 			m_liveNodeWindows->RemoveItem(reinterpret_cast<void *>(entry));
223 			delete entry;
224 		}
225 		delete m_liveNodeWindows;
226 		m_liveNodeWindows = 0;
227 	}
228 
229 	if (m_dormantNodeWindows) {
230 		while (m_dormantNodeWindows->CountItems() > 0) {
231 			dormant_node_window *entry = static_cast<dormant_node_window *>
232 										 (m_dormantNodeWindows->ItemAt(0));
233 			if (entry && entry->window) {
234 				BMessenger messenger(0, entry->window);
235 				messenger.SendMessage(B_QUIT_REQUESTED);
236 			}
237 			m_dormantNodeWindows->RemoveItem(reinterpret_cast<void *>(entry));
238 			delete entry;
239 		}
240 		delete m_dormantNodeWindows;
241 		m_dormantNodeWindows = 0;
242 	}
243 
244 	if (m_connectionWindows) {
245 		while (m_connectionWindows->CountItems() > 0) {
246 			connection_window *entry = static_cast<connection_window *>
247 									   (m_connectionWindows->ItemAt(0));
248 			if (entry && entry->window) {
249 				BMessenger messenger(0, entry->window);
250 				messenger.SendMessage(B_QUIT_REQUESTED);
251 			}
252 			m_connectionWindows->RemoveItem(reinterpret_cast<void *>(entry));
253 			delete entry;
254 		}
255 		delete m_connectionWindows;
256 		m_connectionWindows = 0;
257 	}
258 
259 	if (m_inputWindows) {
260 		while (m_inputWindows->CountItems() > 0) {
261 			input_window *entry = static_cast<input_window *>
262 								  (m_inputWindows->ItemAt(0));
263 			if (entry && entry->window) {
264 				BMessenger messenger(0, entry->window);
265 				messenger.SendMessage(B_QUIT_REQUESTED);
266 			}
267 			m_inputWindows->RemoveItem(reinterpret_cast<void *>(entry));
268 			delete entry;
269 		}
270 		delete m_inputWindows;
271 		m_inputWindows = 0;
272 	}
273 
274 	if (m_outputWindows) {
275 		while (m_outputWindows->CountItems() > 0) {
276 			output_window *entry = static_cast<output_window *>
277 								   (m_outputWindows->ItemAt(0));
278 			if (entry && entry->window) {
279 				BMessenger messenger(0, entry->window);
280 				messenger.SendMessage(B_QUIT_REQUESTED);
281 			}
282 			m_outputWindows->RemoveItem(reinterpret_cast<void *>(entry));
283 			delete entry;
284 		}
285 		delete m_outputWindows;
286 		m_outputWindows = 0;
287 	}
288 }
289 
290 // -------------------------------------------------------- //
291 // *** singleton access
292 // -------------------------------------------------------- //
293 
294 /*static*/
Instance()295 InfoWindowManager *InfoWindowManager::Instance() {
296 	D_ACCESS(("InfoWindowManager::Instance()\n"));
297 
298 	if (!s_instance) {
299 		D_ACCESS((" -> create instance\n"));
300 		s_instance = new InfoWindowManager();
301 	}
302 
303 	return s_instance;
304 }
305 
306 /* static */
shutDown()307 void InfoWindowManager::shutDown() {
308 	D_WINDOW(("InfoWindowManager::shutDown()\n"));
309 
310 	if (s_instance) {
311 		s_instance->Lock();
312 		s_instance->Quit();
313 		s_instance = 0;
314 	}
315 }
316 
317 // -------------------------------------------------------- //
318 // *** operations
319 // -------------------------------------------------------- //
320 
openWindowFor(const NodeRef * ref)321 status_t InfoWindowManager::openWindowFor(
322 	const NodeRef *ref) {
323 	D_WINDOW(("InfoWindowManager::openWindowFor(live_node)\n"));
324 
325 	// make absolutely sure we're locked
326 	if (!IsLocked()) {
327 		debugger("The looper must be locked !");
328 	}
329 
330 	// make sure the ref is valid
331 	if (!ref) {
332 		return B_ERROR;
333 	}
334 
335 	BWindow *window = 0;
336 	if (_findWindowFor(ref->id(), &window)) {
337 		// window for this node already exists, activate it
338 		window->SetWorkspaces(B_CURRENT_WORKSPACE);
339 		window->Activate();
340 		return B_OK;
341 	}
342 
343 	BRect frame = InfoView::M_DEFAULT_FRAME;
344 	frame.OffsetTo(m_nextWindowPosition);
345 	m_nextWindowPosition += M_DEFAULT_OFFSET;
346 	window = new InfoWindow(frame);
347 
348 	if (_addWindowFor(ref, window)) {
349 		// find the correct InfoView sub-class
350 		BMediaRoster *roster = BMediaRoster::CurrentRoster();
351 		dormant_node_info dormantNodeInfo;
352 		if (ref->kind() & B_FILE_INTERFACE)
353 		{
354 			window->AddChild(new FileNodeInfoView(ref));
355 		}
356 		else if (roster->GetDormantNodeFor(ref->node(), &dormantNodeInfo) != B_OK) {
357 			port_info portInfo;
358 			app_info appInfo;
359 			if ((get_port_info(ref->node().port, &portInfo) == B_OK)
360 			 && (be_roster->GetRunningAppInfo(portInfo.team, &appInfo) == B_OK)) {
361 				app_info thisAppInfo;
362 				if ((be_app->GetAppInfo(&thisAppInfo) != B_OK)
363 				 || ((strcmp(appInfo.signature, thisAppInfo.signature) != 0)
364 				 && (strcmp(appInfo.signature, addon_host::g_appSignature) != 0))) {
365 					window->AddChild(new AppNodeInfoView(ref));
366 				}
367 				else {
368 					window->AddChild(new LiveNodeInfoView(ref));
369 				}
370 			}
371 			else {
372 				window->AddChild(new LiveNodeInfoView(ref));
373 			}
374 		}
375 		else {
376 			window->AddChild(new LiveNodeInfoView(ref));
377 		}
378 		// display the window
379 		window->Show();
380 		return B_OK;
381 	}
382 
383 	// failed
384 	delete window;
385 	return B_ERROR;
386 }
387 
openWindowFor(const dormant_node_info & info)388 status_t InfoWindowManager::openWindowFor(
389 	const dormant_node_info &info) {
390 	D_WINDOW(("InfoWindowManager::openWindowFor(dormant_node)\n"));
391 
392 	// make absolutely sure we're locked
393 	if (!IsLocked()) {
394 		debugger("The looper must be locked !");
395 	}
396 
397 	BWindow *window = 0;
398 	if (_findWindowFor(info, &window)) {
399 		// window for this node already exists, activate it
400 		window->SetWorkspaces(B_CURRENT_WORKSPACE);
401 		window->Activate();
402 		return B_OK;
403 	}
404 
405 	BRect frame = InfoView::M_DEFAULT_FRAME;
406 	frame.OffsetTo(m_nextWindowPosition);
407 	m_nextWindowPosition += M_DEFAULT_OFFSET;
408 	window = new InfoWindow(frame);
409 
410 	if (_addWindowFor(info, window)) {
411 		window->AddChild(new DormantNodeInfoView(info));
412 		window->Show();
413 		return B_OK;
414 	}
415 
416 	// failed
417 	delete window;
418 	return B_ERROR;
419 }
420 
openWindowFor(const Connection & connection)421 status_t InfoWindowManager::openWindowFor(
422 	const Connection &connection) {
423 	D_WINDOW(("InfoWindowManager::openWindowFor(connection)\n"));
424 
425 	// make absolutely sure we're locked
426 	if (!IsLocked()) {
427 		debugger("The looper must be locked !");
428 	}
429 
430 	BWindow *window = 0;
431 	if (_findWindowFor(connection.source(), connection.destination(), &window)) {
432 		// window for this node already exists, activate it
433 		window->SetWorkspaces(B_CURRENT_WORKSPACE);
434 		window->Activate();
435 		return B_OK;
436 	}
437 
438 	BRect frame = InfoView::M_DEFAULT_FRAME;
439 	frame.OffsetTo(m_nextWindowPosition);
440 	m_nextWindowPosition += M_DEFAULT_OFFSET;
441 	window = new InfoWindow(frame);
442 
443 	if (_addWindowFor(connection, window)) {
444 		window->AddChild(new ConnectionInfoView(connection));
445 		window->Show();
446 		return B_OK;
447 	}
448 
449 	// failed
450 	delete window;
451 	return B_ERROR;
452 }
453 
openWindowFor(const media_input & input)454 status_t InfoWindowManager::openWindowFor(
455 	const media_input &input) {
456 	D_WINDOW(("InfoWindowManager::openWindowFor(input)\n"));
457 
458 	// make absolutely sure we're locked
459 	if (!IsLocked()) {
460 		debugger("The looper must be locked !");
461 	}
462 
463 	BWindow *window = 0;
464 	if (_findWindowFor(input.destination, &window)) {
465 		// window for this node already exists, activate it
466 		window->SetWorkspaces(B_CURRENT_WORKSPACE);
467 		window->Activate();
468 		return B_OK;
469 	}
470 
471 	BRect frame = InfoView::M_DEFAULT_FRAME;
472 	frame.OffsetTo(m_nextWindowPosition);
473 	m_nextWindowPosition += M_DEFAULT_OFFSET;
474 	window = new InfoWindow(frame);
475 
476 	if (_addWindowFor(input, window)) {
477 		window->AddChild(new EndPointInfoView(input));
478 		window->Show();
479 		return B_OK;
480 	}
481 
482 	// failed
483 	delete window;
484 	return B_ERROR;
485 }
486 
openWindowFor(const media_output & output)487 status_t InfoWindowManager::openWindowFor(
488 	const media_output &output) {
489 	D_WINDOW(("InfoWindowManager::openWindowFor(output)\n"));
490 
491 	// make absolutely sure we're locked
492 	if (!IsLocked()) {
493 		debugger("The looper must be locked !");
494 	}
495 
496 	BWindow *window = 0;
497 	if (_findWindowFor(output.source, &window)) {
498 		// window for this node already exists, activate it
499 		window->SetWorkspaces(B_CURRENT_WORKSPACE);
500 		window->Activate();
501 		return B_OK;
502 	}
503 
504 	BRect frame = InfoView::M_DEFAULT_FRAME;
505 	frame.OffsetTo(m_nextWindowPosition);
506 	m_nextWindowPosition += M_DEFAULT_OFFSET;
507 	window = new BWindow(frame, "", B_DOCUMENT_WINDOW, 0);
508 
509 	if (_addWindowFor(output, window)) {
510 		window->AddChild(new EndPointInfoView(output));
511 		window->Show();
512 		return B_OK;
513 	}
514 
515 	// failed
516 	delete window;
517 	return B_ERROR;
518 }
519 
520 // -------------------------------------------------------- //
521 // *** BLooper impl
522 // -------------------------------------------------------- //
523 
MessageReceived(BMessage * message)524 void InfoWindowManager::MessageReceived(
525 	BMessage *message) {
526 	D_MESSAGE(("InfoWindowManager::MessageReceived()\n"));
527 
528 	switch (message->what) {
529 		case M_LIVE_NODE_WINDOW_CLOSED: {
530 			D_MESSAGE((" -> M_LIVE_NODE_WINDOW_CLOSED\n"));
531 			int32 nodeID;
532 			if (message->FindInt32("nodeID", &nodeID) != B_OK) {
533 				return;
534 			}
535 			_removeWindowFor(nodeID);
536 			break;
537 		}
538 		case M_DORMANT_NODE_WINDOW_CLOSED: {
539 			D_MESSAGE((" -> M_DORMANT_NODE_WINDOW_CLOSED\n"));
540 			dormant_node_info info;
541 			if (message->FindInt32("addOnID", &info.addon) != B_OK) {
542 				return;
543 			}
544 			if (message->FindInt32("flavorID", &info.flavor_id) != B_OK) {
545 				return;
546 			}
547 			_removeWindowFor(info);
548 			break;
549 		}
550 		case M_CONNECTION_WINDOW_CLOSED: {
551 			D_MESSAGE((" -> M_CONNECTION_WINDOW_CLOSED\n"));
552 			media_source source;
553 			if (message->FindInt32("source_port", &source.port) != B_OK) {
554 				return;
555 			}
556 			if (message->FindInt32("source_id", &source.id) != B_OK) {
557 				return;
558 			}
559 			media_destination destination;
560 			if (message->FindInt32("destination_port", &destination.port) != B_OK) {
561 				return;
562 			}
563 			if (message->FindInt32("destination_id", &destination.id) != B_OK) {
564 				return;
565 			}
566 			_removeWindowFor(source, destination);
567 			break;
568 		}
569 		case M_INPUT_WINDOW_CLOSED: {
570 			D_MESSAGE((" -> M_INPUT_WINDOW_CLOSED\n"));
571 			media_destination destination;
572 			if (message->FindInt32("destination_port", &destination.port) != B_OK) {
573 				return;
574 			}
575 			if (message->FindInt32("destination_id", &destination.id) != B_OK) {
576 				return;
577 			}
578 			_removeWindowFor(destination);
579 			break;
580 		}
581 		case M_OUTPUT_WINDOW_CLOSED: {
582 			D_MESSAGE((" -> M_OUTPUT_WINDOW_CLOSED\n"));
583 			media_source source;
584 			if (message->FindInt32("source_port", &source.port) != B_OK) {
585 				return;
586 			}
587 			if (message->FindInt32("source_id", &source.id) != B_OK) {
588 				return;
589 			}
590 			_removeWindowFor(source);
591 			break;
592 		}
593 		case NodeRef::M_RELEASED: {
594 			D_MESSAGE((" -> NodeRef::M_RELEASED\n"));
595 			int32 nodeID;
596 			if (message->FindInt32("nodeID", &nodeID) != B_OK) {
597 				return;
598 			}
599 			BWindow *window;
600 			if (_findWindowFor(nodeID, &window)) {
601 				window->Lock();
602 				window->Quit();
603 				_removeWindowFor(nodeID);
604 			}
605 			break;
606 		}
607 		case B_MEDIA_CONNECTION_BROKEN: {
608 			D_MESSAGE((" -> B_MEDIA_CONNECTION_BROKEN\n"));
609 			const void *data;
610 			ssize_t dataSize;
611 			if (message->FindData("source", B_RAW_TYPE, &data, &dataSize) != B_OK) {
612 				return;
613 			}
614 			const media_source source = *reinterpret_cast<const media_source *>(data);
615 			if (message->FindData("destination", B_RAW_TYPE, &data, &dataSize) != B_OK) {
616 				return;
617 			}
618 			const media_destination destination = *reinterpret_cast<const media_destination *>(data);
619 			BWindow *window;
620 			if (_findWindowFor(source, destination, &window)) {
621 				window->Lock();
622 				window->Quit();
623 				_removeWindowFor(source, destination);
624 			}
625 			break;
626 		}
627 		default: {
628 			BLooper::MessageReceived(message);
629 		}
630 	}
631 }
632 
633 // -------------------------------------------------------- //
634 // *** internal operations
635 // -------------------------------------------------------- //
636 
_addWindowFor(const NodeRef * ref,BWindow * window)637 bool InfoWindowManager::_addWindowFor(
638 	const NodeRef *ref,
639 	BWindow *window) {
640 	D_INTERNAL(("InfoWindowManager::_addWindowFor(live_node)\n"));
641 
642 	if (!m_liveNodeWindows) {
643 		m_liveNodeWindows = new BList();
644 	}
645 
646 	live_node_window *entry = new live_node_window(ref, window);
647 	if (m_liveNodeWindows->AddItem(reinterpret_cast<void *>(entry))) {
648 		add_observer(this, entry->ref);
649 		return true;
650 	}
651 
652 	return false;
653 }
654 
_findWindowFor(int32 nodeID,BWindow ** outWindow)655 bool InfoWindowManager::_findWindowFor(
656 	int32 nodeID,
657 	BWindow **outWindow) {
658 	D_INTERNAL(("InfoWindowManager::_findWindowFor(live_node)\n"));
659 
660 	if (!m_liveNodeWindows) {
661 		return false;
662 	}
663 
664 	for (int32 i = 0; i < m_liveNodeWindows->CountItems(); i++) {
665 		live_node_window *entry = static_cast<live_node_window *>
666 								  (m_liveNodeWindows->ItemAt(i));
667 		if (entry->ref->id() == nodeID) {
668 			*outWindow = entry->window;
669 			return true;
670 		}
671 	}
672 
673 	return false;
674 }
675 
_removeWindowFor(int32 nodeID)676 void InfoWindowManager::_removeWindowFor(
677 	int32 nodeID) {
678 	D_INTERNAL(("InfoWindowManager::_removeWindowFor(live_node)\n"));
679 
680 	if (!m_liveNodeWindows) {
681 		return;
682 	}
683 
684 	for (int32 i = 0; i < m_liveNodeWindows->CountItems(); i++) {
685 		live_node_window *entry = static_cast<live_node_window *>
686 								  (m_liveNodeWindows->ItemAt(i));
687 		if (entry->ref->id() == nodeID) {
688 			m_liveNodeWindows->RemoveItem(reinterpret_cast<void *>(entry));
689 			remove_observer(this, entry->ref);
690 			delete entry;
691 		}
692 	}
693 
694 	if (m_liveNodeWindows->CountItems() <= 0) {
695 		delete m_liveNodeWindows;
696 		m_liveNodeWindows = 0;
697 	}
698 }
699 
_addWindowFor(const dormant_node_info & info,BWindow * window)700 bool InfoWindowManager::_addWindowFor(
701 	const dormant_node_info &info,
702 	BWindow *window) {
703 	D_INTERNAL(("InfoWindowManager::_addWindowFor(dormant_node)\n"));
704 
705 	if (!m_dormantNodeWindows) {
706 		m_dormantNodeWindows = new BList();
707 	}
708 
709 	dormant_node_window *entry = new dormant_node_window(info, window);
710 	return m_dormantNodeWindows->AddItem(reinterpret_cast<void *>(entry));
711 }
712 
_findWindowFor(const dormant_node_info & info,BWindow ** outWindow)713 bool InfoWindowManager::_findWindowFor(
714 	const dormant_node_info &info,
715 	BWindow **outWindow) {
716 	D_INTERNAL(("InfoWindowManager::_findWindowFor(dormant_node)\n"));
717 
718 	if (!m_dormantNodeWindows) {
719 		return false;
720 	}
721 
722 	for (int32 i = 0; i < m_dormantNodeWindows->CountItems(); i++) {
723 		dormant_node_window *entry = static_cast<dormant_node_window *>
724 									 (m_dormantNodeWindows->ItemAt(i));
725 		if ((entry->info.addon == info.addon)
726 		 && (entry->info.flavor_id == info.flavor_id)) {
727 			*outWindow = entry->window;
728 			return true;
729 		}
730 	}
731 
732 	return false;
733 }
734 
_removeWindowFor(const dormant_node_info & info)735 void InfoWindowManager::_removeWindowFor(
736 	const dormant_node_info &info) {
737 	D_INTERNAL(("InfoWindowManager::_removeWindowFor(dormant_node)\n"));
738 
739 	if (!m_dormantNodeWindows) {
740 		return;
741 	}
742 
743 	for (int32 i = 0; i < m_dormantNodeWindows->CountItems(); i++) {
744 		dormant_node_window *entry = static_cast<dormant_node_window *>
745 									 (m_dormantNodeWindows->ItemAt(i));
746 		if ((entry->info.addon == info.addon)
747 		 && (entry->info.flavor_id == info.flavor_id)) {
748 			m_dormantNodeWindows->RemoveItem(reinterpret_cast<void *>(entry));
749 			delete entry;
750 		}
751 	}
752 
753 	if (m_dormantNodeWindows->CountItems() >= 0) {
754 		delete m_dormantNodeWindows;
755 		m_dormantNodeWindows = 0;
756 	}
757 }
758 
_addWindowFor(const Connection & connection,BWindow * window)759 bool InfoWindowManager::_addWindowFor(
760 	const Connection &connection,
761 	BWindow *window) {
762 	D_INTERNAL(("InfoWindowManager::_addWindowFor(connection)\n"));
763 
764 	if (!m_connectionWindows) {
765 		m_connectionWindows = new BList();
766 	}
767 
768 	connection_window *entry = new connection_window(connection.source(),
769 													 connection.destination(),
770 													 window);
771 	return m_connectionWindows->AddItem(reinterpret_cast<void *>(entry));
772 }
773 
_findWindowFor(const media_source & source,const media_destination & destination,BWindow ** outWindow)774 bool InfoWindowManager::_findWindowFor(
775 	const media_source &source,
776 	const media_destination &destination,
777 	BWindow **outWindow) {
778 	D_INTERNAL(("InfoWindowManager::_findWindowFor(connection)\n"));
779 
780 	if (!m_connectionWindows) {
781 		return false;
782 	}
783 
784 	for (int32 i = 0; i < m_connectionWindows->CountItems(); i++) {
785 		connection_window *entry = static_cast<connection_window *>
786 								   (m_connectionWindows->ItemAt(i));
787 		if ((entry->source == source)
788 		 && (entry->destination == destination)) {
789 			*outWindow = entry->window;
790 			return true;
791 		}
792 	}
793 
794 	return false;
795 }
796 
_removeWindowFor(const media_source & source,const media_destination & destination)797 void InfoWindowManager::_removeWindowFor(
798 	const media_source &source,
799 	const media_destination &destination) {
800 	D_INTERNAL(("InfoWindowManager::_removeWindowFor(connection)\n"));
801 
802 	if (!m_connectionWindows) {
803 		return;
804 	}
805 
806 	for (int32 i = 0; i < m_connectionWindows->CountItems(); i++) {
807 		connection_window *entry = static_cast<connection_window *>
808 								   (m_connectionWindows->ItemAt(i));
809 		if ((entry->source == source)
810 		 && (entry->destination == destination)) {
811 			m_connectionWindows->RemoveItem(reinterpret_cast<void *>(entry));
812 			delete entry;
813 		}
814 	}
815 
816 	if (m_connectionWindows->CountItems() >= 0) {
817 		delete m_connectionWindows;
818 		m_connectionWindows = 0;
819 	}
820 }
821 
_addWindowFor(const media_input & input,BWindow * window)822 bool InfoWindowManager::_addWindowFor(
823 	const media_input &input,
824 	BWindow *window) {
825 	D_INTERNAL(("InfoWindowManager::_addWindowFor(input)\n"));
826 
827 	if (!m_inputWindows) {
828 		m_inputWindows = new BList();
829 	}
830 
831 	input_window *entry = new input_window(input.destination, window);
832 	return m_inputWindows->AddItem(reinterpret_cast<void *>(entry));
833 }
834 
_findWindowFor(const media_destination & destination,BWindow ** outWindow)835 bool InfoWindowManager::_findWindowFor(
836 	const media_destination &destination,
837 	BWindow **outWindow) {
838 	D_INTERNAL(("InfoWindowManager::_findWindowFor(input)\n"));
839 
840 	if (!m_inputWindows) {
841 		return false;
842 	}
843 
844 	for (int32 i = 0; i < m_inputWindows->CountItems(); i++) {
845 		input_window *entry = static_cast<input_window *>
846 							  (m_inputWindows->ItemAt(i));
847 		if (entry->destination == destination) {
848 			*outWindow = entry->window;
849 			return true;
850 		}
851 	}
852 
853 	return false;
854 }
855 
_removeWindowFor(const media_destination & destination)856 void InfoWindowManager::_removeWindowFor(
857 	const media_destination &destination) {
858 	D_INTERNAL(("InfoWindowManager::_removeWindowFor(input)\n"));
859 
860 	if (!m_inputWindows) {
861 		return;
862 	}
863 
864 	for (int32 i = 0; i < m_inputWindows->CountItems(); i++) {
865 		input_window *entry = static_cast<input_window *>
866 							  (m_inputWindows->ItemAt(i));
867 		if (entry->destination == destination) {
868 			m_inputWindows->RemoveItem(reinterpret_cast<void *>(entry));
869 			delete entry;
870 		}
871 	}
872 
873 	if (m_inputWindows->CountItems() >= 0) {
874 		delete m_inputWindows;
875 		m_inputWindows = 0;
876 	}
877 }
878 
_addWindowFor(const media_output & output,BWindow * window)879 bool InfoWindowManager::_addWindowFor(
880 	const media_output &output,
881 	BWindow *window) {
882 	D_INTERNAL(("InfoWindowManager::_addWindowFor(output)\n"));
883 
884 	if (!m_outputWindows) {
885 		m_outputWindows = new BList();
886 	}
887 
888 	output_window *entry = new output_window(output.source, window);
889 	return m_outputWindows->AddItem(reinterpret_cast<void *>(entry));
890 }
891 
_findWindowFor(const media_source & source,BWindow ** outWindow)892 bool InfoWindowManager::_findWindowFor(
893 	const media_source &source,
894 	BWindow **outWindow) {
895 	D_INTERNAL(("InfoWindowManager::_findWindowFor(output)\n"));
896 
897 	if (!m_outputWindows) {
898 		return false;
899 	}
900 
901 	for (int32 i = 0; i < m_outputWindows->CountItems(); i++) {
902 		output_window *entry = static_cast<output_window *>
903 							  (m_outputWindows->ItemAt(i));
904 		if (entry->source == source) {
905 			*outWindow = entry->window;
906 			return true;
907 		}
908 	}
909 
910 	return false;
911 }
912 
_removeWindowFor(const media_source & source)913 void InfoWindowManager::_removeWindowFor(
914 	const media_source &source) {
915 	D_INTERNAL(("InfoWindowManager::_removeWindowFor(output)\n"));
916 
917 	if (!m_outputWindows) {
918 		return;
919 	}
920 
921 	for (int32 i = 0; i < m_outputWindows->CountItems(); i++) {
922 		output_window *entry = static_cast<output_window *>
923 							  (m_outputWindows->ItemAt(i));
924 		if (entry->source == source) {
925 			m_outputWindows->RemoveItem(reinterpret_cast<void *>(entry));
926 			delete entry;
927 		}
928 	}
929 
930 	if (m_outputWindows->CountItems() >= 0) {
931 		delete m_outputWindows;
932 		m_outputWindows = 0;
933 	}
934 }
935 
936 // END -- InfoWindowManager.cpp --
937