xref: /haiku/src/kits/media/MediaRoster.cpp (revision 964cab46153923dd43c77ab42438af8fd36f4846)
1255a01c7Sbeveloper /*
27bcdb362SDario Casalinuovo  * Copyright 2015 Dario Casalinuovo
3332cc6bcSAxel Dörfler  * Copyright 2009-2012, Axel Dörfler, axeld@pinc-software.de.
47bcdb362SDario Casalinuovo  * Copyright 2008 Maurice Kalinowski, haiku@kaldience.com
534c72144SAxel Dörfler  *
634c72144SAxel Dörfler  * All rights reserved. Distributed under the terms of the MIT License.
734c72144SAxel Dörfler  */
834c72144SAxel Dörfler 
934c72144SAxel Dörfler /*
1065b73ae4SMarcus Overhagen  * Copyright (c) 2002-2006 Marcus Overhagen <Marcus@Overhagen.de>
11255a01c7Sbeveloper  *
12255a01c7Sbeveloper  * Permission is hereby granted, free of charge, to any person obtaining
13255a01c7Sbeveloper  * a copy of this software and associated documentation files or portions
14255a01c7Sbeveloper  * thereof (the "Software"), to deal in the Software without restriction,
15255a01c7Sbeveloper  * including without limitation the rights to use, copy, modify, merge,
16255a01c7Sbeveloper  * publish, distribute, sublicense, and/or sell copies of the Software,
17255a01c7Sbeveloper  * and to permit persons to whom the Software is furnished to do so, subject
18255a01c7Sbeveloper  * to the following conditions:
19255a01c7Sbeveloper  *
20255a01c7Sbeveloper  *  * Redistributions of source code must retain the above copyright notice,
21255a01c7Sbeveloper  *    this list of conditions and the following disclaimer.
22255a01c7Sbeveloper  *
23255a01c7Sbeveloper  *  * Redistributions in binary form must reproduce the above copyright notice
24255a01c7Sbeveloper  *    in the  binary, as well as this list of conditions and the following
25255a01c7Sbeveloper  *    disclaimer in the documentation and/or other materials provided with
26255a01c7Sbeveloper  *    the distribution.
27255a01c7Sbeveloper  *
28255a01c7Sbeveloper  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
29255a01c7Sbeveloper  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30255a01c7Sbeveloper  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
31255a01c7Sbeveloper  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32255a01c7Sbeveloper  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33255a01c7Sbeveloper  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34255a01c7Sbeveloper  * THE SOFTWARE.
35255a01c7Sbeveloper  */
366938364bSMaurice Kalinowski 
37255a01c7Sbeveloper 
38255a01c7Sbeveloper /* to comply with the license above, do not remove the following line */
398b940bb4SStephan Aßmus char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
408b940bb4SStephan Aßmus 	"Overhagen <Marcus@Overhagen.de>";
41255a01c7Sbeveloper 
429dec2310SAxel Dörfler 
4352a38012Sejakowatz #include <MediaRoster.h>
448b940bb4SStephan Aßmus 
4505962bb1SDario Casalinuovo #include <Application.h>
46d15321ffSDario Casalinuovo #include <Autolock.h>
476938364bSMaurice Kalinowski #include <BufferConsumer.h>
486938364bSMaurice Kalinowski #include <BufferProducer.h>
4952a38012Sejakowatz #include <Locker.h>
5052a38012Sejakowatz #include <Message.h>
5152a38012Sejakowatz #include <Messenger.h>
526938364bSMaurice Kalinowski #include <MimeType.h>
5352a38012Sejakowatz #include <OS.h>
546938364bSMaurice Kalinowski #include <ParameterWeb.h>
5567483edaSDario Casalinuovo #include <Roster.h>
566938364bSMaurice Kalinowski #include <StopWatch.h>
5752a38012Sejakowatz #include <String.h>
5852a38012Sejakowatz #include <TimeSource.h>
598b940bb4SStephan Aßmus 
6005962bb1SDario Casalinuovo #include <new>
619dec2310SAxel Dörfler 
6205962bb1SDario Casalinuovo #include <AppMisc.h>
632f9ed888SAxel Dörfler #include <DataExchange.h>
64b84955d4SBarrett17 #include <MediaDebug.h>
652f9ed888SAxel Dörfler #include <DormantNodeManager.h>
662f9ed888SAxel Dörfler #include <MediaMisc.h>
6732afe10aSDario Casalinuovo #include <MediaRosterEx.h>
682f9ed888SAxel Dörfler #include <Notifications.h>
692f9ed888SAxel Dörfler #include <ServerInterface.h>
702f9ed888SAxel Dörfler #include <SharedBufferList.h>
7132afe10aSDario Casalinuovo #include <TList.h>
722f9ed888SAxel Dörfler 
73835140c8Sbeveloper #include "TimeSourceObjectManager.h"
7452a38012Sejakowatz 
752f9ed888SAxel Dörfler 
76f0a1eb2dSAxel Dörfler namespace BPrivate {
77f0a1eb2dSAxel Dörfler namespace media {
7852a38012Sejakowatz 
79f0a1eb2dSAxel Dörfler 
8032afe10aSDario Casalinuovo struct RosterNotification {
8132afe10aSDario Casalinuovo 	BMessenger	messenger;
8232afe10aSDario Casalinuovo 	int32		what;
8332afe10aSDario Casalinuovo };
8432afe10aSDario Casalinuovo 
8505962bb1SDario Casalinuovo 
8676889670SDario Casalinuovo struct SyncedMessage {
8776889670SDario Casalinuovo 	BMessage* message;
8876889670SDario Casalinuovo };
8976889670SDario Casalinuovo 
9076889670SDario Casalinuovo 
9167060664SDario Casalinuovo struct LocalNode {
9267060664SDario Casalinuovo 				LocalNode(BMediaNode* local_node)
9367060664SDario Casalinuovo 					:
9467060664SDario Casalinuovo 					node(local_node) {}
9567060664SDario Casalinuovo 
9667060664SDario Casalinuovo 				LocalNode()
9767060664SDario Casalinuovo 					:
9867060664SDario Casalinuovo 					node(NULL) {}
9967060664SDario Casalinuovo 
10067060664SDario Casalinuovo 	bool 		operator==(const LocalNode& a)
10167060664SDario Casalinuovo 				{
10267060664SDario Casalinuovo 					if (a.node == this->node)
10367060664SDario Casalinuovo 						return true;
10467060664SDario Casalinuovo 					return false;
10567060664SDario Casalinuovo 				}
10667060664SDario Casalinuovo 
10767060664SDario Casalinuovo 	BMediaNode* node;
10867060664SDario Casalinuovo };
10967060664SDario Casalinuovo 
11067060664SDario Casalinuovo 
11132afe10aSDario Casalinuovo static bool sServerIsUp = false;
11232afe10aSDario Casalinuovo static List<RosterNotification> sNotificationList;
113d15321ffSDario Casalinuovo static BLocker sInitLocker("BMediaRoster::Roster locker");
11467060664SDario Casalinuovo static List<LocalNode> sRegisteredNodes;
11532afe10aSDario Casalinuovo 
1167d337b23SDario Casalinuovo 
1177d337b23SDario Casalinuovo class MediaRosterUndertaker {
1187d337b23SDario Casalinuovo public:
1197d337b23SDario Casalinuovo 	~MediaRosterUndertaker()
1207d337b23SDario Casalinuovo 	{
1217d337b23SDario Casalinuovo 		BAutolock _(sInitLocker);
122ad7255c8SDario Casalinuovo 		if (BMediaRoster::CurrentRoster() != NULL) {
12305962bb1SDario Casalinuovo 
12467060664SDario Casalinuovo 			// Detect any forgotten node
12567060664SDario Casalinuovo 			if (sRegisteredNodes.CountItems() > 0) {
12667060664SDario Casalinuovo 				for (int32 i = 0; i < sRegisteredNodes.CountItems(); i++) {
12767060664SDario Casalinuovo 					LocalNode* node = NULL;
12867060664SDario Casalinuovo 					sRegisteredNodes.Get(i, &node);
12967060664SDario Casalinuovo 					if (node != NULL) {
13067060664SDario Casalinuovo 						ERROR("BMediaRoster: Node with ID %" B_PRId32
13167060664SDario Casalinuovo 							" was not released correctly\n", node->node->ID());
13267060664SDario Casalinuovo 					}
13367060664SDario Casalinuovo 				}
13467060664SDario Casalinuovo 			}
13567060664SDario Casalinuovo 
13605962bb1SDario Casalinuovo 			if (be_app != NULL)
13705962bb1SDario Casalinuovo 				be_app->UnregisterLooper(BMediaRoster::CurrentRoster());
13805962bb1SDario Casalinuovo 
139ad7255c8SDario Casalinuovo 			status_t err = B_ERROR;
140ad7255c8SDario Casalinuovo 			thread_id roster = BMediaRoster::CurrentRoster()->Thread();
141ad7255c8SDario Casalinuovo 
142ad7255c8SDario Casalinuovo 			BMediaRoster::CurrentRoster()->PostMessage(B_QUIT_REQUESTED);
143ad7255c8SDario Casalinuovo 
144ad7255c8SDario Casalinuovo 			wait_for_thread(roster, &err);
145ad7255c8SDario Casalinuovo 			if (err != B_OK)
146ad7255c8SDario Casalinuovo 				ERROR("BMediaRoster: wait_for_thread returned error");
1477d337b23SDario Casalinuovo 		}
1487d337b23SDario Casalinuovo 	}
1497d337b23SDario Casalinuovo };
1507d337b23SDario Casalinuovo 
1517d337b23SDario Casalinuovo 
1527d337b23SDario Casalinuovo static MediaRosterUndertaker sMediaRosterUndertaker;
1537d337b23SDario Casalinuovo 
1549dec2310SAxel Dörfler }	// namespace media
1559dec2310SAxel Dörfler }	// namespace BPrivate
1569dec2310SAxel Dörfler 
1578b04ffc1Sbeveloper using namespace BPrivate::media;
15852a38012Sejakowatz 
1599dec2310SAxel Dörfler 
16034c72144SAxel Dörfler BMediaRosterEx::BMediaRosterEx(status_t* _error)
1619dec2310SAxel Dörfler 	:
16276889670SDario Casalinuovo 	BMediaRoster(),
16376889670SDario Casalinuovo 	fLaunchNotification(false),
16476889670SDario Casalinuovo 	fAutoExit(false)
165dcfb6bfcSJérôme Duval {
1667d337b23SDario Casalinuovo 	gDormantNodeManager = new DormantNodeManager();
1677d337b23SDario Casalinuovo 	gTimeSourceObjectManager = new TimeSourceObjectManager();
168f0a1eb2dSAxel Dörfler 
16932afe10aSDario Casalinuovo 	*_error = BuildConnections();
17032afe10aSDario Casalinuovo 
17132afe10aSDario Casalinuovo 	InitRosterDataExchange(BMessenger(this, this));
17232afe10aSDario Casalinuovo 
17332afe10aSDario Casalinuovo 	if (be_roster->StartWatching(BMessenger(this, this),
174d009f286SDario Casalinuovo 			B_REQUEST_LAUNCHED | B_REQUEST_QUIT) != B_OK) {
17532afe10aSDario Casalinuovo 		*_error = B_ERROR;
176d009f286SDario Casalinuovo 	}
17732afe10aSDario Casalinuovo 	sServerIsUp = BMediaRoster::IsRunning();
17832afe10aSDario Casalinuovo }
17932afe10aSDario Casalinuovo 
18032afe10aSDario Casalinuovo 
1817d337b23SDario Casalinuovo void
1827d337b23SDario Casalinuovo BMediaRosterEx::Quit()
1837d337b23SDario Casalinuovo {
1847d337b23SDario Casalinuovo 	if (be_roster->StopWatching(BMessenger(this, this)) != B_OK)
1857d337b23SDario Casalinuovo 			TRACE("Can't unregister roster notifications");
1867d337b23SDario Casalinuovo 
1877d337b23SDario Casalinuovo 	if (sNotificationList.CountItems() != 0)
1887d337b23SDario Casalinuovo 		sNotificationList.MakeEmpty();
1897d337b23SDario Casalinuovo 
1907d337b23SDario Casalinuovo 	BMediaRoster::Quit();
1917d337b23SDario Casalinuovo }
1927d337b23SDario Casalinuovo 
1937d337b23SDario Casalinuovo 
19432afe10aSDario Casalinuovo status_t
19532afe10aSDario Casalinuovo BMediaRosterEx::BuildConnections()
19632afe10aSDario Casalinuovo {
19732afe10aSDario Casalinuovo 	InitServerDataExchange();
198dcfb6bfcSJérôme Duval 	// register this application with the media server
199dcfb6bfcSJérôme Duval 	server_register_app_request request;
200dcfb6bfcSJérôme Duval 	server_register_app_reply reply;
2019dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
202dcfb6bfcSJérôme Duval 	request.messenger = BMessenger(NULL, this);
2039dec2310SAxel Dörfler 	status_t status = QueryServer(SERVER_REGISTER_APP, &request,
2049dec2310SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2059dec2310SAxel Dörfler 	if (status != B_OK)
20632afe10aSDario Casalinuovo 		return B_MEDIA_SYSTEM_FAILURE;
20732afe10aSDario Casalinuovo 
20832afe10aSDario Casalinuovo 	return B_OK;
209dcfb6bfcSJérôme Duval }
210dcfb6bfcSJérôme Duval 
21134c72144SAxel Dörfler 
212e57acc3aSDario Casalinuovo BMediaRosterEx::~BMediaRosterEx()
213e57acc3aSDario Casalinuovo {
214e57acc3aSDario Casalinuovo 	CALLED();
215e57acc3aSDario Casalinuovo 
216e57acc3aSDario Casalinuovo 	delete gTimeSourceObjectManager;
217e57acc3aSDario Casalinuovo 	delete gDormantNodeManager;
218e57acc3aSDario Casalinuovo 
219e57acc3aSDario Casalinuovo 	// unregister this application with the media server
220e57acc3aSDario Casalinuovo 	server_unregister_app_request request;
221e57acc3aSDario Casalinuovo 	server_unregister_app_reply reply;
222e57acc3aSDario Casalinuovo 	request.team = BPrivate::current_team();
223e57acc3aSDario Casalinuovo 	QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply,
224e57acc3aSDario Casalinuovo 		sizeof(reply));
225e57acc3aSDario Casalinuovo 
226e57acc3aSDario Casalinuovo 	BPrivate::SharedBufferList::Invalidate();
227e57acc3aSDario Casalinuovo }
228e57acc3aSDario Casalinuovo 
229e57acc3aSDario Casalinuovo 
23067060664SDario Casalinuovo void
23167060664SDario Casalinuovo BMediaRosterEx::RegisterLocalNode(BMediaNode* node)
23267060664SDario Casalinuovo {
23367060664SDario Casalinuovo 	sRegisteredNodes.Insert(LocalNode(node));
23467060664SDario Casalinuovo }
23567060664SDario Casalinuovo 
23667060664SDario Casalinuovo 
23767060664SDario Casalinuovo void
23867060664SDario Casalinuovo BMediaRosterEx::UnregisterLocalNode(BMediaNode* node)
23967060664SDario Casalinuovo {
24067060664SDario Casalinuovo 	int32 index = sRegisteredNodes.Find(LocalNode(node));
24167060664SDario Casalinuovo 	if (index != -1)
24267060664SDario Casalinuovo 		sRegisteredNodes.Remove(index);
24367060664SDario Casalinuovo }
24467060664SDario Casalinuovo 
24567060664SDario Casalinuovo 
24676889670SDario Casalinuovo void
24776889670SDario Casalinuovo BMediaRosterEx::EnableLaunchNotification(bool enable, bool autoExit)
24876889670SDario Casalinuovo {
24976889670SDario Casalinuovo 	// NOTE: in theory, we should personalize it depending on each
25076889670SDario Casalinuovo 	// request, but we are using it just in launch/shutdown_media_server,
25176889670SDario Casalinuovo 	// so we are enough safe to don't care about that.
25276889670SDario Casalinuovo 	fLaunchNotification = enable;
25376889670SDario Casalinuovo 	fAutoExit = autoExit;
25476889670SDario Casalinuovo }
25576889670SDario Casalinuovo 
25676889670SDario Casalinuovo 
2573620737cSbeveloper status_t
25854187cc6Sbeveloper BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
25954187cc6Sbeveloper {
2609dec2310SAxel Dörfler 	int32 flavorID;
2619dec2310SAxel Dörfler 	BMediaAddOn* addon = node->AddOn(&flavorID);
2629dec2310SAxel Dörfler 	if (addon == NULL) {
2638056f0dbSStephan Aßmus 		// NOTE: This node could have been created by an application,
2648056f0dbSStephan Aßmus 		// it does not mean there is an error.
26534c72144SAxel Dörfler 		// TODO: this check incorrectly triggers on BeOS R5 BT848 node
266332cc6bcSAxel Dörfler 		TRACE("BMediaRosterEx::SaveNodeConfiguration node %" B_PRId32 " not "
267332cc6bcSAxel Dörfler 			"instantiated from BMediaAddOn!\n", node->ID());
26854187cc6Sbeveloper 		return B_ERROR;
26954187cc6Sbeveloper 	}
2709dec2310SAxel Dörfler 
2719dec2310SAxel Dörfler 	media_addon_id addonID = addon->AddonID();
27254187cc6Sbeveloper 
27334c72144SAxel Dörfler 	// TODO: fix this
2748056f0dbSStephan Aßmus 	printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id "
275332cc6bcSAxel Dörfler 		"%" B_PRId32 ", flavor-id %" B_PRId32 " config NOW!\n", addonID,
276332cc6bcSAxel Dörfler 		flavorID);
27754187cc6Sbeveloper 	return B_OK;
27854187cc6Sbeveloper }
27954187cc6Sbeveloper 
28034c72144SAxel Dörfler 
28154187cc6Sbeveloper status_t
2829dec2310SAxel Dörfler BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonID, int32 flavorID,
2839dec2310SAxel Dörfler 	BMessage *_msg)
28454187cc6Sbeveloper {
28534c72144SAxel Dörfler 	// TODO: fix this
2869dec2310SAxel Dörfler 	_msg->MakeEmpty(); // to be fully R5 compliant
2878b940bb4SStephan Aßmus 	printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id "
288332cc6bcSAxel Dörfler 		"%" B_PRId32 ", flavor-id %" B_PRId32 " config NOW!\n", addonID,
289332cc6bcSAxel Dörfler 		flavorID);
29054187cc6Sbeveloper 	return B_OK;
29154187cc6Sbeveloper }
29254187cc6Sbeveloper 
29334c72144SAxel Dörfler 
29454187cc6Sbeveloper status_t
2959dec2310SAxel Dörfler BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonID,
2969dec2310SAxel Dörfler 	int32 flavorID)
29754187cc6Sbeveloper {
2989c3b4706SAxel Dörfler 	server_change_flavor_instances_count_request request;
2999c3b4706SAxel Dörfler 	server_change_flavor_instances_count_reply reply;
30073794717Sbeveloper 
3019c3b4706SAxel Dörfler 	request.add_on_id = addonID;
3029dec2310SAxel Dörfler 	request.flavor_id = flavorID;
30373794717Sbeveloper 	request.delta = 1;
3049dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
3059c3b4706SAxel Dörfler 	return QueryServer(SERVER_CHANGE_FLAVOR_INSTANCES_COUNT, &request,
30634c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
30754187cc6Sbeveloper }
30854187cc6Sbeveloper 
30934c72144SAxel Dörfler 
31054187cc6Sbeveloper status_t
3119dec2310SAxel Dörfler BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonID,
3129dec2310SAxel Dörfler 	int32 flavorID)
31354187cc6Sbeveloper {
3149c3b4706SAxel Dörfler 	server_change_flavor_instances_count_request request;
3159c3b4706SAxel Dörfler 	server_change_flavor_instances_count_reply reply;
31673794717Sbeveloper 
3179c3b4706SAxel Dörfler 	request.add_on_id = addonID;
3189dec2310SAxel Dörfler 	request.flavor_id = flavorID;
31973794717Sbeveloper 	request.delta = -1;
3209dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
3219c3b4706SAxel Dörfler 	return QueryServer(SERVER_CHANGE_FLAVOR_INSTANCES_COUNT, &request,
32234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
32354187cc6Sbeveloper }
32454187cc6Sbeveloper 
32534c72144SAxel Dörfler 
32654187cc6Sbeveloper status_t
3276aee58a4SJérôme Duval BMediaRosterEx::ReleaseNodeAll(const media_node& node)
3286aee58a4SJérôme Duval {
3296aee58a4SJérôme Duval 		CALLED();
3306aee58a4SJérôme Duval 	if (IS_INVALID_NODE(node))
3316aee58a4SJérôme Duval 		return B_MEDIA_BAD_NODE;
3326aee58a4SJérôme Duval 
33384da57fdSAdrien Destugues 	if (node.kind & NODE_KIND_NO_REFCOUNTING)
3346aee58a4SJérôme Duval 		return B_OK;
3356aee58a4SJérôme Duval 
3366aee58a4SJérôme Duval 	server_release_node_request request;
3376aee58a4SJérôme Duval 	server_release_node_reply reply;
3386aee58a4SJérôme Duval 	status_t rv;
3396aee58a4SJérôme Duval 
3406aee58a4SJérôme Duval 	request.node = node;
3416aee58a4SJérôme Duval 	request.team = BPrivate::current_team();
3426aee58a4SJérôme Duval 
343332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::ReleaseNodeAll, node %" B_PRId32 ", port %" B_PRId32
344332cc6bcSAxel Dörfler 		", team %" B_PRId32 "\n",
3456aee58a4SJérôme Duval 		node.node, node.port, BPrivate::current_team());
3466aee58a4SJérôme Duval 
3476aee58a4SJérôme Duval 	rv = QueryServer(SERVER_RELEASE_NODE_ALL, &request, sizeof(request), &reply,
3486aee58a4SJérôme Duval 		sizeof(reply));
3496aee58a4SJérôme Duval 	if (rv != B_OK) {
350c74afb57SJérôme Duval 		ERROR("BMediaRoster::ReleaseNodeAll failed to query media_server, "
351c74afb57SJérôme Duval 			"retrying local, node %" B_PRId32 ", port %"
352c74afb57SJérôme Duval 			B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
353c74afb57SJérôme Duval 			BPrivate::current_team());
354c74afb57SJérôme Duval 		node_final_release_command command;
355c74afb57SJérôme Duval 		rv = SendToPort(node.port, NODE_FINAL_RELEASE, &command,
356c74afb57SJérôme Duval 			sizeof(command));
357c74afb57SJérôme Duval 		if (rv != B_OK) {
358332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %" B_PRId32 ", port %"
359332cc6bcSAxel Dörfler 				B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
360332cc6bcSAxel Dörfler 				BPrivate::current_team());
3616aee58a4SJérôme Duval 		}
362c74afb57SJérôme Duval 	}
3636aee58a4SJérôme Duval 	return rv;
3646aee58a4SJérôme Duval }
3656aee58a4SJérôme Duval 
3666aee58a4SJérôme Duval 
3676aee58a4SJérôme Duval status_t
36854187cc6Sbeveloper BMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator)
36954187cc6Sbeveloper {
37054187cc6Sbeveloper 	server_set_node_creator_request request;
37154187cc6Sbeveloper 	server_set_node_creator_reply reply;
37254187cc6Sbeveloper 
37354187cc6Sbeveloper 	request.node = node;
37454187cc6Sbeveloper 	request.creator = creator;
37534c72144SAxel Dörfler 	return QueryServer(SERVER_SET_NODE_CREATOR, &request, sizeof(request),
37634c72144SAxel Dörfler 		&reply, sizeof(reply));
37754187cc6Sbeveloper }
37854187cc6Sbeveloper 
37934c72144SAxel Dörfler 
38054187cc6Sbeveloper status_t
38134c72144SAxel Dörfler BMediaRosterEx::GetNode(node_type type, media_node* out_node,
38234c72144SAxel Dörfler 	int32* out_input_id, BString* out_input_name)
38352a38012Sejakowatz {
38452a38012Sejakowatz 	if (out_node == NULL)
38552a38012Sejakowatz 		return B_BAD_VALUE;
38652a38012Sejakowatz 
3878c6a6096Sbeveloper 	server_get_node_request request;
3888c6a6096Sbeveloper 	server_get_node_reply reply;
38952a38012Sejakowatz 	status_t rv;
39052a38012Sejakowatz 
3918c6a6096Sbeveloper 	request.type = type;
3929dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
39334c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply,
39434c72144SAxel Dörfler 		sizeof(reply));
3958c6a6096Sbeveloper 	if (rv != B_OK)
3968c6a6096Sbeveloper 		return rv;
39752a38012Sejakowatz 
39852a38012Sejakowatz 	*out_node = reply.node;
39952a38012Sejakowatz 	if (out_input_id)
40052a38012Sejakowatz 		*out_input_id = reply.input_id;
40152a38012Sejakowatz 	if (out_input_name)
40252a38012Sejakowatz 		*out_input_name = reply.input_name;
4038c6a6096Sbeveloper 	return rv;
40452a38012Sejakowatz }
40552a38012Sejakowatz 
40634c72144SAxel Dörfler 
4073620737cSbeveloper status_t
40834c72144SAxel Dörfler BMediaRosterEx::SetNode(node_type type, const media_node* node,
40934c72144SAxel Dörfler 	const dormant_node_info* info, const media_input* input)
41052a38012Sejakowatz {
4118c6a6096Sbeveloper 	server_set_node_request request;
4128c6a6096Sbeveloper 	server_set_node_reply reply;
41352a38012Sejakowatz 
4148c6a6096Sbeveloper 	request.type = type;
41534c72144SAxel Dörfler 	request.use_node = node != NULL;
41634c72144SAxel Dörfler 	if (node != NULL)
4178c6a6096Sbeveloper 		request.node = *node;
41834c72144SAxel Dörfler 	request.use_dni = info != NULL;
41934c72144SAxel Dörfler 	if (info != NULL)
4208c6a6096Sbeveloper 		request.dni = *info;
42134c72144SAxel Dörfler 	request.use_input = input != NULL;
42234c72144SAxel Dörfler 	if (input != NULL)
4238c6a6096Sbeveloper 		request.input = *input;
42452a38012Sejakowatz 
42534c72144SAxel Dörfler 	return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply,
42634c72144SAxel Dörfler 		sizeof(reply));
42752a38012Sejakowatz }
42852a38012Sejakowatz 
42934c72144SAxel Dörfler 
4303620737cSbeveloper status_t
4318b04ffc1Sbeveloper BMediaRosterEx::GetAllOutputs(const media_node& node, List<media_output>* list)
4323620737cSbeveloper {
4333620737cSbeveloper 	int32 cookie;
4343620737cSbeveloper 	status_t rv;
4353620737cSbeveloper 	status_t result;
4363620737cSbeveloper 
437332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllOutputs() node %" B_PRId32 ", port %"
438332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, node.port);
4395ac4fbd7Sbeveloper 
44065b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_PRODUCER)) {
441332cc6bcSAxel Dörfler 		ERROR("BMediaRosterEx::GetAllOutputs: node %" B_PRId32 " is not a "
44234c72144SAxel Dörfler 			"B_BUFFER_PRODUCER\n", node.node);
44365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
44465b73ae4SMarcus Overhagen 	}
44565b73ae4SMarcus Overhagen 
4463620737cSbeveloper 	result = B_OK;
4473620737cSbeveloper 	cookie = 0;
44876669a29Sbeveloper 	list->MakeEmpty();
4493620737cSbeveloper 	for (;;) {
4503620737cSbeveloper 		producer_get_next_output_request request;
4513620737cSbeveloper 		producer_get_next_output_reply reply;
4523620737cSbeveloper 		request.cookie = cookie;
45334c72144SAxel Dörfler 		rv = QueryPort(node.port, PRODUCER_GET_NEXT_OUTPUT, &request,
45434c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
4553620737cSbeveloper 		if (rv != B_OK)
4563620737cSbeveloper 			break;
4573620737cSbeveloper 		cookie = reply.cookie;
45876669a29Sbeveloper 		if (!list->Insert(reply.output)) {
4595ac4fbd7Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
4603620737cSbeveloper 			result = B_ERROR;
4613620737cSbeveloper 		}
4625ac4fbd7Sbeveloper 		#if DEBUG >= 3
463332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
4645ac4fbd7Sbeveloper 			PRINT_OUTPUT("output ", reply.output);
4655ac4fbd7Sbeveloper 		#endif
4663620737cSbeveloper 	}
4673620737cSbeveloper 
4683620737cSbeveloper 	producer_dispose_output_cookie_request request;
4693620737cSbeveloper 	producer_dispose_output_cookie_reply reply;
47034c72144SAxel Dörfler 	QueryPort(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &request,
47134c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
4723620737cSbeveloper 
4733620737cSbeveloper 	return result;
4743620737cSbeveloper }
4753620737cSbeveloper 
47634c72144SAxel Dörfler 
4773620737cSbeveloper status_t
4784d2d96e0Sbeveloper BMediaRosterEx::GetAllOutputs(BBufferProducer* node, List<media_output>* list)
4794d2d96e0Sbeveloper {
4804d2d96e0Sbeveloper 	int32 cookie;
4814d2d96e0Sbeveloper 	status_t result;
4824d2d96e0Sbeveloper 
483332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllOutputs() (by pointer) node %" B_PRId32
484332cc6bcSAxel Dörfler 		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
4854d2d96e0Sbeveloper 
4864d2d96e0Sbeveloper 	result = B_OK;
4874d2d96e0Sbeveloper 	cookie = 0;
4884d2d96e0Sbeveloper 	list->MakeEmpty();
4894d2d96e0Sbeveloper 	for (;;) {
4904d2d96e0Sbeveloper 		media_output output;
4914d2d96e0Sbeveloper 		if (B_OK != node->GetNextOutput(&cookie, &output))
4924d2d96e0Sbeveloper 			break;
4934d2d96e0Sbeveloper 		if (!list->Insert(output)) {
4944d2d96e0Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
4954d2d96e0Sbeveloper 			result = B_ERROR;
4964d2d96e0Sbeveloper 		}
4974d2d96e0Sbeveloper 		#if DEBUG >= 3
498332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
4994d2d96e0Sbeveloper 			PRINT_OUTPUT("output ", output);
5004d2d96e0Sbeveloper 		#endif
5014d2d96e0Sbeveloper 	}
5024d2d96e0Sbeveloper 	node->DisposeOutputCookie(cookie);
5034d2d96e0Sbeveloper 	return result;
5044d2d96e0Sbeveloper }
5054d2d96e0Sbeveloper 
50634c72144SAxel Dörfler 
5074d2d96e0Sbeveloper status_t
5088b04ffc1Sbeveloper BMediaRosterEx::GetAllInputs(const media_node& node, List<media_input>* list)
5093620737cSbeveloper {
5103620737cSbeveloper 	int32 cookie;
5113620737cSbeveloper 	status_t rv;
5123620737cSbeveloper 	status_t result;
5133620737cSbeveloper 
514332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllInputs() node %" B_PRId32 ", port %"
515332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, node.port);
5165ac4fbd7Sbeveloper 
51765b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_CONSUMER)) {
518332cc6bcSAxel Dörfler 		ERROR("BMediaRosterEx::GetAllInputs: node %" B_PRId32 " is not a "
51934c72144SAxel Dörfler 			"B_BUFFER_CONSUMER\n", node.node);
52065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
52165b73ae4SMarcus Overhagen 	}
52265b73ae4SMarcus Overhagen 
5233620737cSbeveloper 	result = B_OK;
5243620737cSbeveloper 	cookie = 0;
52576669a29Sbeveloper 	list->MakeEmpty();
5263620737cSbeveloper 	for (;;) {
5273620737cSbeveloper 		consumer_get_next_input_request request;
5283620737cSbeveloper 		consumer_get_next_input_reply reply;
5293620737cSbeveloper 		request.cookie = cookie;
53034c72144SAxel Dörfler 		rv = QueryPort(node.port, CONSUMER_GET_NEXT_INPUT, &request,
53134c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
5323620737cSbeveloper 		if (rv != B_OK)
5333620737cSbeveloper 			break;
5343620737cSbeveloper 		cookie = reply.cookie;
53576669a29Sbeveloper 		if (!list->Insert(reply.input)) {
5365ac4fbd7Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
5373620737cSbeveloper 			result = B_ERROR;
5383620737cSbeveloper 		}
5395ac4fbd7Sbeveloper 		#if DEBUG >= 3
540332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
5415ac4fbd7Sbeveloper 			PRINT_OUTPUT("input ", reply.input);
5425ac4fbd7Sbeveloper 		#endif
5433620737cSbeveloper 	}
5443620737cSbeveloper 
5453620737cSbeveloper 	consumer_dispose_input_cookie_request request;
5463620737cSbeveloper 	consumer_dispose_input_cookie_reply reply;
54734c72144SAxel Dörfler 	QueryPort(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &request,
54834c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
5493620737cSbeveloper 
5503620737cSbeveloper 	return result;
5513620737cSbeveloper }
5523620737cSbeveloper 
55334c72144SAxel Dörfler 
5543620737cSbeveloper status_t
5554d2d96e0Sbeveloper BMediaRosterEx::GetAllInputs(BBufferConsumer* node, List<media_input>* list)
5564d2d96e0Sbeveloper {
5574d2d96e0Sbeveloper 	int32 cookie;
5584d2d96e0Sbeveloper 	status_t result;
5594d2d96e0Sbeveloper 
560332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllInputs() (by pointer) node %" B_PRId32
561332cc6bcSAxel Dörfler 		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
5624d2d96e0Sbeveloper 
5634d2d96e0Sbeveloper 	result = B_OK;
5644d2d96e0Sbeveloper 	cookie = 0;
5654d2d96e0Sbeveloper 	list->MakeEmpty();
5664d2d96e0Sbeveloper 	for (;;) {
5674d2d96e0Sbeveloper 		media_input input;
5684d2d96e0Sbeveloper 		if (B_OK != node->GetNextInput(&cookie, &input))
5694d2d96e0Sbeveloper 			break;
5704d2d96e0Sbeveloper 		if (!list->Insert(input)) {
5714d2d96e0Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
5724d2d96e0Sbeveloper 			result = B_ERROR;
5734d2d96e0Sbeveloper 		}
5744d2d96e0Sbeveloper 		#if DEBUG >= 3
575332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
5764d2d96e0Sbeveloper 			PRINT_INPUT("input ", input);
5774d2d96e0Sbeveloper 		#endif
5784d2d96e0Sbeveloper 	}
5794d2d96e0Sbeveloper 	node->DisposeInputCookie(cookie);
5804d2d96e0Sbeveloper 	return result;
5814d2d96e0Sbeveloper }
5824d2d96e0Sbeveloper 
58334c72144SAxel Dörfler 
5844d2d96e0Sbeveloper status_t
5858b04ffc1Sbeveloper BMediaRosterEx::PublishOutputs(const media_node& node, List<media_output>* list)
5863620737cSbeveloper {
5873620737cSbeveloper 	server_publish_outputs_request request;
5883620737cSbeveloper 	server_publish_outputs_reply reply;
5893620737cSbeveloper 	media_output* output;
5903620737cSbeveloper 	media_output* outputs;
5913620737cSbeveloper 	int32 count;
592a7b41a96Sbeveloper 	status_t rv;
5933620737cSbeveloper 
59476669a29Sbeveloper 	count = list->CountItems();
595332cc6bcSAxel Dörfler 	TRACE("PublishOutputs: publishing %" B_PRId32 "\n", count);
5963620737cSbeveloper 
5973620737cSbeveloper 	request.node = node;
5983620737cSbeveloper 	request.count = count;
5993620737cSbeveloper 	if (count > MAX_OUTPUTS) {
6003620737cSbeveloper 		void *start_addr;
6013620737cSbeveloper 		size_t size;
60240f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_output));
60334c72144SAxel Dörfler 		request.area = create_area("publish outputs", &start_addr,
60434c72144SAxel Dörfler 			B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
6053620737cSbeveloper 		if (request.area < B_OK) {
606332cc6bcSAxel Dörfler 			ERROR("PublishOutputs: failed to create area, %#" B_PRIx32 "\n",
60734c72144SAxel Dörfler 				request.area);
6083620737cSbeveloper 			return (status_t)request.area;
6093620737cSbeveloper 		}
6103620737cSbeveloper 		outputs = static_cast<media_output *>(start_addr);
6113620737cSbeveloper 	} else {
6123620737cSbeveloper 		request.area = -1;
6133620737cSbeveloper 		outputs = request.outputs;
6143620737cSbeveloper 	}
615332cc6bcSAxel Dörfler 	TRACE("PublishOutputs: area %" B_PRId32 "\n", request.area);
6163620737cSbeveloper 
61776669a29Sbeveloper 	int i;
61876669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&output); i++) {
61976669a29Sbeveloper 		ASSERT(i < count);
6203620737cSbeveloper 		outputs[i] = *output;
6213620737cSbeveloper 	}
6223620737cSbeveloper 
62334c72144SAxel Dörfler 	rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request),
62434c72144SAxel Dörfler 		&reply, sizeof(reply));
625a7b41a96Sbeveloper 
626a7b41a96Sbeveloper 	if (request.area != -1)
627a7b41a96Sbeveloper 		delete_area(request.area);
628a7b41a96Sbeveloper 
629a7b41a96Sbeveloper 	return rv;
6303620737cSbeveloper }
6313620737cSbeveloper 
63234c72144SAxel Dörfler 
6333620737cSbeveloper status_t
6348b04ffc1Sbeveloper BMediaRosterEx::PublishInputs(const media_node& node, List<media_input>* list)
6353620737cSbeveloper {
6363620737cSbeveloper 	server_publish_inputs_request request;
6373620737cSbeveloper 	server_publish_inputs_reply reply;
6383620737cSbeveloper 	media_input* input;
6393620737cSbeveloper 	media_input* inputs;
6403620737cSbeveloper 	int32 count;
641a7b41a96Sbeveloper 	status_t rv;
6423620737cSbeveloper 
64376669a29Sbeveloper 	count = list->CountItems();
644332cc6bcSAxel Dörfler 	TRACE("PublishInputs: publishing %" B_PRId32 "\n", count);
6453620737cSbeveloper 
6463620737cSbeveloper 	request.node = node;
6473620737cSbeveloper 	request.count = count;
6483620737cSbeveloper 	if (count > MAX_INPUTS) {
6493620737cSbeveloper 		void* start_addr;
6503620737cSbeveloper 		size_t size;
65140f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_input));
65234c72144SAxel Dörfler 		request.area = create_area("publish inputs", &start_addr,
65334c72144SAxel Dörfler 			B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
6543620737cSbeveloper 		if (request.area < B_OK) {
655332cc6bcSAxel Dörfler 			ERROR("PublishInputs: failed to create area, %#" B_PRIx32 "\n",
656332cc6bcSAxel Dörfler 				request.area);
6573620737cSbeveloper 			return (status_t)request.area;
6583620737cSbeveloper 		}
6593620737cSbeveloper 		inputs = static_cast<media_input *>(start_addr);
6603620737cSbeveloper 	} else {
6613620737cSbeveloper 		request.area = -1;
6623620737cSbeveloper 		inputs = request.inputs;
6633620737cSbeveloper 	}
664332cc6bcSAxel Dörfler 	TRACE("PublishInputs: area %" B_PRId32 "\n", request.area);
6653620737cSbeveloper 
66676669a29Sbeveloper 	int i;
66776669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&input); i++) {
66876669a29Sbeveloper 		ASSERT(i < count);
6693620737cSbeveloper 		inputs[i] = *input;
6703620737cSbeveloper 	}
6713620737cSbeveloper 
67234c72144SAxel Dörfler 	rv = QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request),
67334c72144SAxel Dörfler 		&reply, sizeof(reply));
674a7b41a96Sbeveloper 
675a7b41a96Sbeveloper 	if (request.area != -1)
676a7b41a96Sbeveloper 		delete_area(request.area);
677a7b41a96Sbeveloper 
678a7b41a96Sbeveloper 	return rv;
6793620737cSbeveloper }
6803620737cSbeveloper 
68134c72144SAxel Dörfler 
68234c72144SAxel Dörfler BTimeSource*
683f4ec236cSAxel Dörfler BMediaRosterEx::MakeTimeSourceObject(media_node_id timeSourceID)
68434c72144SAxel Dörfler {
68534c72144SAxel Dörfler 	media_node clone;
686f4ec236cSAxel Dörfler 	status_t status = GetNodeFor(timeSourceID, &clone);
687f4ec236cSAxel Dörfler 	if (status != B_OK) {
688f4ec236cSAxel Dörfler 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetNodeFor failed: %s\n",
689f4ec236cSAxel Dörfler 			strerror(status));
69034c72144SAxel Dörfler 		return NULL;
69134c72144SAxel Dörfler 	}
69234c72144SAxel Dörfler 
693f4ec236cSAxel Dörfler 	BTimeSource* source = gTimeSourceObjectManager->GetTimeSource(clone);
69434c72144SAxel Dörfler 	if (source == NULL) {
69534c72144SAxel Dörfler 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetTimeSource failed\n");
69634c72144SAxel Dörfler 		return NULL;
69734c72144SAxel Dörfler 	}
69834c72144SAxel Dörfler 
69934c72144SAxel Dörfler 	// TODO: release?
70034c72144SAxel Dörfler 	ReleaseNode(clone);
70134c72144SAxel Dörfler 
70234c72144SAxel Dörfler 	return source;
70334c72144SAxel Dörfler }
70434c72144SAxel Dörfler 
70534c72144SAxel Dörfler 
70634c72144SAxel Dörfler //	#pragma mark - public BMediaRoster
70734c72144SAxel Dörfler 
70852a38012Sejakowatz 
70952a38012Sejakowatz status_t
71034c72144SAxel Dörfler BMediaRoster::GetVideoInput(media_node* _node)
71152a38012Sejakowatz {
71252a38012Sejakowatz 	CALLED();
71334c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(VIDEO_INPUT, _node);
71452a38012Sejakowatz }
71552a38012Sejakowatz 
71652a38012Sejakowatz 
71752a38012Sejakowatz status_t
71834c72144SAxel Dörfler BMediaRoster::GetAudioInput(media_node* _node)
71952a38012Sejakowatz {
72052a38012Sejakowatz 	CALLED();
72134c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_INPUT, _node);
72252a38012Sejakowatz }
72352a38012Sejakowatz 
72452a38012Sejakowatz 
72552a38012Sejakowatz status_t
72634c72144SAxel Dörfler BMediaRoster::GetVideoOutput(media_node* _node)
72752a38012Sejakowatz {
72852a38012Sejakowatz 	CALLED();
72934c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(VIDEO_OUTPUT, _node);
73052a38012Sejakowatz }
73152a38012Sejakowatz 
73252a38012Sejakowatz 
73352a38012Sejakowatz status_t
73434c72144SAxel Dörfler BMediaRoster::GetAudioMixer(media_node* _node)
73552a38012Sejakowatz {
73652a38012Sejakowatz 	CALLED();
73734c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_MIXER, _node);
73852a38012Sejakowatz }
73952a38012Sejakowatz 
74052a38012Sejakowatz 
74152a38012Sejakowatz status_t
74234c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node)
74352a38012Sejakowatz {
74452a38012Sejakowatz 	CALLED();
74534c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT, _node);
74652a38012Sejakowatz }
74752a38012Sejakowatz 
74852a38012Sejakowatz 
74952a38012Sejakowatz status_t
75034c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node, int32* _inputID,
75134c72144SAxel Dörfler 	BString* _inputName)
75252a38012Sejakowatz {
75352a38012Sejakowatz 	CALLED();
75434c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT_EX, _node, _inputID,
75534c72144SAxel Dörfler 		_inputName);
75652a38012Sejakowatz }
75752a38012Sejakowatz 
75852a38012Sejakowatz 
75952a38012Sejakowatz status_t
76034c72144SAxel Dörfler BMediaRoster::GetTimeSource(media_node* _node)
76152a38012Sejakowatz {
76252a38012Sejakowatz 	CALLED();
76386bce45bSbeveloper 	status_t rv;
76486bce45bSbeveloper 
76534c72144SAxel Dörfler 	// TODO: need to do this in a nicer way.
76686bce45bSbeveloper 
76734c72144SAxel Dörfler 	rv = MediaRosterEx(this)->GetNode(TIME_SOURCE, _node);
76886bce45bSbeveloper 	if (rv != B_OK)
76986bce45bSbeveloper 		return rv;
77086bce45bSbeveloper 
77186bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
77286bce45bSbeveloper 	// release the node immediately.
77334c72144SAxel Dörfler 	ReleaseNode(*_node);
77486bce45bSbeveloper 
77586bce45bSbeveloper 	// we need to remember to not use this node with server side reference counting
77634c72144SAxel Dörfler 	_node->kind |= NODE_KIND_NO_REFCOUNTING;
77786bce45bSbeveloper 	return B_OK;
77852a38012Sejakowatz }
77952a38012Sejakowatz 
78052a38012Sejakowatz 
78152a38012Sejakowatz status_t
78252a38012Sejakowatz BMediaRoster::SetVideoInput(const media_node& producer)
78352a38012Sejakowatz {
78452a38012Sejakowatz 	CALLED();
7858b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, &producer);
78652a38012Sejakowatz }
78752a38012Sejakowatz 
78852a38012Sejakowatz 
78952a38012Sejakowatz status_t
79052a38012Sejakowatz BMediaRoster::SetVideoInput(const dormant_node_info& producer)
79152a38012Sejakowatz {
79252a38012Sejakowatz 	CALLED();
7938b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, NULL, &producer);
79452a38012Sejakowatz }
79552a38012Sejakowatz 
79652a38012Sejakowatz 
79752a38012Sejakowatz status_t
79852a38012Sejakowatz BMediaRoster::SetAudioInput(const media_node& producer)
79952a38012Sejakowatz {
80052a38012Sejakowatz 	CALLED();
8018b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, &producer);
80252a38012Sejakowatz }
80352a38012Sejakowatz 
80452a38012Sejakowatz 
80552a38012Sejakowatz status_t
80652a38012Sejakowatz BMediaRoster::SetAudioInput(const dormant_node_info& producer)
80752a38012Sejakowatz {
80852a38012Sejakowatz 	CALLED();
8098b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, NULL, &producer);
81052a38012Sejakowatz }
81152a38012Sejakowatz 
81252a38012Sejakowatz 
81352a38012Sejakowatz status_t
81452a38012Sejakowatz BMediaRoster::SetVideoOutput(const media_node& consumer)
81552a38012Sejakowatz {
81652a38012Sejakowatz 	CALLED();
8178b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, &consumer);
81852a38012Sejakowatz }
81952a38012Sejakowatz 
82052a38012Sejakowatz 
82152a38012Sejakowatz status_t
82252a38012Sejakowatz BMediaRoster::SetVideoOutput(const dormant_node_info& consumer)
82352a38012Sejakowatz {
82452a38012Sejakowatz 	CALLED();
8258b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, NULL, &consumer);
82652a38012Sejakowatz }
82752a38012Sejakowatz 
82852a38012Sejakowatz 
82952a38012Sejakowatz status_t
83052a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_node& consumer)
83152a38012Sejakowatz {
83252a38012Sejakowatz 	CALLED();
8338b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, &consumer);
83452a38012Sejakowatz }
83552a38012Sejakowatz 
83652a38012Sejakowatz 
83752a38012Sejakowatz status_t
83834c72144SAxel Dörfler BMediaRoster::SetAudioOutput(const media_input& input)
83952a38012Sejakowatz {
84052a38012Sejakowatz 	CALLED();
84134c72144SAxel Dörfler 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, NULL, &input);
84252a38012Sejakowatz }
84352a38012Sejakowatz 
84452a38012Sejakowatz 
84552a38012Sejakowatz status_t
84652a38012Sejakowatz BMediaRoster::SetAudioOutput(const dormant_node_info& consumer)
84752a38012Sejakowatz {
84852a38012Sejakowatz 	CALLED();
8498b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, &consumer);
85052a38012Sejakowatz }
85152a38012Sejakowatz 
85252a38012Sejakowatz 
85352a38012Sejakowatz status_t
85434c72144SAxel Dörfler BMediaRoster::GetNodeFor(media_node_id node, media_node* clone)
85552a38012Sejakowatz {
8569e9417d2Sbeveloper 	CALLED();
8579e9417d2Sbeveloper 	if (clone == NULL)
8589e9417d2Sbeveloper 		return B_BAD_VALUE;
85965b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(node))
8609e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
8619e9417d2Sbeveloper 
8629e9417d2Sbeveloper 	server_get_node_for_request request;
8639e9417d2Sbeveloper 	server_get_node_for_reply reply;
8649e9417d2Sbeveloper 	status_t rv;
8659e9417d2Sbeveloper 
8669dec2310SAxel Dörfler 	request.node_id = node;
8679dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
8689e9417d2Sbeveloper 
86934c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply,
87034c72144SAxel Dörfler 		sizeof(reply));
8719e9417d2Sbeveloper 	if (rv != B_OK)
8729e9417d2Sbeveloper 		return rv;
8739e9417d2Sbeveloper 
8749e9417d2Sbeveloper 	*clone = reply.clone;
8759e9417d2Sbeveloper 	return B_OK;
87652a38012Sejakowatz }
87752a38012Sejakowatz 
87852a38012Sejakowatz 
87952a38012Sejakowatz status_t
88052a38012Sejakowatz BMediaRoster::GetSystemTimeSource(media_node* clone)
88152a38012Sejakowatz {
88252a38012Sejakowatz 	CALLED();
88386bce45bSbeveloper 	status_t rv;
88486bce45bSbeveloper 
88534c72144SAxel Dörfler 	// TODO: need to do this in a nicer way.
88686bce45bSbeveloper 
88786bce45bSbeveloper 	rv = MediaRosterEx(this)->GetNode(SYSTEM_TIME_SOURCE, clone);
88886bce45bSbeveloper 	if (rv != B_OK)
88986bce45bSbeveloper 		return rv;
89086bce45bSbeveloper 
89186bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
89286bce45bSbeveloper 	// release the node immediately.
89386bce45bSbeveloper 	ReleaseNode(*clone);
89486bce45bSbeveloper 
89534c72144SAxel Dörfler 	// we need to remember to not use this node with server side reference
89634c72144SAxel Dörfler 	// counting
89786bce45bSbeveloper 	clone->kind |= NODE_KIND_NO_REFCOUNTING;
89886bce45bSbeveloper 
89986bce45bSbeveloper 	return B_OK;
90052a38012Sejakowatz }
90152a38012Sejakowatz 
90252a38012Sejakowatz 
90352a38012Sejakowatz status_t
90452a38012Sejakowatz BMediaRoster::ReleaseNode(const media_node& node)
90552a38012Sejakowatz {
9069e9417d2Sbeveloper 	CALLED();
90740f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
9089e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
90952a38012Sejakowatz 
91086bce45bSbeveloper 	if (node.kind & NODE_KIND_NO_REFCOUNTING) {
911cb2c4f8dSAdrien Destugues 		TRACE("BMediaRoster::ReleaseNode, trying to release reference "
912332cc6bcSAxel Dörfler 			"counting disabled timesource, node %" B_PRId32 ", port %" B_PRId32
913332cc6bcSAxel Dörfler 			", team %" B_PRId32 "\n", node.node, node.port,
914332cc6bcSAxel Dörfler 			BPrivate::current_team());
91586bce45bSbeveloper 		return B_OK;
91686bce45bSbeveloper 	}
91786bce45bSbeveloper 
9189e9417d2Sbeveloper 	server_release_node_request request;
9199e9417d2Sbeveloper 	server_release_node_reply reply;
920cf4e2277Sbeveloper 	status_t rv;
9219e9417d2Sbeveloper 
9229e9417d2Sbeveloper 	request.node = node;
9239dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
9249e9417d2Sbeveloper 
925332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::ReleaseNode, node %" B_PRId32 ", port %" B_PRId32
926332cc6bcSAxel Dörfler 		", team %" B_PRId32 "\n", node.node, node.port,
927332cc6bcSAxel Dörfler 		BPrivate::current_team());
928cf4e2277Sbeveloper 
92934c72144SAxel Dörfler 	rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply,
93034c72144SAxel Dörfler 		sizeof(reply));
931cf4e2277Sbeveloper 	if (rv != B_OK) {
932332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::ReleaseNode FAILED, node %" B_PRId32 ", port %"
933332cc6bcSAxel Dörfler 			B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
934332cc6bcSAxel Dörfler 			BPrivate::current_team());
935cf4e2277Sbeveloper 	}
936cf4e2277Sbeveloper 	return rv;
9379e9417d2Sbeveloper }
93852a38012Sejakowatz 
93934c72144SAxel Dörfler 
94052a38012Sejakowatz BTimeSource*
94134c72144SAxel Dörfler BMediaRoster::MakeTimeSourceFor(const media_node& forNode)
94252a38012Sejakowatz {
943f180ef79Sbeveloper 	// MakeTimeSourceFor() returns a BTimeSource object
944f180ef79Sbeveloper 	// corresponding to the specified node's time source.
945f180ef79Sbeveloper 
946835140c8Sbeveloper 	CALLED();
947f180ef79Sbeveloper 
94834c72144SAxel Dörfler 	if (IS_SYSTEM_TIMESOURCE(forNode)) {
949f180ef79Sbeveloper 		// special handling for the system time source
95034c72144SAxel Dörfler 		TRACE("BMediaRoster::MakeTimeSourceFor, asked for system time "
95134c72144SAxel Dörfler 			"source\n");
95234c72144SAxel Dörfler 		return MediaRosterEx(this)->MakeTimeSourceObject(
95334c72144SAxel Dörfler 			NODE_SYSTEM_TIMESOURCE_ID);
954f180ef79Sbeveloper 	}
955f180ef79Sbeveloper 
95634c72144SAxel Dörfler 	if (IS_INVALID_NODE(forNode)) {
957332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::MakeTimeSourceFor: for_node invalid, node %"
958332cc6bcSAxel Dörfler 			B_PRId32 ", port %" B_PRId32 ", kinds 0x%" B_PRIx32 "\n",
959332cc6bcSAxel Dörfler 			forNode.node, forNode.port, forNode.kind);
9605917dd5bSbeveloper 		return NULL;
9610e21b167Sbeveloper 	}
9620e21b167Sbeveloper 
963332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::MakeTimeSourceFor: node %" B_PRId32 " enter\n",
964332cc6bcSAxel Dörfler 		forNode.node);
9655917dd5bSbeveloper 
9665917dd5bSbeveloper 	node_get_timesource_request request;
9675917dd5bSbeveloper 	node_get_timesource_reply reply;
9685917dd5bSbeveloper 	BTimeSource *source;
9695917dd5bSbeveloper 	status_t rv;
9705917dd5bSbeveloper 
97192e575c1Sbeveloper 	// ask the node to get it's current timesource id
97234c72144SAxel Dörfler 	rv = QueryPort(forNode.port, NODE_GET_TIMESOURCE, &request,
97334c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
9745917dd5bSbeveloper 	if (rv != B_OK) {
9755ac4fbd7Sbeveloper 		ERROR("BMediaRoster::MakeTimeSourceFor: request failed\n");
9765917dd5bSbeveloper 		return NULL;
9775917dd5bSbeveloper 	}
9785917dd5bSbeveloper 
9795917dd5bSbeveloper 	source = MediaRosterEx(this)->MakeTimeSourceObject(reply.timesource_id);
9805917dd5bSbeveloper 
981332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::MakeTimeSourceFor: node %" B_PRId32 " leave\n",
982332cc6bcSAxel Dörfler 		forNode.node);
983287f7492Sbeveloper 
984835140c8Sbeveloper 	return source;
98552a38012Sejakowatz }
98652a38012Sejakowatz 
98752a38012Sejakowatz 
98852a38012Sejakowatz status_t
98934c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to,
99034c72144SAxel Dörfler 	media_format* _format, media_output* _output, media_input* _input)
99152a38012Sejakowatz {
99234c72144SAxel Dörfler 	return BMediaRoster::Connect(from, to, _format, _output, _input, 0);
993eae26d3dSbeveloper }
994eae26d3dSbeveloper 
995eae26d3dSbeveloper 
996eae26d3dSbeveloper status_t
99734c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to,
99834c72144SAxel Dörfler 	media_format* io_format, media_output* out_output, media_input* out_input,
99934c72144SAxel Dörfler 	uint32 in_flags, void* _reserved)
1000eae26d3dSbeveloper {
100152a38012Sejakowatz 	CALLED();
100252a38012Sejakowatz 	if (io_format == NULL || out_output == NULL || out_input == NULL)
100352a38012Sejakowatz 		return B_BAD_VALUE;
100440f36b03Sbeveloper 	if (IS_INVALID_SOURCE(from)) {
10055ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_source invalid\n");
100652a38012Sejakowatz 		return B_MEDIA_BAD_SOURCE;
10079e9417d2Sbeveloper 	}
100840f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(to)) {
10095ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_destination invalid\n");
101052a38012Sejakowatz 		return B_MEDIA_BAD_DESTINATION;
10119e9417d2Sbeveloper 	}
101252a38012Sejakowatz 
101352a38012Sejakowatz 	status_t rv;
101465b73ae4SMarcus Overhagen 
101565b73ae4SMarcus Overhagen 	// find the output and input nodes
101634c72144SAxel Dörfler 	// TODO: isn't there a easier way?
101765b73ae4SMarcus Overhagen 	media_node sourcenode;
101865b73ae4SMarcus Overhagen 	media_node destnode;
101965b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(from.port), &sourcenode);
102065b73ae4SMarcus Overhagen 	if (rv != B_OK) {
1021332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: Can't find source node for port %"
1022332cc6bcSAxel Dörfler 			B_PRId32 "\n", from.port);
102365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
102465b73ae4SMarcus Overhagen 	}
102565b73ae4SMarcus Overhagen 	ReleaseNode(sourcenode);
102665b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(to.port), &destnode);
102765b73ae4SMarcus Overhagen 	if (rv != B_OK) {
102834c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: Can't find destination node for port "
1029332cc6bcSAxel Dörfler 			"%" B_PRId32 "\n", to.port);
103065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
103165b73ae4SMarcus Overhagen 	}
103265b73ae4SMarcus Overhagen 	ReleaseNode(destnode);
103365b73ae4SMarcus Overhagen 
103465b73ae4SMarcus Overhagen 	if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
1035332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: source node %" B_PRId32 " is not a "
103634c72144SAxel Dörfler 			"B_BUFFER_PRODUCER\n", sourcenode.node);
103765b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
103865b73ae4SMarcus Overhagen 	}
103965b73ae4SMarcus Overhagen 	if (!(destnode.kind & B_BUFFER_CONSUMER)) {
1040332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: destination node %" B_PRId32 " is not a "
104134c72144SAxel Dörfler 			"B_BUFFER_CONSUMER\n", destnode.node);
104265b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
104365b73ae4SMarcus Overhagen 	}
104465b73ae4SMarcus Overhagen 
10458c6a6096Sbeveloper 	producer_format_proposal_request request1;
10468c6a6096Sbeveloper 	producer_format_proposal_reply reply1;
104752a38012Sejakowatz 
104834c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
104934c72144SAxel Dörfler 		"BBufferProducer::FormatProposal with format  ", *io_format);
105069983609Sbeveloper 
105152a38012Sejakowatz 	// BBufferProducer::FormatProposal
10528c6a6096Sbeveloper 	request1.output = from;
10538c6a6096Sbeveloper 	request1.format = *io_format;
105434c72144SAxel Dörfler 	rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1,
105534c72144SAxel Dörfler 		sizeof(request1), &reply1, sizeof(reply1));
10568c6a6096Sbeveloper 	if (rv != B_OK) {
105734c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
1058332cc6bcSAxel Dörfler 			"BBufferProducer::FormatProposal, status = %#" B_PRIx32 "\n",rv);
105952a38012Sejakowatz 		return rv;
106052a38012Sejakowatz 	}
10618c6a6096Sbeveloper 	// reply1.format now contains the format proposed by the producer
10628c6a6096Sbeveloper 
10638c6a6096Sbeveloper 	consumer_accept_format_request request2;
10648c6a6096Sbeveloper 	consumer_accept_format_reply reply2;
10658c6a6096Sbeveloper 
106634c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
106734c72144SAxel Dörfler 		"BBufferConsumer::AcceptFormat with format    ", reply1.format);
106869983609Sbeveloper 
10698c6a6096Sbeveloper 	// BBufferConsumer::AcceptFormat
10708c6a6096Sbeveloper 	request2.dest = to;
10718c6a6096Sbeveloper 	request2.format = reply1.format;
107234c72144SAxel Dörfler 	rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2,
107334c72144SAxel Dörfler 		sizeof(request2), &reply2, sizeof(reply2));
10748c6a6096Sbeveloper 	if (rv != B_OK) {
107534c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
1076332cc6bcSAxel Dörfler 			"BBufferConsumer::AcceptFormat, status = %#" B_PRIx32 "\n",rv);
10778c6a6096Sbeveloper 		return rv;
10788c6a6096Sbeveloper 	}
10798c6a6096Sbeveloper 	// reply2.format now contains the format accepted by the consumer
10808c6a6096Sbeveloper 
10818c6a6096Sbeveloper 	// BBufferProducer::PrepareToConnect
10828c6a6096Sbeveloper 	producer_prepare_to_connect_request request3;
10838c6a6096Sbeveloper 	producer_prepare_to_connect_reply reply3;
10848c6a6096Sbeveloper 
108534c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
108634c72144SAxel Dörfler 		"BBufferProducer::PrepareToConnect with format", reply2.format);
108769983609Sbeveloper 
10888c6a6096Sbeveloper 	request3.source = from;
10898c6a6096Sbeveloper 	request3.destination = to;
10908c6a6096Sbeveloper 	request3.format = reply2.format;
109134c72144SAxel Dörfler 	strcpy(request3.name, "XXX some default name"); // TODO: fix this
109234c72144SAxel Dörfler 	rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3,
109334c72144SAxel Dörfler 		sizeof(request3), &reply3, sizeof(reply3));
10948c6a6096Sbeveloper 	if (rv != B_OK) {
109534c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
1096332cc6bcSAxel Dörfler 			"BBufferProducer::PrepareToConnect, status = %#" B_PRIx32 "\n", rv);
10978c6a6096Sbeveloper 		return rv;
10988c6a6096Sbeveloper 	}
10998c6a6096Sbeveloper 	// reply3.format is still our pretty media format
11008c6a6096Sbeveloper 	// reply3.out_source the real source to be used for the connection
110134c72144SAxel Dörfler 	// reply3.name the name BBufferConsumer::Connected will see in the
110234c72144SAxel Dörfler 	// outInput->name argument
11038c6a6096Sbeveloper 
11048c6a6096Sbeveloper 	// BBufferConsumer::Connected
11058c6a6096Sbeveloper 	consumer_connected_request request4;
11068c6a6096Sbeveloper 	consumer_connected_reply reply4;
11078c6a6096Sbeveloper 	status_t con_status;
11088c6a6096Sbeveloper 
110934c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferConsumer::Connected() "
111034c72144SAxel Dörfler 		"with format       ", reply3.format);
111169983609Sbeveloper 
111269983609Sbeveloper 	request4.input.node = destnode;
111369983609Sbeveloper 	request4.input.source = reply3.out_source;
111469983609Sbeveloper 	request4.input.destination = to;
111569983609Sbeveloper 	request4.input.format = reply3.format;
111669983609Sbeveloper 	strcpy(request4.input.name, reply3.name);
111769983609Sbeveloper 
111834c72144SAxel Dörfler 	con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4,
111934c72144SAxel Dörfler 		sizeof(request4), &reply4, sizeof(reply4));
11208c6a6096Sbeveloper 	if (con_status != B_OK) {
112134c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborting after "
1122332cc6bcSAxel Dörfler 			"BBufferConsumer::Connected, status = %#" B_PRIx32 "\n",
1123332cc6bcSAxel Dörfler 			con_status);
11248c6a6096Sbeveloper 		// we do NOT return here!
11258c6a6096Sbeveloper 	}
112634c72144SAxel Dörfler 	// con_status contains the status code to be supplied to
112734c72144SAxel Dörfler 	// BBufferProducer::Connect's status argument
112834c72144SAxel Dörfler 	// reply4.input contains the media_input that describes the connection
112934c72144SAxel Dörfler 	// from the consumer point of view
11308c6a6096Sbeveloper 
11318c6a6096Sbeveloper 	// BBufferProducer::Connect
11328c6a6096Sbeveloper 	producer_connect_request request5;
11338c6a6096Sbeveloper 	producer_connect_reply reply5;
11348c6a6096Sbeveloper 
113534c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::Connect with "
113634c72144SAxel Dörfler 		"format         ", reply4.input.format);
113769983609Sbeveloper 
11388c6a6096Sbeveloper 	request5.error = con_status;
11398c6a6096Sbeveloper 	request5.source = reply3.out_source;
11408c6a6096Sbeveloper 	request5.destination = reply4.input.destination;
114169983609Sbeveloper 	request5.format = reply4.input.format;
11428c6a6096Sbeveloper 	strcpy(request5.name, reply4.input.name);
114334c72144SAxel Dörfler 	rv = QueryPort(reply4.input.source.port, PRODUCER_CONNECT, &request5,
114434c72144SAxel Dörfler 		sizeof(request5), &reply5, sizeof(reply5));
11458c6a6096Sbeveloper 	if (con_status != B_OK) {
11465ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted\n");
11478c6a6096Sbeveloper 		return con_status;
11488c6a6096Sbeveloper 	}
11498c6a6096Sbeveloper 	if (rv != B_OK) {
115034c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after BBufferProducer::Connect()"
1151332cc6bcSAxel Dörfler 			", status = %#" B_PRIx32 "\n", rv);
11528c6a6096Sbeveloper 		return rv;
11538c6a6096Sbeveloper 	}
11548c6a6096Sbeveloper 	// reply5.name contains the name assigned to the connection by the producer
11558c6a6096Sbeveloper 
11568c6a6096Sbeveloper 	// initilize connection info
115769983609Sbeveloper 	*io_format = reply4.input.format;
11588c6a6096Sbeveloper 	*out_input = reply4.input;
11598c6a6096Sbeveloper 	out_output->node = sourcenode;
11608c6a6096Sbeveloper 	out_output->source = reply4.input.source;
11618c6a6096Sbeveloper 	out_output->destination = reply4.input.destination;
11628c6a6096Sbeveloper 	out_output->format = reply4.input.format;
11638c6a6096Sbeveloper 	strcpy(out_output->name, reply5.name);
11648c6a6096Sbeveloper 
11658c6a6096Sbeveloper 	// the connection is now made
116669983609Sbeveloper 	PRINT_FORMAT("   format", *io_format);
116769983609Sbeveloper 	PRINT_INPUT("   input", *out_input);
116869983609Sbeveloper 	PRINT_OUTPUT("   output", *out_output);
11698c6a6096Sbeveloper 
117034c72144SAxel Dörfler 	// TODO: register connection with server
117134c72144SAxel Dörfler 	// TODO: we should just send a notification, instead of republishing all
117234c72144SAxel Dörfler 	// endpoints
117376669a29Sbeveloper 	List<media_output> outlist;
117476669a29Sbeveloper 	List<media_input> inlist;
117534c72144SAxel Dörfler 	if (MediaRosterEx(this)->GetAllOutputs(out_output->node , &outlist) == B_OK)
11768b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishOutputs(out_output->node , &outlist);
117734c72144SAxel Dörfler 	if (MediaRosterEx(this)->GetAllInputs(out_input->node , &inlist) == B_OK)
11788b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishInputs(out_input->node, &inlist);
11798c6a6096Sbeveloper 
118034c72144SAxel Dörfler 	// TODO: if (mute) BBufferProducer::EnableOutput(false)
11819e9417d2Sbeveloper 	if (in_flags & B_CONNECT_MUTED) {
11829e9417d2Sbeveloper 	}
11838c6a6096Sbeveloper 
11849e9417d2Sbeveloper 	// send a notification
118534c72144SAxel Dörfler 	BPrivate::media::notifications::ConnectionMade(*out_input, *out_output,
118634c72144SAxel Dörfler 		*io_format);
11879e9417d2Sbeveloper 
11888c6a6096Sbeveloper 	return B_OK;
11898c6a6096Sbeveloper };
119052a38012Sejakowatz 
119152a38012Sejakowatz 
119252a38012Sejakowatz status_t
11939e9417d2Sbeveloper BMediaRoster::Disconnect(media_node_id source_nodeid,
119434c72144SAxel Dörfler 	const media_source& source, media_node_id destination_nodeid,
119552a38012Sejakowatz 	const media_destination& destination)
119652a38012Sejakowatz {
11979e9417d2Sbeveloper 	CALLED();
119840f36b03Sbeveloper 	if (IS_INVALID_NODEID(source_nodeid)) {
11995ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: source media_node_id invalid\n");
12009e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
12019e9417d2Sbeveloper 	}
120240f36b03Sbeveloper 	if (IS_INVALID_NODEID(destination_nodeid)) {
12035ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: destination media_node_id invalid\n");
12049e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
12059e9417d2Sbeveloper 	}
120640f36b03Sbeveloper 	if (IS_INVALID_SOURCE(source)) {
12075ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_source invalid\n");
12089e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
12099e9417d2Sbeveloper 	}
121040f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(destination)) {
12115ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_destination invalid\n");
12129e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
12139e9417d2Sbeveloper 	}
12149e9417d2Sbeveloper 
12159e9417d2Sbeveloper 	producer_disconnect_request request2;
12169e9417d2Sbeveloper 	producer_disconnect_reply reply2;
12179e9417d2Sbeveloper 	consumer_disconnected_request request1;
12189e9417d2Sbeveloper 	consumer_disconnected_reply reply1;
12199e9417d2Sbeveloper 	status_t rv1, rv2;
12209e9417d2Sbeveloper 
122134c72144SAxel Dörfler 	// TODO: we should ask the server if this connection really exists
12229e9417d2Sbeveloper 
12239e9417d2Sbeveloper 	request1.source = source;
12249e9417d2Sbeveloper 	request1.destination = destination;
12259e9417d2Sbeveloper 	request2.source = source;
12269e9417d2Sbeveloper 	request2.destination = destination;
12279e9417d2Sbeveloper 
122834c72144SAxel Dörfler 	rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1,
122934c72144SAxel Dörfler 		sizeof(request1), &reply1, sizeof(reply1));
123034c72144SAxel Dörfler 	rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2,
123134c72144SAxel Dörfler 		sizeof(request2), &reply2, sizeof(reply2));
12329e9417d2Sbeveloper 
123334c72144SAxel Dörfler 	// TODO: unregister connection with server
123434c72144SAxel Dörfler 	// TODO: we should just send a notification, instead of republishing all
123534c72144SAxel Dörfler 	// endpoints
123676669a29Sbeveloper 	List<media_output> outlist;
123776669a29Sbeveloper 	List<media_input> inlist;
12389e9417d2Sbeveloper 	media_node sourcenode;
12399e9417d2Sbeveloper 	media_node destnode;
124034c72144SAxel Dörfler 	if (GetNodeFor(source_nodeid, &sourcenode) == B_OK) {
124165b73ae4SMarcus Overhagen 		if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
1242332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::Disconnect: source_nodeid %" B_PRId32
1243332cc6bcSAxel Dörfler 				" is not a B_BUFFER_PRODUCER\n", source_nodeid);
124465b73ae4SMarcus Overhagen 		}
124534c72144SAxel Dörfler 		if (MediaRosterEx(this)->GetAllOutputs(sourcenode , &outlist) == B_OK)
12468b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishOutputs(sourcenode , &outlist);
12479e9417d2Sbeveloper 		ReleaseNode(sourcenode);
12484f09fa2fSbeveloper 	} else {
1249332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Disconnect: GetNodeFor source_nodeid %" B_PRId32
1250332cc6bcSAxel Dörfler 			" failed\n", source_nodeid);
12514f09fa2fSbeveloper 	}
125234c72144SAxel Dörfler 	if (GetNodeFor(destination_nodeid, &destnode) == B_OK) {
125365b73ae4SMarcus Overhagen 		if (!(destnode.kind & B_BUFFER_CONSUMER)) {
1254332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::Disconnect: destination_nodeid %" B_PRId32
1255332cc6bcSAxel Dörfler 				" is not a B_BUFFER_CONSUMER\n", destination_nodeid);
125665b73ae4SMarcus Overhagen 		}
125734c72144SAxel Dörfler 		if (MediaRosterEx(this)->GetAllInputs(destnode , &inlist) == B_OK)
12588b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishInputs(destnode, &inlist);
12599e9417d2Sbeveloper 		ReleaseNode(destnode);
12604f09fa2fSbeveloper 	} else {
1261332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Disconnect: GetNodeFor destination_nodeid %"
1262332cc6bcSAxel Dörfler 			B_PRId32 " failed\n", destination_nodeid);
12634f09fa2fSbeveloper 	}
12649e9417d2Sbeveloper 
12659e9417d2Sbeveloper 	// send a notification
12669e9417d2Sbeveloper 	BPrivate::media::notifications::ConnectionBroken(source, destination);
12679e9417d2Sbeveloper 
126834c72144SAxel Dörfler 	return rv1 != B_OK || rv2 != B_OK ? B_ERROR : B_OK;
126952a38012Sejakowatz }
127052a38012Sejakowatz 
127134c72144SAxel Dörfler 
127265b73ae4SMarcus Overhagen status_t
127365b73ae4SMarcus Overhagen BMediaRoster::Disconnect(const media_output& output, const media_input& input)
127465b73ae4SMarcus Overhagen {
127565b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(output.node.node)) {
1276332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: output.node.node %" B_PRId32
1277332cc6bcSAxel Dörfler 			" invalid\n", output.node.node);
127865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
127965b73ae4SMarcus Overhagen 	}
128065b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(input.node.node)) {
1281332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.node.node %" B_PRId32
1282332cc6bcSAxel Dörfler 			" invalid\n", input.node.node);
128365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
128465b73ae4SMarcus Overhagen 	}
128565b73ae4SMarcus Overhagen 	if (!(output.node.kind & B_BUFFER_PRODUCER)) {
1286332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: output.node.kind 0x%" B_PRIx32
1287332cc6bcSAxel Dörfler 			" is no B_BUFFER_PRODUCER\n", output.node.kind);
128865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
128965b73ae4SMarcus Overhagen 	}
129065b73ae4SMarcus Overhagen 	if (!(input.node.kind & B_BUFFER_CONSUMER)) {
1291332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.node.kind 0x%" B_PRIx32
1292332cc6bcSAxel Dörfler 			" is no B_BUFFER_PRODUCER\n", input.node.kind);
129365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
129465b73ae4SMarcus Overhagen 	}
129565b73ae4SMarcus Overhagen 	if (input.source.port != output.source.port) {
1296332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.source.port %" B_PRId32
1297332cc6bcSAxel Dörfler 			" doesn't match output.source.port %" B_PRId32 "\n",
1298332cc6bcSAxel Dörfler 			input.source.port, output.source.port);
129965b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
130065b73ae4SMarcus Overhagen 	}
130165b73ae4SMarcus Overhagen 	if (input.source.id != output.source.id) {
1302332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.source.id %" B_PRId32
1303332cc6bcSAxel Dörfler 			" doesn't match output.source.id %" B_PRId32 "\n", input.source.id,
1304332cc6bcSAxel Dörfler 			output.source.id);
130565b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
130665b73ae4SMarcus Overhagen 	}
130765b73ae4SMarcus Overhagen 	if (input.destination.port != output.destination.port) {
1308332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.destination.port %" B_PRId32
1309332cc6bcSAxel Dörfler 			" doesn't match output.destination.port %" B_PRId32 "\n",
1310332cc6bcSAxel Dörfler 			input.destination.port, output.destination.port);
131165b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
131265b73ae4SMarcus Overhagen 	}
131365b73ae4SMarcus Overhagen 	if (input.destination.id != output.destination.id) {
1314332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.destination.id %" B_PRId32
1315332cc6bcSAxel Dörfler 			" doesn't match output.destination.id %" B_PRId32 "\n",
1316332cc6bcSAxel Dörfler 			input.destination.id, output.destination.id);
131765b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
131865b73ae4SMarcus Overhagen 	}
131934c72144SAxel Dörfler 
132034c72144SAxel Dörfler 	return Disconnect(output.node.node, output.source, input.node.node,
132134c72144SAxel Dörfler 		input.destination);
132265b73ae4SMarcus Overhagen }
132365b73ae4SMarcus Overhagen 
132452a38012Sejakowatz 
132552a38012Sejakowatz status_t
132634c72144SAxel Dörfler BMediaRoster::StartNode(const media_node& node, bigtime_t atPerformanceTime)
132752a38012Sejakowatz {
132852a38012Sejakowatz 	CALLED();
13299e9417d2Sbeveloper 	if (node.node <= 0)
133052a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
133152a38012Sejakowatz 
1332332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StartNode, node %" B_PRId32 ", at perf %" B_PRId64
1333332cc6bcSAxel Dörfler 		"\n", node.node, atPerformanceTime);
13340e21b167Sbeveloper 
13356396865dSbeveloper 	node_start_command command;
133634c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
133752a38012Sejakowatz 
13386396865dSbeveloper 	return SendToPort(node.port, NODE_START, &command, sizeof(command));
133952a38012Sejakowatz }
134052a38012Sejakowatz 
134152a38012Sejakowatz 
134252a38012Sejakowatz status_t
134334c72144SAxel Dörfler BMediaRoster::StopNode(const media_node& node, bigtime_t atPerformanceTime,
134452a38012Sejakowatz 	bool immediate)
134552a38012Sejakowatz {
134652a38012Sejakowatz 	CALLED();
134740f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
134852a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
134952a38012Sejakowatz 
1350332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StopNode, node %" B_PRId32 ", at perf %" B_PRId64
1351332cc6bcSAxel Dörfler 		" %s\n", node.node, atPerformanceTime, immediate ? "NOW" : "");
13520e21b167Sbeveloper 
13536396865dSbeveloper 	node_stop_command command;
135434c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
13556396865dSbeveloper 	command.immediate = immediate;
135652a38012Sejakowatz 
13576396865dSbeveloper 	return SendToPort(node.port, NODE_STOP, &command, sizeof(command));
135852a38012Sejakowatz }
135952a38012Sejakowatz 
136052a38012Sejakowatz 
136152a38012Sejakowatz status_t
136234c72144SAxel Dörfler BMediaRoster::SeekNode(const media_node& node, bigtime_t toMediaTime,
136334c72144SAxel Dörfler 	bigtime_t atPerformanceTime)
136452a38012Sejakowatz {
136552a38012Sejakowatz 	CALLED();
136640f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
136752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
136852a38012Sejakowatz 
1369332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SeekNode, node %" B_PRId32 ", at perf %" B_PRId64
1370332cc6bcSAxel Dörfler 		", to perf %" B_PRId64 "\n", node.node, atPerformanceTime, toMediaTime);
13710e21b167Sbeveloper 
13726396865dSbeveloper 	node_seek_command command;
137334c72144SAxel Dörfler 	command.media_time = toMediaTime;
137434c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
137552a38012Sejakowatz 
13766396865dSbeveloper 	return SendToPort(node.port, NODE_SEEK, &command, sizeof(command));
137752a38012Sejakowatz }
137852a38012Sejakowatz 
137952a38012Sejakowatz 
138052a38012Sejakowatz status_t
138134c72144SAxel Dörfler BMediaRoster::StartTimeSource(const media_node& node, bigtime_t atRealTime)
138252a38012Sejakowatz {
138352a38012Sejakowatz 	CALLED();
138460f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
138534c72144SAxel Dörfler 		// TODO: debug this
1386332cc6bcSAxel Dörfler 		//ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " is system timesource\n", node.node);
138760f15390Sbeveloper 		return B_OK;
138860f15390Sbeveloper 	}
138992e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
139034c72144SAxel Dörfler //		// TODO: debug this
1391332cc6bcSAxel Dörfler //		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " is shadow timesource\n", node.node);
139292e575c1Sbeveloper //		return B_OK;
139392e575c1Sbeveloper //	}
139440f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1395332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " invalid\n",
139634c72144SAxel Dörfler 			node.node);
139752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
13980e21b167Sbeveloper 	}
1399332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1400332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32
1401332cc6bcSAxel Dörfler 			" is no timesource\n", node.node);
1402332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1403332cc6bcSAxel Dörfler 	}
14040e21b167Sbeveloper 
1405332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StartTimeSource, node %" B_PRId32 ", at real %"
1406332cc6bcSAxel Dörfler 		B_PRId64 "\n", node.node, atRealTime);
140752a38012Sejakowatz 
140852a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
140952a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_START;
141034c72144SAxel Dörfler 	msg.real_time = atRealTime;
141152a38012Sejakowatz 
141252a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
141352a38012Sejakowatz }
141452a38012Sejakowatz 
141552a38012Sejakowatz 
141652a38012Sejakowatz status_t
141734c72144SAxel Dörfler BMediaRoster::StopTimeSource(const media_node& node, bigtime_t atRealTime,
141852a38012Sejakowatz 	bool immediate)
141952a38012Sejakowatz {
142052a38012Sejakowatz 	CALLED();
142160f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
142234c72144SAxel Dörfler 		// TODO: debug this
14235ac4fbd7Sbeveloper 		//ERROR("BMediaRoster::StopTimeSource node %ld is system timesource\n", node.node);
142460f15390Sbeveloper 		return B_OK;
142560f15390Sbeveloper 	}
142692e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
142734c72144SAxel Dörfler //		// TODO: debug this
142892e575c1Sbeveloper //		ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node);
142992e575c1Sbeveloper //		return B_OK;
143092e575c1Sbeveloper //	}
143140f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1432332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StopTimeSource node %" B_PRId32 " invalid\n",
143334c72144SAxel Dörfler 			node.node);
143452a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
14350e21b167Sbeveloper 	}
1436332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1437332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StopTimeSource node %" B_PRId32 " is no "
1438332cc6bcSAxel Dörfler 			"timesource\n", node.node);
1439332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1440332cc6bcSAxel Dörfler 	}
14410e21b167Sbeveloper 
1442332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StopTimeSource, node %" B_PRId32 ", at real %" B_PRId64
1443332cc6bcSAxel Dörfler 		" %s\n", node.node, atRealTime, immediate ? "NOW" : "");
144452a38012Sejakowatz 
144552a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
144634c72144SAxel Dörfler 	msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY
144734c72144SAxel Dörfler 		: BTimeSource::B_TIMESOURCE_STOP;
144834c72144SAxel Dörfler 	msg.real_time = atRealTime;
144952a38012Sejakowatz 
145052a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
145152a38012Sejakowatz }
145252a38012Sejakowatz 
145352a38012Sejakowatz 
145452a38012Sejakowatz status_t
145552a38012Sejakowatz BMediaRoster::SeekTimeSource(const media_node& node,
145634c72144SAxel Dörfler 	bigtime_t toPerformanceTime, bigtime_t atRealTime)
145752a38012Sejakowatz {
145852a38012Sejakowatz 	CALLED();
145960f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
146034c72144SAxel Dörfler 		// TODO: debug this
14615ac4fbd7Sbeveloper 		// ERROR("BMediaRoster::SeekTimeSource node %ld is system timesource\n", node.node);
146260f15390Sbeveloper 		// you can't seek the system time source, but
146360f15390Sbeveloper 		// returning B_ERROR would break StampTV
146460f15390Sbeveloper 		return B_OK;
146560f15390Sbeveloper 	}
146692e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
146734c72144SAxel Dörfler //		// TODO: debug this
146892e575c1Sbeveloper //		ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node);
146992e575c1Sbeveloper //		return B_OK;
147092e575c1Sbeveloper //	}
147140f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1472332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SeekTimeSource node %" B_PRId32 " invalid\n",
147334c72144SAxel Dörfler 			node.node);
147452a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
14750e21b167Sbeveloper 	}
1476332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1477332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SeekTimeSource node %" B_PRId32
1478332cc6bcSAxel Dörfler 			" is no timesource\n", node.node);
1479332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1480332cc6bcSAxel Dörfler 	}
14810e21b167Sbeveloper 
1482332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SeekTimeSource, node %" B_PRId32 ", at real %" B_PRId64
1483332cc6bcSAxel Dörfler 		", to perf %" B_PRId64 "\n", node.node, atRealTime, toPerformanceTime);
148452a38012Sejakowatz 
148552a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
148652a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_SEEK;
148734c72144SAxel Dörfler 	msg.real_time = atRealTime;
148834c72144SAxel Dörfler 	msg.performance_time = toPerformanceTime;
148952a38012Sejakowatz 
149052a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
149152a38012Sejakowatz }
149252a38012Sejakowatz 
149352a38012Sejakowatz 
149452a38012Sejakowatz status_t
149534c72144SAxel Dörfler BMediaRoster::SyncToNode(const media_node& node, bigtime_t atTime,
149652a38012Sejakowatz 	bigtime_t timeout)
149752a38012Sejakowatz {
149875486484SDario Casalinuovo 	TRACE("BMediaRoster::SyncToNode, node %" B_PRId32 ", at real %" B_PRId64
149975486484SDario Casalinuovo 		", at timeout %" B_PRId64 "\n", node.node, atTime, timeout);
150075486484SDario Casalinuovo 	if (IS_INVALID_NODE(node))
150175486484SDario Casalinuovo 		return B_MEDIA_BAD_NODE;
150275486484SDario Casalinuovo 
150375486484SDario Casalinuovo 	port_id waitPort = create_port(1, "SyncToNode wait port");
150475486484SDario Casalinuovo 	if (waitPort < B_OK)
150575486484SDario Casalinuovo 		return waitPort;
150675486484SDario Casalinuovo 
150775486484SDario Casalinuovo 	node_sync_to_request request;
150875486484SDario Casalinuovo 	node_sync_to_reply reply;
150975486484SDario Casalinuovo 	request.performance_time = atTime;
151075486484SDario Casalinuovo 	request.port = waitPort;
151175486484SDario Casalinuovo 
151275486484SDario Casalinuovo 	status_t status = QueryPort(node.port, NODE_SYNC_TO, &request,
151375486484SDario Casalinuovo 		sizeof(request), &reply, sizeof(reply));
151475486484SDario Casalinuovo 
151575486484SDario Casalinuovo 	if (status == B_OK) {
151675486484SDario Casalinuovo 		ssize_t readSize = read_port_etc(waitPort, NULL, &status,
151775486484SDario Casalinuovo 			sizeof(status), B_TIMEOUT, timeout);
151875486484SDario Casalinuovo 		if (readSize < 0)
151975486484SDario Casalinuovo 			status = readSize;
152075486484SDario Casalinuovo 	}
152175486484SDario Casalinuovo 	close_port(waitPort);
152275486484SDario Casalinuovo 	delete_port(waitPort);
152375486484SDario Casalinuovo 	return status;
152452a38012Sejakowatz }
152552a38012Sejakowatz 
152652a38012Sejakowatz 
152752a38012Sejakowatz status_t
152834c72144SAxel Dörfler BMediaRoster::SetRunModeNode(const media_node& node, BMediaNode::run_mode mode)
152952a38012Sejakowatz {
1530332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetRunModeNode, node %" B_PRId32 ", mode %d\n",
1531332cc6bcSAxel Dörfler 		node.node, mode);
153240f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
153352a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
153452a38012Sejakowatz 
1535dfb2ad61Sbeveloper 	node_set_run_mode_command msg;
153652a38012Sejakowatz 	msg.mode = mode;
153752a38012Sejakowatz 
153852a38012Sejakowatz 	return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg));
153952a38012Sejakowatz }
154052a38012Sejakowatz 
154152a38012Sejakowatz 
154252a38012Sejakowatz status_t
154352a38012Sejakowatz BMediaRoster::PrerollNode(const media_node& node)
154452a38012Sejakowatz {
154552a38012Sejakowatz 	CALLED();
154640f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
154752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
154852a38012Sejakowatz 
154952a38012Sejakowatz 	char dummy;
155052a38012Sejakowatz 	return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy));
155152a38012Sejakowatz }
155252a38012Sejakowatz 
155352a38012Sejakowatz 
155452a38012Sejakowatz status_t
155534c72144SAxel Dörfler BMediaRoster::RollNode(const media_node& node, bigtime_t startPerformance,
155634c72144SAxel Dörfler 	bigtime_t stopPerformance, bigtime_t atMediaTime)
155752a38012Sejakowatz {
155814896b93SDario Casalinuovo 	CALLED();
155914896b93SDario Casalinuovo 	if (IS_INVALID_NODE(node))
156014896b93SDario Casalinuovo 		return B_MEDIA_BAD_NODE;
156114896b93SDario Casalinuovo 
156214896b93SDario Casalinuovo 	TRACE("BMediaRoster::RollNode, node %" B_PRId32 ", at start perf %"
156314896b93SDario Casalinuovo 		B_PRId64 ", at stop perf %" B_PRId64 ", at media time %"
156414896b93SDario Casalinuovo 		B_PRId64 "\n", node.node, startPerformance,
156514896b93SDario Casalinuovo 		stopPerformance, atMediaTime);
156614896b93SDario Casalinuovo 
156714896b93SDario Casalinuovo 	node_roll_command command;
156814896b93SDario Casalinuovo 	command.start_performance_time = startPerformance;
156914896b93SDario Casalinuovo 	command.stop_performance_time = stopPerformance;
157014896b93SDario Casalinuovo 	command.seek_media_time = atMediaTime;
157114896b93SDario Casalinuovo 
157214896b93SDario Casalinuovo 	return write_port(node.port, NODE_ROLL, &command, sizeof(command));
157352a38012Sejakowatz }
157452a38012Sejakowatz 
157552a38012Sejakowatz 
157652a38012Sejakowatz status_t
157752a38012Sejakowatz BMediaRoster::SetProducerRunModeDelay(const media_node& node,
157834c72144SAxel Dörfler 	bigtime_t delay, BMediaNode::run_mode mode)
157952a38012Sejakowatz {
1580332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetProducerRunModeDelay, node %" B_PRId32 ", delay %"
1581332cc6bcSAxel Dörfler 		B_PRId64 ", mode %d\n", node.node, delay, mode);
158260f15390Sbeveloper 	if (IS_INVALID_NODE(node))
158360f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
158460f15390Sbeveloper 	if ((node.kind & B_BUFFER_PRODUCER) == 0)
158560f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
158660f15390Sbeveloper 
158760f15390Sbeveloper 	producer_set_run_mode_delay_command command;
158860f15390Sbeveloper 	command.mode = mode;
158960f15390Sbeveloper 	command.delay = delay;
159060f15390Sbeveloper 
159134c72144SAxel Dörfler 	return SendToPort(node.port, PRODUCER_SET_RUN_MODE_DELAY, &command,
159234c72144SAxel Dörfler 		sizeof(command));
159352a38012Sejakowatz }
159452a38012Sejakowatz 
159552a38012Sejakowatz 
159652a38012Sejakowatz status_t
159734c72144SAxel Dörfler BMediaRoster::SetProducerRate(const media_node& producer, int32 numer,
159852a38012Sejakowatz 	int32 denom)
159952a38012Sejakowatz {
160052a38012Sejakowatz 	CALLED();
160140f36b03Sbeveloper 	if (IS_INVALID_NODE(producer))
160252a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
160352a38012Sejakowatz 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
160452a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
160552a38012Sejakowatz 
16066cafce94SAxel Dörfler 	producer_set_play_rate_request request;
16076cafce94SAxel Dörfler 	request.numer = numer;
16086cafce94SAxel Dörfler 	request.denom = denom;
16096cafce94SAxel Dörfler 	status_t status = write_port(producer.node, PRODUCER_SET_PLAY_RATE,
16106cafce94SAxel Dörfler 		&request, sizeof(request));
16116cafce94SAxel Dörfler 	if (status != B_OK)
16126cafce94SAxel Dörfler 		return status;
161352a38012Sejakowatz 
16146cafce94SAxel Dörfler 	producer_set_play_rate_reply reply;
16156cafce94SAxel Dörfler 	int32 code;
16166cafce94SAxel Dörfler 	status = read_port(request.reply_port, &code, &reply, sizeof(reply));
16176cafce94SAxel Dörfler 
16186cafce94SAxel Dörfler 	return status < B_OK ? status : reply.result;
161952a38012Sejakowatz }
162052a38012Sejakowatz 
162152a38012Sejakowatz 
162234c72144SAxel Dörfler /*!	Nodes will have available inputs/outputs as long as they are capable
162334c72144SAxel Dörfler 	of accepting more connections. The node may create an additional
162434c72144SAxel Dörfler 	output or input as the currently available is taken into usage.
162534c72144SAxel Dörfler */
162652a38012Sejakowatz status_t
162752a38012Sejakowatz BMediaRoster::GetLiveNodeInfo(const media_node& node,
162852a38012Sejakowatz 	live_node_info* out_live_info)
162952a38012Sejakowatz {
16309e9417d2Sbeveloper 	CALLED();
16319e9417d2Sbeveloper 	if (out_live_info == NULL)
16329e9417d2Sbeveloper 		return B_BAD_VALUE;
163340f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
16349e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
16359e9417d2Sbeveloper 
16369e9417d2Sbeveloper 	server_get_live_node_info_request request;
16379e9417d2Sbeveloper 	server_get_live_node_info_reply reply;
16389e9417d2Sbeveloper 	status_t rv;
16399e9417d2Sbeveloper 
16409e9417d2Sbeveloper 	request.node = node;
16419e9417d2Sbeveloper 
164234c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request),
164334c72144SAxel Dörfler 		&reply, sizeof(reply));
16449e9417d2Sbeveloper 	if (rv != B_OK)
16459e9417d2Sbeveloper 		return rv;
16469e9417d2Sbeveloper 
16479e9417d2Sbeveloper 	*out_live_info = reply.live_info;
16489e9417d2Sbeveloper 	return B_OK;
164952a38012Sejakowatz }
165052a38012Sejakowatz 
165152a38012Sejakowatz 
165252a38012Sejakowatz status_t
16539c3b4706SAxel Dörfler BMediaRoster::GetLiveNodes(live_node_info* liveNodes, int32* _totalCount,
165434c72144SAxel Dörfler 	const media_format* hasInput, const media_format* hasOutput,
165534c72144SAxel Dörfler 	const char* name, uint64 nodeKinds)
165652a38012Sejakowatz {
16579e9417d2Sbeveloper 	CALLED();
16589c3b4706SAxel Dörfler 	if (liveNodes == NULL || _totalCount == NULL || *_totalCount <= 0)
16599e9417d2Sbeveloper 		return B_BAD_VALUE;
16609e9417d2Sbeveloper 
166134c72144SAxel Dörfler 	// TODO: we also support the wildcard search as GetDormantNodes does.
166234c72144SAxel Dörfler 	// This needs to be documented
16639e9417d2Sbeveloper 
16649e9417d2Sbeveloper 	server_get_live_nodes_request request;
16659c3b4706SAxel Dörfler 	request.team = BPrivate::current_team();
16669e9417d2Sbeveloper 
16679c3b4706SAxel Dörfler 	request.max_count = *_totalCount;
166834c72144SAxel Dörfler 	request.has_input = hasInput != NULL;
166934c72144SAxel Dörfler 	if (hasInput != NULL) {
167034c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
16719c3b4706SAxel Dörfler 		request.input_format = *hasInput;
167234c72144SAxel Dörfler 	}
167334c72144SAxel Dörfler 	request.has_output = hasOutput != NULL;
167434c72144SAxel Dörfler 	if (hasOutput != NULL) {
167534c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
16769c3b4706SAxel Dörfler 		request.output_format = *hasOutput;
167734c72144SAxel Dörfler 	}
167834c72144SAxel Dörfler 	request.has_name = name != NULL;
16799c3b4706SAxel Dörfler 	if (name != NULL)
16809c3b4706SAxel Dörfler 		strlcpy(request.name, name, sizeof(request.name));
168134c72144SAxel Dörfler 	request.require_kinds = nodeKinds;
16829e9417d2Sbeveloper 
16839c3b4706SAxel Dörfler 	server_get_live_nodes_reply reply;
16849c3b4706SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_LIVE_NODES, &request,
16859c3b4706SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
16869c3b4706SAxel Dörfler 	if (status != B_OK) {
16879c3b4706SAxel Dörfler 		ERROR("BMediaRoster::GetLiveNodes failed querying server: %s\n",
16889c3b4706SAxel Dörfler 			strerror(status));
168934c72144SAxel Dörfler 		*_totalCount = 0;
16909c3b4706SAxel Dörfler 		return status;
16919e9417d2Sbeveloper 	}
16929e9417d2Sbeveloper 
16939c3b4706SAxel Dörfler 	const live_node_info* info;
16949c3b4706SAxel Dörfler 	if (reply.area >= 0)
16959c3b4706SAxel Dörfler 		info = (live_node_info*)reply.address;
16969c3b4706SAxel Dörfler 	else
16979c3b4706SAxel Dörfler 		info = reply.live_info;
16989e9417d2Sbeveloper 
16999c3b4706SAxel Dörfler 	for (int32 i = 0; i < reply.count; i++)
17009c3b4706SAxel Dörfler 		liveNodes[i] = info[i];
17019c3b4706SAxel Dörfler 
17029c3b4706SAxel Dörfler 	if (reply.area >= 0)
17039e9417d2Sbeveloper 		delete_area(reply.area);
170452a38012Sejakowatz 
170534c72144SAxel Dörfler 	*_totalCount = reply.count;
17069e9417d2Sbeveloper 	return B_OK;
17079e9417d2Sbeveloper }
17089e9417d2Sbeveloper 
170952a38012Sejakowatz 
171052a38012Sejakowatz status_t
171152a38012Sejakowatz BMediaRoster::GetFreeInputsFor(const media_node& node,
171234c72144SAxel Dörfler 	media_input * out_free_inputs, int32 buf_num_inputs,
171334c72144SAxel Dörfler 	int32 * out_total_count, media_type filter_type)
171452a38012Sejakowatz {
17153620737cSbeveloper 	CALLED();
17165ac4fbd7Sbeveloper 	if (IS_INVALID_NODE(node)) {
1717332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::GetFreeInputsFor: node %" B_PRId32 ", port %"
1718332cc6bcSAxel Dörfler 			B_PRId32 " invalid\n", node.node, node.port);
17193620737cSbeveloper 		return B_MEDIA_BAD_NODE;
17205ac4fbd7Sbeveloper 	}
17215ac4fbd7Sbeveloper 	if ((node.kind & B_BUFFER_CONSUMER) == 0) {
1722332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::GetFreeInputsFor: node %" B_PRId32 ", port %"
1723332cc6bcSAxel Dörfler 			B_PRId32 " is not a consumer\n", node.node, node.port);
17245ac4fbd7Sbeveloper 		return B_MEDIA_BAD_NODE;
17255ac4fbd7Sbeveloper 	}
17263620737cSbeveloper 	if (out_free_inputs == NULL || out_total_count == NULL)
17273620737cSbeveloper 		return B_BAD_VALUE;
17283620737cSbeveloper 
172976669a29Sbeveloper 	List<media_input> list;
17303620737cSbeveloper 	media_input *input;
17313620737cSbeveloper 	status_t rv;
17323620737cSbeveloper 
17331299bfb2Sbeveloper 	*out_total_count = 0;
17341299bfb2Sbeveloper 
17358b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
17363620737cSbeveloper 	if (B_OK != rv)
17373620737cSbeveloper 		return rv;
17383620737cSbeveloper 
1739332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetFreeInputsFor node %" B_PRId32 ", max %" B_PRId32
1740332cc6bcSAxel Dörfler 		", filter-type %" B_PRId32 "\n", node.node, buf_num_inputs,
1741332cc6bcSAxel Dörfler 		filter_type);
17425ac4fbd7Sbeveloper 
174376669a29Sbeveloper 	int32 i;
1744b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
174534c72144SAxel Dörfler 		if (filter_type != B_MEDIA_UNKNOWN_TYPE
174634c72144SAxel Dörfler 			&& filter_type != input->format.type) {
174734c72144SAxel Dörfler 			// media_type used, but doesn't match
174834c72144SAxel Dörfler 			continue;
174934c72144SAxel Dörfler 		}
175034c72144SAxel Dörfler 		if (input->source != media_source::null) {
175134c72144SAxel Dörfler 			// consumer source already connected
175234c72144SAxel Dörfler 			continue;
175334c72144SAxel Dörfler 		}
175434c72144SAxel Dörfler 
17553620737cSbeveloper 		out_free_inputs[i] = *input;
17563620737cSbeveloper 		*out_total_count += 1;
17573620737cSbeveloper 		buf_num_inputs -= 1;
17585ac4fbd7Sbeveloper 		#if DEBUG >= 3
17595ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input", out_free_inputs[i]);
17605ac4fbd7Sbeveloper 		#endif
17613620737cSbeveloper 		if (buf_num_inputs == 0)
17623620737cSbeveloper 			break;
1763b65a0ac5SJérôme Duval 		i++;
17643620737cSbeveloper 	}
17653620737cSbeveloper 
17668b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
17673620737cSbeveloper 	return B_OK;
176852a38012Sejakowatz }
176952a38012Sejakowatz 
177052a38012Sejakowatz 
177152a38012Sejakowatz status_t
177252a38012Sejakowatz BMediaRoster::GetConnectedInputsFor(const media_node& node,
177334c72144SAxel Dörfler 	media_input* out_active_inputs, int32 buf_num_inputs,
177452a38012Sejakowatz 	int32* out_total_count)
177552a38012Sejakowatz {
17763620737cSbeveloper 	CALLED();
177740f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
17783620737cSbeveloper 		return B_MEDIA_BAD_NODE;
17793620737cSbeveloper 	if (out_active_inputs == NULL || out_total_count == NULL)
17803620737cSbeveloper 		return B_BAD_VALUE;
17813620737cSbeveloper 
178276669a29Sbeveloper 	List<media_input> list;
17833620737cSbeveloper 	media_input *input;
17843620737cSbeveloper 	status_t rv;
17853620737cSbeveloper 
17861299bfb2Sbeveloper 	*out_total_count = 0;
17871299bfb2Sbeveloper 
17888b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
17893620737cSbeveloper 	if (B_OK != rv)
17903620737cSbeveloper 		return rv;
17913620737cSbeveloper 
1792332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetConnectedInputsFor node %" B_PRId32 ", max %"
1793332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, buf_num_inputs);
17945ac4fbd7Sbeveloper 
179576669a29Sbeveloper 	int32 i;
1796b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
17973620737cSbeveloper 		if (input->source == media_source::null)
17983620737cSbeveloper 			continue; // consumer source not connected
17993620737cSbeveloper 		out_active_inputs[i] = *input;
18003620737cSbeveloper 		*out_total_count += 1;
18013620737cSbeveloper 		buf_num_inputs -= 1;
18025ac4fbd7Sbeveloper 		#if DEBUG >= 3
18035ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_active_inputs[i]);
18045ac4fbd7Sbeveloper 		#endif
18053620737cSbeveloper 		if (buf_num_inputs == 0)
18063620737cSbeveloper 			break;
1807b65a0ac5SJérôme Duval 		i++;
18083620737cSbeveloper 	}
18093620737cSbeveloper 
18108b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
18113620737cSbeveloper 	return B_OK;
181252a38012Sejakowatz }
181352a38012Sejakowatz 
181452a38012Sejakowatz 
181552a38012Sejakowatz status_t
181634c72144SAxel Dörfler BMediaRoster::GetAllInputsFor(const media_node& node, media_input* out_inputs,
181734c72144SAxel Dörfler 	int32 buf_num_inputs, int32* out_total_count)
181852a38012Sejakowatz {
181952a38012Sejakowatz 	CALLED();
182040f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
182152a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
182252a38012Sejakowatz 	if (out_inputs == NULL || out_total_count == NULL)
182352a38012Sejakowatz 		return B_BAD_VALUE;
182452a38012Sejakowatz 
182576669a29Sbeveloper 	List<media_input> list;
18263620737cSbeveloper 	media_input *input;
182752a38012Sejakowatz 	status_t rv;
182852a38012Sejakowatz 
18291299bfb2Sbeveloper 	*out_total_count = 0;
18301299bfb2Sbeveloper 
18318b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
18323620737cSbeveloper 	if (B_OK != rv)
18333620737cSbeveloper 		return rv;
18343620737cSbeveloper 
1835332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetAllInputsFor node %" B_PRId32 ", max %" B_PRId32
1836332cc6bcSAxel Dörfler 		"\n", node.node, buf_num_inputs);
18375ac4fbd7Sbeveloper 
183876669a29Sbeveloper 	int32 i;
183976669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&input); i++) {
18403620737cSbeveloper 		out_inputs[i] = *input;
184152a38012Sejakowatz 		*out_total_count += 1;
18423620737cSbeveloper 		buf_num_inputs -= 1;
18435ac4fbd7Sbeveloper 		#if DEBUG >= 3
18445ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_inputs[i]);
18455ac4fbd7Sbeveloper 		#endif
18463620737cSbeveloper 		if (buf_num_inputs == 0)
18473620737cSbeveloper 			break;
184852a38012Sejakowatz 	}
184952a38012Sejakowatz 
18508b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
18513620737cSbeveloper 	return B_OK;
185252a38012Sejakowatz }
185352a38012Sejakowatz 
185452a38012Sejakowatz 
185552a38012Sejakowatz status_t
185652a38012Sejakowatz BMediaRoster::GetFreeOutputsFor(const media_node& node,
185734c72144SAxel Dörfler 	media_output* out_free_outputs, int32 buf_num_outputs,
185834c72144SAxel Dörfler 	int32* out_total_count, media_type filter_type)
185952a38012Sejakowatz {
18603620737cSbeveloper 	CALLED();
186140f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
18623620737cSbeveloper 		return B_MEDIA_BAD_NODE;
18633620737cSbeveloper 	if (out_free_outputs == NULL || out_total_count == NULL)
18643620737cSbeveloper 		return B_BAD_VALUE;
18653620737cSbeveloper 
186676669a29Sbeveloper 	List<media_output> list;
18673620737cSbeveloper 	media_output *output;
18683620737cSbeveloper 	status_t rv;
18693620737cSbeveloper 
18701299bfb2Sbeveloper 	*out_total_count = 0;
18711299bfb2Sbeveloper 
18728b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
18733620737cSbeveloper 	if (B_OK != rv)
18743620737cSbeveloper 		return rv;
18753620737cSbeveloper 
1876332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetFreeOutputsFor node %" B_PRId32 ", max %"
1877332cc6bcSAxel Dörfler 		B_PRId32 ", filter-type %" B_PRId32 "\n", node.node, buf_num_outputs,
1878332cc6bcSAxel Dörfler 		filter_type);
18795ac4fbd7Sbeveloper 
188076669a29Sbeveloper 	int32 i;
1881b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
188234c72144SAxel Dörfler 		if (filter_type != B_MEDIA_UNKNOWN_TYPE
188334c72144SAxel Dörfler 			&& filter_type != output->format.type) {
188434c72144SAxel Dörfler 			// media_type used, but doesn't match
188534c72144SAxel Dörfler 			continue;
188634c72144SAxel Dörfler 		}
188734c72144SAxel Dörfler 		if (output->destination != media_destination::null) {
188834c72144SAxel Dörfler 			// producer destination already connected
188934c72144SAxel Dörfler 			continue;
189034c72144SAxel Dörfler 		}
189134c72144SAxel Dörfler 
18923620737cSbeveloper 		out_free_outputs[i] = *output;
18933620737cSbeveloper 		*out_total_count += 1;
18943620737cSbeveloper 		buf_num_outputs -= 1;
18955ac4fbd7Sbeveloper 		#if DEBUG >= 3
18965ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_free_outputs[i]);
18975ac4fbd7Sbeveloper 		#endif
18983620737cSbeveloper 		if (buf_num_outputs == 0)
18993620737cSbeveloper 			break;
1900b65a0ac5SJérôme Duval 		i++;
19013620737cSbeveloper 	}
19023620737cSbeveloper 
19038b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
19043620737cSbeveloper 	return B_OK;
190552a38012Sejakowatz }
190652a38012Sejakowatz 
190752a38012Sejakowatz 
190852a38012Sejakowatz status_t
190952a38012Sejakowatz BMediaRoster::GetConnectedOutputsFor(const media_node& node,
191034c72144SAxel Dörfler 	media_output* out_active_outputs, int32 buf_num_outputs,
191152a38012Sejakowatz 	int32* out_total_count)
191252a38012Sejakowatz {
19133620737cSbeveloper 	CALLED();
191440f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
19153620737cSbeveloper 		return B_MEDIA_BAD_NODE;
19163620737cSbeveloper 	if (out_active_outputs == NULL || out_total_count == NULL)
19173620737cSbeveloper 		return B_BAD_VALUE;
19183620737cSbeveloper 
191976669a29Sbeveloper 	List<media_output> list;
19203620737cSbeveloper 	media_output *output;
19213620737cSbeveloper 	status_t rv;
19223620737cSbeveloper 
19231299bfb2Sbeveloper 	*out_total_count = 0;
19241299bfb2Sbeveloper 
19258b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
19263620737cSbeveloper 	if (B_OK != rv)
19273620737cSbeveloper 		return rv;
19283620737cSbeveloper 
1929332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetConnectedOutputsFor node %" B_PRId32 ", max %"
1930332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, buf_num_outputs);
19315ac4fbd7Sbeveloper 
193276669a29Sbeveloper 	int32 i;
1933b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
193434c72144SAxel Dörfler 		if (output->destination == media_destination::null) {
193534c72144SAxel Dörfler 			// producer destination not connected
193634c72144SAxel Dörfler 			continue;
193734c72144SAxel Dörfler 		}
19383620737cSbeveloper 		out_active_outputs[i] = *output;
19393620737cSbeveloper 		*out_total_count += 1;
19403620737cSbeveloper 		buf_num_outputs -= 1;
19415ac4fbd7Sbeveloper 		#if DEBUG >= 3
19425ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_active_outputs[i]);
19435ac4fbd7Sbeveloper 		#endif
19443620737cSbeveloper 		if (buf_num_outputs == 0)
19453620737cSbeveloper 			break;
1946b65a0ac5SJérôme Duval 		i++;
19473620737cSbeveloper 	}
19483620737cSbeveloper 
19498b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
19503620737cSbeveloper 	return B_OK;
195152a38012Sejakowatz }
195252a38012Sejakowatz 
195352a38012Sejakowatz 
195452a38012Sejakowatz status_t
195552a38012Sejakowatz BMediaRoster::GetAllOutputsFor(const media_node& node,
195634c72144SAxel Dörfler 	media_output* out_outputs, int32 buf_num_outputs, int32* out_total_count)
195752a38012Sejakowatz {
195852a38012Sejakowatz 	CALLED();
195940f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
196052a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
196152a38012Sejakowatz 	if (out_outputs == NULL || out_total_count == NULL)
196252a38012Sejakowatz 		return B_BAD_VALUE;
196352a38012Sejakowatz 
196476669a29Sbeveloper 	List<media_output> list;
19653620737cSbeveloper 	media_output *output;
196652a38012Sejakowatz 	status_t rv;
196752a38012Sejakowatz 
19681299bfb2Sbeveloper 	*out_total_count = 0;
19691299bfb2Sbeveloper 
19708b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
19713620737cSbeveloper 	if (B_OK != rv)
19723620737cSbeveloper 		return rv;
19733620737cSbeveloper 
1974332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetAllOutputsFor node %" B_PRId32 ", max %" B_PRId32
1975332cc6bcSAxel Dörfler 		"\n", node.node, buf_num_outputs);
19765ac4fbd7Sbeveloper 
197776669a29Sbeveloper 	int32 i;
197876669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&output); i++) {
19793620737cSbeveloper 		out_outputs[i] = *output;
198052a38012Sejakowatz 		*out_total_count += 1;
19813620737cSbeveloper 		buf_num_outputs -= 1;
19825ac4fbd7Sbeveloper 		#if DEBUG >= 3
19835ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_outputs[i]);
19845ac4fbd7Sbeveloper 		#endif
19853620737cSbeveloper 		if (buf_num_outputs == 0)
19863620737cSbeveloper 			break;
198752a38012Sejakowatz 	}
198852a38012Sejakowatz 
19898b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
19903620737cSbeveloper 	return B_OK;
199152a38012Sejakowatz }
199252a38012Sejakowatz 
199352a38012Sejakowatz 
199452a38012Sejakowatz status_t
199552a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger& where)
199652a38012Sejakowatz {
1997eae26d3dSbeveloper 	CALLED();
1998eae26d3dSbeveloper 	if (!where.IsValid()) {
19995ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
2000eae26d3dSbeveloper 		return B_BAD_VALUE;
2001eae26d3dSbeveloper 	}
200234c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, media_node::null,
200334c72144SAxel Dörfler 		B_MEDIA_WILDCARD);
200452a38012Sejakowatz }
200552a38012Sejakowatz 
200652a38012Sejakowatz 
200752a38012Sejakowatz status_t
200834c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType)
200952a38012Sejakowatz {
2010eae26d3dSbeveloper 	CALLED();
2011eae26d3dSbeveloper 	if (!where.IsValid()) {
20125ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
2013eae26d3dSbeveloper 		return B_BAD_VALUE;
2014eae26d3dSbeveloper 	}
201534c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(false,
201634c72144SAxel Dörfler 			notificationType)) {
20175ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
2018eae26d3dSbeveloper 		return B_BAD_VALUE;
2019eae26d3dSbeveloper 	}
202032afe10aSDario Casalinuovo 
202132afe10aSDario Casalinuovo 	// NOTE: we support only explicitly B_MEDIA_SERVER_STARTED/QUIT
202232afe10aSDario Casalinuovo 	// notifications. This should be cleared in documentation.
202332afe10aSDario Casalinuovo 
202434c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, media_node::null,
202534c72144SAxel Dörfler 		notificationType);
202652a38012Sejakowatz }
202752a38012Sejakowatz 
202852a38012Sejakowatz 
202952a38012Sejakowatz status_t
203034c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger& where, const media_node& node,
203152a38012Sejakowatz 	int32 notificationType)
203252a38012Sejakowatz {
2033eae26d3dSbeveloper 	CALLED();
2034eae26d3dSbeveloper 	if (!where.IsValid()) {
20355ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
2036eae26d3dSbeveloper 		return B_BAD_VALUE;
2037eae26d3dSbeveloper 	}
203840f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
20395ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: node invalid!\n");
2040eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
2041eae26d3dSbeveloper 	}
204234c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(true,
204334c72144SAxel Dörfler 			notificationType)) {
20445ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
2045eae26d3dSbeveloper 		return B_BAD_VALUE;
2046eae26d3dSbeveloper 	}
204734c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, node,
204834c72144SAxel Dörfler 		notificationType);
204952a38012Sejakowatz }
205052a38012Sejakowatz 
205152a38012Sejakowatz 
205252a38012Sejakowatz status_t
205352a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger& where)
205452a38012Sejakowatz {
2055eae26d3dSbeveloper 	CALLED();
2056eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
205734c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, media_node::null,
205834c72144SAxel Dörfler 		B_MEDIA_WILDCARD);
205952a38012Sejakowatz }
206052a38012Sejakowatz 
206152a38012Sejakowatz 
206252a38012Sejakowatz status_t
206334c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, int32 notificationType)
206452a38012Sejakowatz {
2065eae26d3dSbeveloper 	CALLED();
2066eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
206734c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(false,
206834c72144SAxel Dörfler 			notificationType)) {
20695ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
2070eae26d3dSbeveloper 		return B_BAD_VALUE;
2071eae26d3dSbeveloper 	}
207234c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, media_node::null,
207334c72144SAxel Dörfler 		notificationType);
207452a38012Sejakowatz }
207552a38012Sejakowatz 
207652a38012Sejakowatz 
207752a38012Sejakowatz status_t
207834c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, const media_node& node,
207952a38012Sejakowatz 	int32 notificationType)
208052a38012Sejakowatz {
2081eae26d3dSbeveloper 	CALLED();
2082eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
208340f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
20845ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: node invalid!\n");
2085eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
2086eae26d3dSbeveloper 	}
208734c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(true,
208834c72144SAxel Dörfler 			notificationType)) {
20895ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
2090eae26d3dSbeveloper 		return B_BAD_VALUE;
2091eae26d3dSbeveloper 	}
209234c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, node,
209334c72144SAxel Dörfler 		notificationType);
209452a38012Sejakowatz }
209552a38012Sejakowatz 
209652a38012Sejakowatz 
209752a38012Sejakowatz status_t
209852a38012Sejakowatz BMediaRoster::RegisterNode(BMediaNode* node)
209952a38012Sejakowatz {
210054187cc6Sbeveloper 	CALLED();
210154187cc6Sbeveloper 	// addon-id = -1 (unused), addon-flavor-id = 0 (unused, too)
210254187cc6Sbeveloper 	return MediaRosterEx(this)->RegisterNode(node, -1, 0);
210354187cc6Sbeveloper }
210454187cc6Sbeveloper 
210554187cc6Sbeveloper 
210654187cc6Sbeveloper status_t
21079c3b4706SAxel Dörfler BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addOnID,
21089dec2310SAxel Dörfler 	int32 flavorID)
210954187cc6Sbeveloper {
211052a38012Sejakowatz 	CALLED();
211152a38012Sejakowatz 	if (node == NULL)
211252a38012Sejakowatz 		return B_BAD_VALUE;
211352a38012Sejakowatz 
211454187cc6Sbeveloper 	// some sanity check
211554187cc6Sbeveloper 	// I'm not sure if the media kit warrants to call BMediaNode::AddOn() here.
211654187cc6Sbeveloper 	// Perhaps we don't need it.
21179dec2310SAxel Dörfler 	DEBUG_ONLY(
21189dec2310SAxel Dörfler 		int32 testFlavorID;
21199dec2310SAxel Dörfler 		BMediaAddOn* addon = node->AddOn(&testFlavorID);
21209dec2310SAxel Dörfler 
21216813f2c7SIngo Weinhold 		ASSERT(addOnID == (addon != NULL ? addon->AddonID() : -1));
2122e817f41eSFredrik Modéen //		ASSERT(flavorID == testFlavorID);
21239dec2310SAxel Dörfler 	);
212452a38012Sejakowatz 
21259e9417d2Sbeveloper 	server_register_node_request request;
21269e9417d2Sbeveloper 	server_register_node_reply reply;
21279e9417d2Sbeveloper 
21289c3b4706SAxel Dörfler 	request.add_on_id = addOnID;
21299c3b4706SAxel Dörfler 	request.flavor_id = flavorID;
21309e9417d2Sbeveloper 	strcpy(request.name, node->Name());
21319e9417d2Sbeveloper 	request.kinds = node->Kinds();
21329e9417d2Sbeveloper 	request.port = node->ControlPort();
21339dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
21347bcdb362SDario Casalinuovo 	request.timesource_id = node->fTimeSourceID;
21359e9417d2Sbeveloper 
213634c72144SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port "
2137332cc6bcSAxel Dörfler 		"%" B_PRId32 ", kinds 0x%" B_PRIx64 ", team %" B_PRId32 ", name '%s'\n",
2138332cc6bcSAxel Dörfler 		request.port, request.kinds, request.team, request.name);
21391299bfb2Sbeveloper 
21409c3b4706SAxel Dörfler 	status_t status = QueryServer(SERVER_REGISTER_NODE, &request,
21419c3b4706SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
21429c3b4706SAxel Dörfler 	if (status != B_OK) {
21439c3b4706SAxel Dörfler 		ERROR("BMediaRoster::RegisterNode: failed to register node %s: %s\n",
21449c3b4706SAxel Dörfler 			node->Name(), strerror(status));
21459c3b4706SAxel Dörfler 		return status;
21469e9417d2Sbeveloper 	}
21479e9417d2Sbeveloper 
214834c72144SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: QueryServer SERVER_REGISTER_NODE "
214934c72144SAxel Dörfler 		"finished\n");
21504295907bSbeveloper 
21518b04ffc1Sbeveloper 	// we are a friend class of BMediaNode and initialize this member variable
21529dec2310SAxel Dörfler 	node->fNodeID = reply.node_id;
21539dec2310SAxel Dörfler 	ASSERT(reply.node_id == node->Node().node);
21549dec2310SAxel Dörfler 	ASSERT(reply.node_id == node->ID());
21559e9417d2Sbeveloper 
215634c72144SAxel Dörfler 	// if the BMediaNode also inherits from BTimeSource, we need to call
215734c72144SAxel Dörfler 	// BTimeSource::FinishCreate()
21589c3b4706SAxel Dörfler 	if ((node->Kinds() & B_TIME_SOURCE) != 0) {
21599c3b4706SAxel Dörfler 		if (BTimeSource* timeSource = dynamic_cast<BTimeSource*>(node))
21609c3b4706SAxel Dörfler 			timeSource->FinishCreate();
21610e21b167Sbeveloper 	}
21620e21b167Sbeveloper 
216311ed4f9fSDario Casalinuovo 	// call the callback
216411ed4f9fSDario Casalinuovo 	node->NodeRegistered();
216511ed4f9fSDario Casalinuovo 
216611ed4f9fSDario Casalinuovo 	TRACE("BMediaRoster::RegisterNode: NodeRegistered callback finished\n");
216711ed4f9fSDario Casalinuovo 
21684295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: publishing inputs/outputs\n");
21694295907bSbeveloper 
21703620737cSbeveloper 	// register existing inputs and outputs with the
21713620737cSbeveloper 	// media_server, this allows GetLiveNodes() to work
21723620737cSbeveloper 	// with created, but unconnected nodes.
21734d2d96e0Sbeveloper 	// The node control loop might not be running, or might deadlock
21744d2d96e0Sbeveloper 	// if we send a message and wait for a reply here.
21754d2d96e0Sbeveloper 	// We have a pointer to the node, and thus call the functions directly
21764295907bSbeveloper 
21779c3b4706SAxel Dörfler 	if ((node->Kinds() & B_BUFFER_PRODUCER) != 0) {
21789c3b4706SAxel Dörfler 		if (BBufferProducer* producer = dynamic_cast<BBufferProducer*>(node)) {
2179359ac306Sbeveloper 			List<media_output> list;
21809c3b4706SAxel Dörfler 			if (GetAllOutputs(producer, &list) == B_OK)
2181359ac306Sbeveloper 				PublishOutputs(node->Node(), &list);
218221871f38Sbeveloper 		}
21834d2d96e0Sbeveloper 	}
21849dec2310SAxel Dörfler 	if ((node->Kinds() & B_BUFFER_CONSUMER) != 0) {
21859c3b4706SAxel Dörfler 		if (BBufferConsumer* consumer = dynamic_cast<BBufferConsumer*>(node)) {
2186359ac306Sbeveloper 			List<media_input> list;
21879dec2310SAxel Dörfler 			if (GetAllInputs(consumer, &list) == B_OK)
2188359ac306Sbeveloper 				PublishInputs(node->Node(), &list);
21893620737cSbeveloper 		}
21904d2d96e0Sbeveloper 	}
219121871f38Sbeveloper 
21924295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n");
21934295907bSbeveloper 
21949dec2310SAxel Dörfler 	BPrivate::media::notifications::NodesCreated(&reply.node_id, 1);
21954295907bSbeveloper 
21964295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: finished\n");
21974295907bSbeveloper 
2198570f7d04Sbeveloper /*
21999c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: registered node name '%s', id %ld,
22009c3b4706SAxel Dörfler 		addon %ld, flavor %ld\n", node->Name(), node->ID(), addOnID, flavorID);
2201570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node this               %p\n", node);
22029c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fConsumerThis      %p\n",
22039c3b4706SAxel Dörfler 		node->fConsumerThis);
22049c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fProducerThis      %p\n",
22059c3b4706SAxel Dörfler 		node->fProducerThis);
22069c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fFileInterfaceThis %p\n",
22079c3b4706SAxel Dörfler 		node->fFileInterfaceThis);
22089c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fControllableThis  %p\n",
22099c3b4706SAxel Dörfler 		node->fControllableThis);
22109c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fTimeSourceThis    %p\n",
22119c3b4706SAxel Dörfler 		node->fTimeSourceThis);
2212570f7d04Sbeveloper */
22139e9417d2Sbeveloper 	return B_OK;
221452a38012Sejakowatz }
221552a38012Sejakowatz 
221652a38012Sejakowatz 
221752a38012Sejakowatz status_t
221852a38012Sejakowatz BMediaRoster::UnregisterNode(BMediaNode* node)
221952a38012Sejakowatz {
22209e9417d2Sbeveloper 	CALLED();
22219e9417d2Sbeveloper 	if (node == NULL)
22229e9417d2Sbeveloper 		return B_BAD_VALUE;
22239e9417d2Sbeveloper 
22242ceb090fSDario Casalinuovo 	TRACE("BMediaRoster::UnregisterNode %"
22252ceb090fSDario Casalinuovo 		B_PRId32 " (%p)\n", node->ID(), node);
222660f15390Sbeveloper 
222729bb91d6SAxel Dörfler 	if ((node->fKinds & NODE_KIND_NO_REFCOUNTING) !=0) {
222834c72144SAxel Dörfler 		TRACE("BMediaRoster::UnregisterNode, trying to unregister reference "
22292ceb090fSDario Casalinuovo 			"counting disabled timesource, node %"
22302ceb090fSDario Casalinuovo 			B_PRId32 " , port %" B_PRId32 " , team %" B_PRId32 "\n",
22319dec2310SAxel Dörfler 			node->ID(), node->ControlPort(), BPrivate::current_team());
223286bce45bSbeveloper 		return B_OK;
223386bce45bSbeveloper 	}
22348b04ffc1Sbeveloper 	if (node->ID() == NODE_UNREGISTERED_ID) {
223534c72144SAxel Dörfler 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name "
223634c72144SAxel Dörfler 			"'%s' already unregistered\n", node->ID(), node->Name());
22379e9417d2Sbeveloper 		return B_OK;
22389e9417d2Sbeveloper 	}
223954187cc6Sbeveloper 	if (node->fRefCount != 0) {
224034c72144SAxel Dörfler 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name "
224134c72144SAxel Dörfler 			"'%s' has local reference count of %ld\n", node->ID(), node->Name(),
224234c72144SAxel Dörfler 			node->fRefCount);
224354187cc6Sbeveloper 		// no return here, we continue and unregister!
224454187cc6Sbeveloper 	}
224554187cc6Sbeveloper 
224634c72144SAxel Dörfler 	// Calling BMediaAddOn::GetConfigurationFor(BMediaNode *node,
224734c72144SAxel Dörfler 	// BMessage *config) if this node was instanciated by an add-on needs to
224834c72144SAxel Dörfler 	// be done *somewhere*
224954187cc6Sbeveloper 	// We can't do it here because it is already to late (destructor of the node
225054187cc6Sbeveloper 	// might have been called).
22519e9417d2Sbeveloper 
22529e9417d2Sbeveloper 	server_unregister_node_request request;
22539dec2310SAxel Dörfler 	request.node_id = node->ID();
22549dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
22559e9417d2Sbeveloper 
22561299bfb2Sbeveloper 	// send a notification
22579dec2310SAxel Dörfler 	BPrivate::media::notifications::NodesDeleted(&request.node_id, 1);
22581299bfb2Sbeveloper 
225929bb91d6SAxel Dörfler 	server_unregister_node_reply reply;
2260c74afb57SJérôme Duval 	reply.add_on_id = -1;
226129bb91d6SAxel Dörfler 	status_t status = QueryServer(SERVER_UNREGISTER_NODE, &request,
226229bb91d6SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
226329bb91d6SAxel Dörfler 	if (status != B_OK) {
2264332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %"
2265332cc6bcSAxel Dörfler 			B_PRId32 ", name '%s': %s\n", node->ID(), node->Name(),
2266332cc6bcSAxel Dörfler 			strerror(status));
2267c74afb57SJérôme Duval 		BMediaAddOn *addon = node->AddOn(&reply.flavor_id);
2268c74afb57SJérôme Duval 		if (addon != NULL)
2269c74afb57SJérôme Duval 			reply.add_on_id = addon->AddonID();
22709e9417d2Sbeveloper 	}
22719e9417d2Sbeveloper 
22729c3b4706SAxel Dörfler 	if (reply.add_on_id != -1) {
227329bb91d6SAxel Dörfler 		// TODO: this doesn't look right
227429bb91d6SAxel Dörfler 		// Small problem here, we can't use DormantNodeManager::PutAddOn(), as
227534c72144SAxel Dörfler 		// UnregisterNode() is called by a dormant node itself (by the
227634c72144SAxel Dörfler 		// destructor).
227754187cc6Sbeveloper 		// The add-on that contains the node needs to remain in memory until the
227854187cc6Sbeveloper 		// destructor execution is finished.
227929bb91d6SAxel Dörfler 		// DormantNodeManager::PutAddOnDelayed() will delay unloading.
22809c3b4706SAxel Dörfler 		gDormantNodeManager->PutAddOnDelayed(reply.add_on_id);
2281cf4e2277Sbeveloper 
228229bb91d6SAxel Dörfler 		status = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount(
22839c3b4706SAxel Dörfler 			reply.add_on_id, reply.flavor_id);
228429bb91d6SAxel Dörfler 		if (status != B_OK) {
228534c72144SAxel Dörfler 			ERROR("BMediaRoster::UnregisterNode: "
228634c72144SAxel Dörfler 				"DecrementAddonFlavorInstancesCount() failed\n");
228754187cc6Sbeveloper 			// this is really a problem, but we can't fail now
228854187cc6Sbeveloper 		}
22898b04ffc1Sbeveloper 	}
22909e9417d2Sbeveloper 
22911299bfb2Sbeveloper 	// we are a friend class of BMediaNode and invalidate this member variable
22928b04ffc1Sbeveloper 	node->fNodeID = NODE_UNREGISTERED_ID;
22939e9417d2Sbeveloper 
2294c74afb57SJérôme Duval 	return status;
229552a38012Sejakowatz }
229652a38012Sejakowatz 
229752a38012Sejakowatz 
229834c72144SAxel Dörfler //!	Thread safe for multiple calls to Roster()
229952a38012Sejakowatz /*static*/ BMediaRoster*
230052a38012Sejakowatz BMediaRoster::Roster(status_t* out_error)
230152a38012Sejakowatz {
2302d15321ffSDario Casalinuovo 	BAutolock lock(sInitLocker);
2303d15321ffSDario Casalinuovo 
230405962bb1SDario Casalinuovo 	if (be_app == NULL)
230534619a6fSDario Casalinuovo 		TRACE("Warning! You should have a valid BApplication.");
230605962bb1SDario Casalinuovo 
2307d15321ffSDario Casalinuovo 	if (!lock.IsLocked())
2308d15321ffSDario Casalinuovo 		return NULL;
2309d15321ffSDario Casalinuovo 
23108496c38aSbeveloper 	if (out_error)
23118496c38aSbeveloper 		*out_error = B_OK;
2312d15321ffSDario Casalinuovo 
23139def3bf7SStephan Aßmus 	if (sDefaultInstance == NULL) {
23148496c38aSbeveloper 		status_t err;
23159def3bf7SStephan Aßmus 		sDefaultInstance = new (std::nothrow) BMediaRosterEx(&err);
23169def3bf7SStephan Aßmus 		if (sDefaultInstance == NULL)
2317a715f908SStephan Aßmus 			err = B_NO_MEMORY;
2318a715f908SStephan Aßmus 		else if (err != B_OK) {
23199def3bf7SStephan Aßmus 			if (sDefaultInstance) {
23209def3bf7SStephan Aßmus 				sDefaultInstance->Lock();
23219def3bf7SStephan Aßmus 				sDefaultInstance->Quit();
23229def3bf7SStephan Aßmus 				sDefaultInstance = NULL;
2323dcfb6bfcSJérôme Duval 			}
23248496c38aSbeveloper 			if (out_error)
23258496c38aSbeveloper 				*out_error = err;
232605962bb1SDario Casalinuovo 		} else if (be_app != NULL) {
232705962bb1SDario Casalinuovo 			be_app->RegisterLooper(sDefaultInstance);
23288496c38aSbeveloper 		}
232952a38012Sejakowatz 	}
233005962bb1SDario Casalinuovo 
23319def3bf7SStephan Aßmus 	return sDefaultInstance;
233252a38012Sejakowatz }
233352a38012Sejakowatz 
233452a38012Sejakowatz 
233552a38012Sejakowatz /*static*/ BMediaRoster*
233652a38012Sejakowatz BMediaRoster::CurrentRoster()
233752a38012Sejakowatz {
23389def3bf7SStephan Aßmus 	return sDefaultInstance;
233952a38012Sejakowatz }
234052a38012Sejakowatz 
234152a38012Sejakowatz 
234252a38012Sejakowatz status_t
234334c72144SAxel Dörfler BMediaRoster::SetTimeSourceFor(media_node_id node, media_node_id time_source)
234452a38012Sejakowatz {
2345aac800c2Sbeveloper 	CALLED();
234640f36b03Sbeveloper 	if (IS_INVALID_NODEID(node) || IS_INVALID_NODEID(time_source))
2347aac800c2Sbeveloper 		return B_BAD_VALUE;
2348aac800c2Sbeveloper 
2349aac800c2Sbeveloper 	media_node clone;
23507bcdb362SDario Casalinuovo 	// We need to get a clone of the node to have a port id
23517bcdb362SDario Casalinuovo 	status_t result = GetNodeFor(node, &clone);
23527bcdb362SDario Casalinuovo 	if (result == B_OK) {
23537bcdb362SDario Casalinuovo 		// We just send the request to set time_source-id as
23547bcdb362SDario Casalinuovo 		// timesource to the node, the NODE_SET_TIMESOURCE handler
23557bcdb362SDario Casalinuovo 		// code will do the real assignment.
2356aac800c2Sbeveloper 		result = B_OK;
2357aac800c2Sbeveloper 		node_set_timesource_command cmd;
2358aac800c2Sbeveloper 		cmd.timesource_id = time_source;
23597bcdb362SDario Casalinuovo 		result = SendToPort(clone.port, NODE_SET_TIMESOURCE,
23607bcdb362SDario Casalinuovo 			&cmd, sizeof(cmd));
23617bcdb362SDario Casalinuovo 		if (result != B_OK) {
23627bcdb362SDario Casalinuovo 			ERROR("BMediaRoster::SetTimeSourceFor"
23637bcdb362SDario Casalinuovo 				"sending NODE_SET_TIMESOURCE failed, node id %"
23647bcdb362SDario Casalinuovo 				B_PRId32 "\n", clone.node);
23657bcdb362SDario Casalinuovo 		}
23667bcdb362SDario Casalinuovo 		// We release the clone
23677bcdb362SDario Casalinuovo 		result = ReleaseNode(clone);
23687bcdb362SDario Casalinuovo 		if (result != B_OK) {
23697bcdb362SDario Casalinuovo 			ERROR("BMediaRoster::SetTimeSourceFor, ReleaseNode failed,"
23707bcdb362SDario Casalinuovo 				" node id %" B_PRId32 "\n", clone.node);
23717bcdb362SDario Casalinuovo 		}
23727bcdb362SDario Casalinuovo 	} else {
23737bcdb362SDario Casalinuovo 		ERROR("BMediaRoster::SetTimeSourceFor GetCloneForID failed, "
23747bcdb362SDario Casalinuovo 			"node id %" B_PRId32 "\n", node);
23757bcdb362SDario Casalinuovo 	}
23767bcdb362SDario Casalinuovo 
23777bcdb362SDario Casalinuovo 	if (result == B_OK) {
23787bcdb362SDario Casalinuovo 		// Notify the server
23797bcdb362SDario Casalinuovo 		server_set_node_timesource_request request;
23807bcdb362SDario Casalinuovo 		server_set_node_timesource_reply reply;
23817bcdb362SDario Casalinuovo 
23827bcdb362SDario Casalinuovo 		request.node_id = node;
23837bcdb362SDario Casalinuovo 		request.timesource_id = time_source;
23847bcdb362SDario Casalinuovo 
23857bcdb362SDario Casalinuovo 		result = QueryServer(SERVER_SET_NODE_TIMESOURCE, &request,
23867bcdb362SDario Casalinuovo 			sizeof(request), &reply, sizeof(reply));
23877bcdb362SDario Casalinuovo 		if (result != B_OK) {
238834c72144SAxel Dörfler 			ERROR("BMediaRoster::SetTimeSourceFor, sending NODE_SET_TIMESOURCE "
2389332cc6bcSAxel Dörfler 				"failed, node id %" B_PRId32 "\n", node);
23907bcdb362SDario Casalinuovo 		} else {
2391332cc6bcSAxel Dörfler 			TRACE("BMediaRoster::SetTimeSourceFor: node %" B_PRId32 " time source %"
23927bcdb362SDario Casalinuovo 				B_PRId32 " OK\n", node, time_source);
23937bcdb362SDario Casalinuovo 		}
23947bcdb362SDario Casalinuovo 	}
2395aac800c2Sbeveloper 	return result;
2396aac800c2Sbeveloper }
2397aac800c2Sbeveloper 
239852a38012Sejakowatz 
239952a38012Sejakowatz status_t
240034c72144SAxel Dörfler BMediaRoster::GetParameterWebFor(const media_node& node, BParameterWeb** _web)
240152a38012Sejakowatz {
240228ad138aSbeveloper 	CALLED();
240334c72144SAxel Dörfler 	if (_web == NULL)
240428ad138aSbeveloper 		return B_BAD_VALUE;
240528ad138aSbeveloper 	if (IS_INVALID_NODE(node))
240628ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
240728ad138aSbeveloper 	if ((node.kind & B_CONTROLLABLE) == 0)
240828ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
240928ad138aSbeveloper 
241028ad138aSbeveloper 	controllable_get_parameter_web_request request;
241128ad138aSbeveloper 	controllable_get_parameter_web_reply reply;
241234c72144SAxel Dörfler 	int32 requestsize[] = {B_PAGE_SIZE, 4 * B_PAGE_SIZE, 16 * B_PAGE_SIZE,
241334c72144SAxel Dörfler 		64 * B_PAGE_SIZE, 128 * B_PAGE_SIZE, 256 * B_PAGE_SIZE, 0};
241428ad138aSbeveloper 	int32 size;
241528ad138aSbeveloper 
241634c72144SAxel Dörfler 	// TODO: it might be better to query the node for the (current) parameter
241734c72144SAxel Dörfler 	// size first
241828ad138aSbeveloper 	for (int i = 0; (size = requestsize[i]) != 0; i++) {
241928ad138aSbeveloper 		status_t rv;
242028ad138aSbeveloper 		area_id area;
242128ad138aSbeveloper 		void *data;
242234c72144SAxel Dörfler 		area = create_area("parameter web data", &data, B_ANY_ADDRESS, size,
2423*964cab46SAugustin Cavalier 			B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_CLONEABLE_AREA);
242428ad138aSbeveloper 		if (area < B_OK) {
242534c72144SAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor couldn't create area of "
2426332cc6bcSAxel Dörfler 				"size %" B_PRId32 "\n", size);
242728ad138aSbeveloper 			return B_ERROR;
242828ad138aSbeveloper 		}
242934c72144SAxel Dörfler 		request.max_size = size;
243028ad138aSbeveloper 		request.area = area;
243134c72144SAxel Dörfler 		rv = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_WEB, &request,
243234c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
243328ad138aSbeveloper 		if (rv != B_OK) {
243434c72144SAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor "
243534c72144SAxel Dörfler 				"CONTROLLABLE_GET_PARAMETER_WEB failed\n");
243628ad138aSbeveloper 			delete_area(area);
243728ad138aSbeveloper 			return B_ERROR;
243828ad138aSbeveloper 		}
243928ad138aSbeveloper 		if (reply.size == 0) {
244028ad138aSbeveloper 			// no parameter web available
244134c72144SAxel Dörfler 			// TODO: should we return an error?
2442332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor node %" B_PRId32
2443332cc6bcSAxel Dörfler 				" has no parameter web\n", node.node);
244434c72144SAxel Dörfler 			*_web = new (std::nothrow) BParameterWeb();
244528ad138aSbeveloper 			delete_area(area);
244634c72144SAxel Dörfler 			return *_web != NULL ? B_OK : B_NO_MEMORY;
244752a38012Sejakowatz 		}
244828ad138aSbeveloper 		if (reply.size > 0) {
244928ad138aSbeveloper 			// we got a flattened parameter web!
2450df612ac9SRene Gollent 			BParameterWeb* web = new (std::nothrow) BParameterWeb();
2451df612ac9SRene Gollent 			if (web == NULL)
2452a715f908SStephan Aßmus 				rv = B_NO_MEMORY;
2453a715f908SStephan Aßmus 			else {
2454df612ac9SRene Gollent 				rv = web->Unflatten(reply.code, data, reply.size);
245528ad138aSbeveloper 				if (rv != B_OK) {
245634c72144SAxel Dörfler 					ERROR("BMediaRoster::GetParameterWebFor Unflatten failed, "
245734c72144SAxel Dörfler 						"%s\n", strerror(rv));
2458df612ac9SRene Gollent 					delete web;
2459df612ac9SRene Gollent 				} else
2460df612ac9SRene Gollent 					*_web = web;
246128ad138aSbeveloper 			}
2462df612ac9SRene Gollent 
246328ad138aSbeveloper 			delete_area(area);
2464a715f908SStephan Aßmus 			return rv;
246528ad138aSbeveloper 		}
246628ad138aSbeveloper 		delete_area(area);
246728ad138aSbeveloper 		ASSERT(reply.size == -1);
246828ad138aSbeveloper 		// parameter web data was too large
246928ad138aSbeveloper 		// loop and try a larger size
247028ad138aSbeveloper 	}
2471332cc6bcSAxel Dörfler 	ERROR("BMediaRoster::GetParameterWebFor node %" B_PRId32 " has no "
2472332cc6bcSAxel Dörfler 		"parameter web larger than %" B_PRId32 "\n", node.node, size);
247328ad138aSbeveloper 	return B_ERROR;
247428ad138aSbeveloper }
247552a38012Sejakowatz 
247652a38012Sejakowatz 
247752a38012Sejakowatz status_t
247834c72144SAxel Dörfler BMediaRoster::StartControlPanel(const media_node& node, BMessenger* _messenger)
247952a38012Sejakowatz {
2480999cd0acSMaurice Kalinowski 	CALLED();
2481999cd0acSMaurice Kalinowski 
2482999cd0acSMaurice Kalinowski 	controllable_start_control_panel_request request;
2483999cd0acSMaurice Kalinowski 	controllable_start_control_panel_reply reply;
2484999cd0acSMaurice Kalinowski 
2485999cd0acSMaurice Kalinowski 	request.node = node;
2486999cd0acSMaurice Kalinowski 
2487999cd0acSMaurice Kalinowski 	status_t rv;
248834c72144SAxel Dörfler 	rv = QueryPort(node.port, CONTROLLABLE_START_CONTROL_PANEL, &request,
248934c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2490999cd0acSMaurice Kalinowski 	if (rv != B_OK)
2491999cd0acSMaurice Kalinowski 		return rv;
2492999cd0acSMaurice Kalinowski 
249334c72144SAxel Dörfler 	if (reply.team != -1 && _messenger != NULL)
249434c72144SAxel Dörfler 		*_messenger = BMessenger(NULL, reply.team);
2495999cd0acSMaurice Kalinowski 
2496999cd0acSMaurice Kalinowski 	return B_OK;
249752a38012Sejakowatz }
249852a38012Sejakowatz 
249952a38012Sejakowatz 
250052a38012Sejakowatz status_t
250134c72144SAxel Dörfler BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
250234c72144SAxel Dörfler 	const media_format* hasInput, const media_format* hasOutput,
250334c72144SAxel Dörfler 	const char* name, uint64 requireKinds, uint64 denyKinds)
250452a38012Sejakowatz {
250552a38012Sejakowatz 	CALLED();
250634c72144SAxel Dörfler 	if (_info == NULL || _count == NULL || *_count <= 0)
250752a38012Sejakowatz 		return B_BAD_VALUE;
250852a38012Sejakowatz 
2509e4c87231SAxel Dörfler 	server_get_dormant_nodes_request request;
2510e4c87231SAxel Dörfler 	request.max_count = *_count;
2511e4c87231SAxel Dörfler 	request.has_input = hasInput != NULL;
251234c72144SAxel Dörfler 	if (hasInput != NULL) {
251334c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
2514e4c87231SAxel Dörfler 		request.input_format = *hasInput;
251534c72144SAxel Dörfler 	}
2516e4c87231SAxel Dörfler 	request.has_output = hasOutput != NULL;
251734c72144SAxel Dörfler 	if (hasOutput != NULL) {
251834c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
2519e4c87231SAxel Dörfler 		request.output_format = *hasOutput;
252034c72144SAxel Dörfler 	}
252134c72144SAxel Dörfler 
2522e4c87231SAxel Dörfler 	request.has_name = name != NULL;
2523e4c87231SAxel Dörfler 	if (name != NULL)
2524e4c87231SAxel Dörfler 		strlcpy(request.name, name, sizeof(request.name));
252552a38012Sejakowatz 
2526e4c87231SAxel Dörfler 	request.require_kinds = requireKinds;
2527e4c87231SAxel Dörfler 	request.deny_kinds = denyKinds;
252852a38012Sejakowatz 
2529e4c87231SAxel Dörfler 	server_get_dormant_nodes_reply reply;
2530e4c87231SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_DORMANT_NODES, &request,
2531e4c87231SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
25326cafce94SAxel Dörfler 	if (status != B_OK)
2533e4c87231SAxel Dörfler 		return status;
253452a38012Sejakowatz 
253534c72144SAxel Dörfler 	*_count = reply.count;
253652a38012Sejakowatz 
2537e4c87231SAxel Dörfler 	if (reply.count > 0) {
2538e4c87231SAxel Dörfler 		int32 code;
2539e4c87231SAxel Dörfler 		status = read_port(request.reply_port, &code, _info,
2540e4c87231SAxel Dörfler 			reply.count * sizeof(dormant_node_info));
2541e4c87231SAxel Dörfler 		if (status < B_OK)
2542e4c87231SAxel Dörfler 			reply.result = status;
254352a38012Sejakowatz 	}
254452a38012Sejakowatz 
254552a38012Sejakowatz 	return reply.result;
254652a38012Sejakowatz }
254752a38012Sejakowatz 
2548e4c87231SAxel Dörfler 
254934c72144SAxel Dörfler /*!	This function is used to do the real work of instantiating a dormant node.
255034c72144SAxel Dörfler 	It is either called by the media_addon_server to instantiate a global node,
255134c72144SAxel Dörfler 	or it gets called from BMediaRoster::InstantiateDormantNode() to create a
255234c72144SAxel Dörfler 	local one.
255334c72144SAxel Dörfler 
255434c72144SAxel Dörfler 	Checks concerning global/local are not done here.
25558b04ffc1Sbeveloper */
255652a38012Sejakowatz status_t
255734c72144SAxel Dörfler BMediaRosterEx::InstantiateDormantNode(media_addon_id addonID, int32 flavorID,
255834c72144SAxel Dörfler 	team_id creator, media_node *_node)
255952a38012Sejakowatz {
256054187cc6Sbeveloper 	// This function is always called from the correct context, if the node
256154187cc6Sbeveloper 	// is supposed to be global, it is called from the media_addon_server.
256254187cc6Sbeveloper 
256352a38012Sejakowatz 	// if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that
256452a38012Sejakowatz 	// resides in the media_addon_server
256552a38012Sejakowatz 
25668b04ffc1Sbeveloper 	// RegisterNode() must be called for nodes instantiated from add-ons,
25678b04ffc1Sbeveloper 	// since the media kit warrants that it's done automatically.
256852a38012Sejakowatz 
256934c72144SAxel Dörfler 	// addonID		Indicates the ID number of the media add-on in which the
257034c72144SAxel Dörfler 	//				node resides.
257134c72144SAxel Dörfler 	// flavorID		Indicates the internal ID number that the add-on uses to
257234c72144SAxel Dörfler 	//				identify the flavor, this is the number that was published
257334c72144SAxel Dörfler 	//				by BMediaAddOn::GetFlavorAt() in the
25748b04ffc1Sbeveloper 	//				flavor_info::internal_id field.
257534c72144SAxel Dörfler 	// creator		The creator team is -1 if nodes are created locally. If
257634c72144SAxel Dörfler 	//				created globally, it will contain (while called in
257734c72144SAxel Dörfler 	//				media_addon_server context) the team-id of the team that
257834c72144SAxel Dörfler 	//				requested the instantiation.
25798b04ffc1Sbeveloper 
2580332cc6bcSAxel Dörfler 	TRACE("BMediaRosterEx::InstantiateDormantNode: addonID %" B_PRId32
2581332cc6bcSAxel Dörfler 		", flavorID %" B_PRId32 "\n", addonID, flavorID);
25828b04ffc1Sbeveloper 
25838b04ffc1Sbeveloper 	// Get flavor_info from the server
258434c72144SAxel Dörfler 	dormant_flavor_info info;
25858c6a6096Sbeveloper 	status_t rv;
258634c72144SAxel Dörfler 	rv = GetDormantFlavorInfo(addonID, flavorID, &info);
25878b04ffc1Sbeveloper 	if (rv != B_OK) {
258834c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode error: failed to get "
2589332cc6bcSAxel Dörfler 			"dormant_flavor_info for addon-id %" B_PRId32 ", flavor-id %"
2590332cc6bcSAxel Dörfler 			B_PRId32 "\n", addonID, flavorID);
259152a38012Sejakowatz 		return B_ERROR;
259252a38012Sejakowatz 	}
25938b04ffc1Sbeveloper 
25941ecccf18SFrançois Revol 	ASSERT(info.internal_id == flavorID);
25958b04ffc1Sbeveloper 
25968b04ffc1Sbeveloper 	// load the BMediaAddOn object
259729bb91d6SAxel Dörfler 	BMediaAddOn* addon = gDormantNodeManager->GetAddOn(addonID);
259834c72144SAxel Dörfler 	if (addon == NULL) {
25995ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: GetAddon failed\n");
26008b04ffc1Sbeveloper 		return B_ERROR;
26018b04ffc1Sbeveloper 	}
26028b04ffc1Sbeveloper 
260354187cc6Sbeveloper 	// Now we need to try to increment the use count of this addon flavor
260454187cc6Sbeveloper 	// in the server. This can fail if the total number instances of this
260554187cc6Sbeveloper 	// flavor is limited.
260634c72144SAxel Dörfler 	rv = IncrementAddonFlavorInstancesCount(addonID, flavorID);
260754187cc6Sbeveloper 	if (rv != B_OK) {
260834c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode error: can't create "
2609332cc6bcSAxel Dörfler 			"more nodes for addon-id %" B_PRId32 ", flavor-id %" B_PRId32 "\n",
2610332cc6bcSAxel Dörfler 			addonID, flavorID);
261154187cc6Sbeveloper 		// Put the addon back into the pool
261229bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
261354187cc6Sbeveloper 		return B_ERROR;
261454187cc6Sbeveloper 	}
261554187cc6Sbeveloper 
26168b04ffc1Sbeveloper 	BMessage config;
261734c72144SAxel Dörfler 	rv = LoadNodeConfiguration(addonID, flavorID, &config);
261854187cc6Sbeveloper 	if (rv != B_OK) {
261934c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode: couldn't load "
2620332cc6bcSAxel Dörfler 			"configuration for addon-id %" B_PRId32 ", flavor-id %" B_PRId32
2621332cc6bcSAxel Dörfler 			"\n", addonID, flavorID);
262254187cc6Sbeveloper 		// do not return, this is a minor problem, not a reason to fail
262354187cc6Sbeveloper 	}
26248b04ffc1Sbeveloper 
262534c72144SAxel Dörfler 	status_t status = B_OK;
262634c72144SAxel Dörfler 	BMediaNode* node = addon->InstantiateNodeFor(&info, &config, &status);
262734c72144SAxel Dörfler 	if (node == NULL) {
262834c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode: InstantiateNodeFor "
262934c72144SAxel Dörfler 			"failed\n");
26308b04ffc1Sbeveloper 
263154187cc6Sbeveloper 		// Put the addon back into the pool
263229bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
263334c72144SAxel Dörfler 
263454187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
263554187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
263634c72144SAxel Dörfler 		rv = DecrementAddonFlavorInstancesCount(addonID, flavorID);
263754187cc6Sbeveloper 		if (rv != B_OK) {
263834c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon"
263934c72144SAxel Dörfler 				"FlavorInstancesCount failed\n");
264016b7eea4Sbeveloper 		}
264134c72144SAxel Dörfler 		return status != B_OK ? status : B_ERROR;
264254187cc6Sbeveloper 	}
264354187cc6Sbeveloper 
264434c72144SAxel Dörfler 	rv = RegisterNode(node, addonID, flavorID);
26458c6a6096Sbeveloper 	if (rv != B_OK) {
26465ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: RegisterNode failed\n");
26478c6a6096Sbeveloper 		delete node;
264854187cc6Sbeveloper 		// Put the addon back into the pool
264929bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
265054187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
265154187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
265234c72144SAxel Dörfler 		rv = DecrementAddonFlavorInstancesCount(addonID, flavorID);
265354187cc6Sbeveloper 		if (rv != B_OK) {
265434c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon"
265534c72144SAxel Dörfler 				"FlavorInstancesCount failed\n");
265654187cc6Sbeveloper 		}
26578c6a6096Sbeveloper 		return B_ERROR;
26588c6a6096Sbeveloper 	}
26598c6a6096Sbeveloper 
266054187cc6Sbeveloper 	if (creator != -1) {
266134c72144SAxel Dörfler 		// send a message to the server to assign team "creator" as creator
266234c72144SAxel Dörfler 		// of node "node->ID()"
2663332cc6bcSAxel Dörfler 		printf("!!! BMediaRosterEx::InstantiateDormantNode assigning team %"
2664332cc6bcSAxel Dörfler 			B_PRId32 " as creator of node %" B_PRId32 "\n", creator,
2665332cc6bcSAxel Dörfler 			node->ID());
266634c72144SAxel Dörfler 
266754187cc6Sbeveloper 		rv = MediaRosterEx(this)->SetNodeCreator(node->ID(), creator);
266854187cc6Sbeveloper 		if (rv != B_OK) {
266934c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode failed to assign "
2670332cc6bcSAxel Dörfler 				"team %" B_PRId32 " as creator of node %" B_PRId32 "\n",
2671332cc6bcSAxel Dörfler 				creator, node->ID());
267254187cc6Sbeveloper 			// do not return, this is a minor problem, not a reason to fail
267354187cc6Sbeveloper 		}
267454187cc6Sbeveloper 	}
267554187cc6Sbeveloper 
267654187cc6Sbeveloper 	// RegisterNode() does remember the add-on id in the server
267754187cc6Sbeveloper 	// and UnregisterNode() will call DormantNodeManager::PutAddon()
267854187cc6Sbeveloper 	// when the node is unregistered.
26798c6a6096Sbeveloper 
268034c72144SAxel Dörfler 	*_node = node->Node();
2681cf4e2277Sbeveloper 
2682332cc6bcSAxel Dörfler 	TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %" B_PRId32
2683332cc6bcSAxel Dörfler 		", flavor_id %" B_PRId32 " instanciated as node %" B_PRId32 ", port %"
2684332cc6bcSAxel Dörfler 		B_PRId32 " in team %" B_PRId32 "\n", addonID, flavorID, _node->node,
2685332cc6bcSAxel Dörfler 		_node->port, BPrivate::current_team());
2686cf4e2277Sbeveloper 
268716b7eea4Sbeveloper 	return B_OK;
268816b7eea4Sbeveloper }
268952a38012Sejakowatz 
269052a38012Sejakowatz 
269152a38012Sejakowatz status_t
269234c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
269334c72144SAxel Dörfler 	media_node* _node, uint32 flags)
26948b04ffc1Sbeveloper {
26958b04ffc1Sbeveloper 	CALLED();
269634c72144SAxel Dörfler 	if (_node == NULL)
26978b04ffc1Sbeveloper 		return B_BAD_VALUE;
269834c72144SAxel Dörfler 	if (info.addon <= B_OK) {
2699332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode error: addon-id %" B_PRId32
270034c72144SAxel Dörfler 			" invalid.\n", info.addon);
27018b04ffc1Sbeveloper 		return B_BAD_VALUE;
27028b04ffc1Sbeveloper 	}
27038b04ffc1Sbeveloper 
2704332cc6bcSAxel Dörfler 	printf("BMediaRoster::InstantiateDormantNode: addon-id %" B_PRId32
2705332cc6bcSAxel Dörfler 		", flavor_id %" B_PRId32 ", flags 0x%" B_PRIx32 "\n", info.addon,
2706332cc6bcSAxel Dörfler 		info.flavor_id, flags);
27078b04ffc1Sbeveloper 
27088b04ffc1Sbeveloper 	// Get flavor_info from the server
270934c72144SAxel Dörfler 	// TODO: this is a little overhead, as we get the full blown
271034c72144SAxel Dörfler 	// dormant_flavor_info,
271134c72144SAxel Dörfler 	// TODO: but only need the flags.
271234c72144SAxel Dörfler 	dormant_flavor_info flavorInfo;
27138b04ffc1Sbeveloper 	status_t rv;
271434c72144SAxel Dörfler 	rv = MediaRosterEx(this)->GetDormantFlavorInfo(info.addon, info.flavor_id,
271534c72144SAxel Dörfler 		&flavorInfo);
27168b04ffc1Sbeveloper 	if (rv != B_OK) {
271734c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: failed to get "
2718332cc6bcSAxel Dörfler 			"dormant_flavor_info for addon-id %" B_PRId32 ", flavor-id %"
2719332cc6bcSAxel Dörfler 			B_PRId32 "\n", info.addon, info.flavor_id);
2720626824eaSbeveloper 		return B_NAME_NOT_FOUND;
27218b04ffc1Sbeveloper 	}
27228b04ffc1Sbeveloper 
272334c72144SAxel Dörfler 	ASSERT(flavorInfo.internal_id == info.flavor_id);
27248b04ffc1Sbeveloper 
27258b04ffc1Sbeveloper #if DEBUG
272634c72144SAxel Dörfler 	printf("BMediaRoster::InstantiateDormantNode: name \"%s\", info \"%s\", "
2727332cc6bcSAxel Dörfler 		"flavor_flags 0x%" B_PRIx32 ", internal_id %" B_PRId32
2728332cc6bcSAxel Dörfler 		", possible_count %" B_PRId32 "\n", flavorInfo.name, flavorInfo.info,
2729332cc6bcSAxel Dörfler 		flavorInfo.flavor_flags, flavorInfo.internal_id,
2730332cc6bcSAxel Dörfler 		flavorInfo.possible_count);
273134c72144SAxel Dörfler 
273234c72144SAxel Dörfler 	if ((flags & B_FLAVOR_IS_LOCAL) != 0) {
273334c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: caller requested "
273434c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL\n");
273534c72144SAxel Dörfler 	}
273634c72144SAxel Dörfler 	if ((flags & B_FLAVOR_IS_GLOBAL) != 0) {
273734c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: caller requested "
273834c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL\n");
273934c72144SAxel Dörfler 	}
274034c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0) {
274134c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: node requires "
274234c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL\n");
274334c72144SAxel Dörfler 	}
274434c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0) {
274534c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: node requires "
274634c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL\n");
274734c72144SAxel Dörfler 	}
27488b04ffc1Sbeveloper #endif
27498b04ffc1Sbeveloper 
27508b04ffc1Sbeveloper 	// Make sure that flags demanded by the dormant node and those requested
27518b04ffc1Sbeveloper 	// by the caller are not incompatible.
275234c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0
275334c72144SAxel Dörfler 		&& (flags & B_FLAVOR_IS_LOCAL) != 0) {
275434c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: requested "
275534c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL, but dormant node has B_FLAVOR_IS_GLOBAL\n");
2756626824eaSbeveloper 		return B_NAME_NOT_FOUND;
27578b04ffc1Sbeveloper 	}
275834c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0
275934c72144SAxel Dörfler 		&& (flags & B_FLAVOR_IS_GLOBAL) != 0) {
276034c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: requested "
276134c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL, but dormant node has B_FLAVOR_IS_LOCAL\n");
2762626824eaSbeveloper 		return B_NAME_NOT_FOUND;
27638b04ffc1Sbeveloper 	}
276454187cc6Sbeveloper 
27658b04ffc1Sbeveloper 	// If either the node, or the caller requested to make the instance global
276634c72144SAxel Dörfler 	// we will do it by forwarding this request into the media_addon_server,
276734c72144SAxel Dörfler 	// which in turn will call BMediaRosterEx::InstantiateDormantNode to create
276834c72144SAxel Dörfler 	// the node there and make it globally available.
276934c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0
277034c72144SAxel Dörfler 		|| (flags & B_FLAVOR_IS_GLOBAL) != 0) {
277134c72144SAxel Dörfler 		TRACE("BMediaRoster::InstantiateDormantNode: creating global object "
277234c72144SAxel Dörfler 			"in media_addon_server\n");
2773cf4e2277Sbeveloper 
27749c3b4706SAxel Dörfler 		add_on_server_instantiate_dormant_node_request request;
27759c3b4706SAxel Dörfler 		add_on_server_instantiate_dormant_node_reply reply;
27769c3b4706SAxel Dörfler 		request.add_on_id = info.addon;
27779dec2310SAxel Dörfler 		request.flavor_id = info.flavor_id;
27789dec2310SAxel Dörfler 		request.creator_team = BPrivate::current_team();
277934c72144SAxel Dörfler 			// creator team is allowed to also release global nodes
27809c3b4706SAxel Dörfler 		rv = QueryAddOnServer(ADD_ON_SERVER_INSTANTIATE_DORMANT_NODE, &request,
278134c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
278234c72144SAxel Dörfler 		if (rv == B_OK)
278334c72144SAxel Dörfler 			*_node = reply.node;
27848b04ffc1Sbeveloper 	} else {
278554187cc6Sbeveloper 		// creator team = -1, as this is a local node
278634c72144SAxel Dörfler 		rv = MediaRosterEx(this)->InstantiateDormantNode(info.addon,
278734c72144SAxel Dörfler 			info.flavor_id, -1, _node);
27888b04ffc1Sbeveloper 	}
2789626824eaSbeveloper 	if (rv != B_OK) {
279034c72144SAxel Dörfler 		*_node = media_node::null;
2791626824eaSbeveloper 		return B_NAME_NOT_FOUND;
2792626824eaSbeveloper 	}
2793626824eaSbeveloper 	return B_OK;
27948b04ffc1Sbeveloper }
27958b04ffc1Sbeveloper 
27968b04ffc1Sbeveloper 
27978b04ffc1Sbeveloper status_t
279834c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
279934c72144SAxel Dörfler 	media_node* _node)
28008b04ffc1Sbeveloper {
280134c72144SAxel Dörfler 	return InstantiateDormantNode(info, _node, 0);
28028b04ffc1Sbeveloper }
28038b04ffc1Sbeveloper 
28048b04ffc1Sbeveloper 
28058b04ffc1Sbeveloper status_t
280652a38012Sejakowatz BMediaRoster::GetDormantNodeFor(const media_node& node,
280734c72144SAxel Dörfler 	dormant_node_info* _info)
280852a38012Sejakowatz {
280985dfab2bSbeveloper 	CALLED();
281034c72144SAxel Dörfler 	if (_info == NULL)
281185dfab2bSbeveloper 		return B_BAD_VALUE;
281240f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
281385dfab2bSbeveloper 		return B_MEDIA_BAD_NODE;
281452a38012Sejakowatz 
281585dfab2bSbeveloper 	server_get_dormant_node_for_request request;
281685dfab2bSbeveloper 	server_get_dormant_node_for_reply reply;
281785dfab2bSbeveloper 	status_t rv;
281885dfab2bSbeveloper 
281985dfab2bSbeveloper 	request.node = node;
282085dfab2bSbeveloper 
282134c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request),
282234c72144SAxel Dörfler 		&reply, sizeof(reply));
282385dfab2bSbeveloper 	if (rv != B_OK)
282485dfab2bSbeveloper 		return rv;
282585dfab2bSbeveloper 
282634c72144SAxel Dörfler 	*_info = reply.node_info;
282785dfab2bSbeveloper 	return B_OK;
282852a38012Sejakowatz }
282952a38012Sejakowatz 
283034c72144SAxel Dörfler 
283152a38012Sejakowatz status_t
283234c72144SAxel Dörfler BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID,
283334c72144SAxel Dörfler 	dormant_flavor_info* _flavor)
283452a38012Sejakowatz {
283552a38012Sejakowatz 	CALLED();
283634c72144SAxel Dörfler 	if (_flavor == NULL)
28379bedd42cSbeveloper 		return B_BAD_VALUE;
283852a38012Sejakowatz 
2839e4c87231SAxel Dörfler 	// TODO: better use an area here as well!
284052a38012Sejakowatz 
2841e4c87231SAxel Dörfler 	server_get_dormant_flavor_info_reply* reply
2842e4c87231SAxel Dörfler 		= (server_get_dormant_flavor_info_reply*)malloc(16300);
284334c72144SAxel Dörfler 	if (reply == NULL)
284434c72144SAxel Dörfler 		return B_NO_MEMORY;
284552a38012Sejakowatz 
2846e4c87231SAxel Dörfler 	server_get_dormant_flavor_info_request request;
2847e4c87231SAxel Dörfler 	request.add_on_id = addonID;
2848e4c87231SAxel Dörfler 	request.flavor_id = flavorID;
2849e4c87231SAxel Dörfler 
2850e4c87231SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_DORMANT_FLAVOR_INFO, &request,
2851e4c87231SAxel Dörfler 		sizeof(request), reply, 16300);
28529dec2310SAxel Dörfler 	if (status != B_OK) {
285352a38012Sejakowatz 		free(reply);
28549dec2310SAxel Dörfler 		return status;
285552a38012Sejakowatz 	}
285652a38012Sejakowatz 
28579dec2310SAxel Dörfler 	if (reply->result == B_OK) {
28589dec2310SAxel Dörfler 		status = _flavor->Unflatten(reply->type, &reply->flattened_data,
28599dec2310SAxel Dörfler 			reply->flattened_size);
28609dec2310SAxel Dörfler 	} else
28619dec2310SAxel Dörfler 		status = reply->result;
286252a38012Sejakowatz 
286352a38012Sejakowatz 	free(reply);
28649dec2310SAxel Dörfler 	return status;
286552a38012Sejakowatz }
286652a38012Sejakowatz 
286734c72144SAxel Dörfler 
28688b04ffc1Sbeveloper status_t
286934c72144SAxel Dörfler BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info& dormant,
287034c72144SAxel Dörfler 	dormant_flavor_info* _flavor)
28718b04ffc1Sbeveloper {
287234c72144SAxel Dörfler 	return MediaRosterEx(this)->GetDormantFlavorInfo(dormant.addon,
287334c72144SAxel Dörfler 		dormant.flavor_id, _flavor);
28748b04ffc1Sbeveloper }
287552a38012Sejakowatz 
287634c72144SAxel Dörfler 
287760f15390Sbeveloper // Reports in outLatency the maximum latency found downstream from
287860f15390Sbeveloper // the specified BBufferProducer, producer, given the current connections.
287952a38012Sejakowatz status_t
288034c72144SAxel Dörfler BMediaRoster::GetLatencyFor(const media_node& producer, bigtime_t* _latency)
288152a38012Sejakowatz {
288260f15390Sbeveloper 	CALLED();
288334c72144SAxel Dörfler 	if (_latency == NULL)
288460f15390Sbeveloper 		return B_BAD_VALUE;
288534c72144SAxel Dörfler 	if (IS_INVALID_NODE(producer)
288634c72144SAxel Dörfler 		|| (producer.kind & B_BUFFER_PRODUCER) == 0)
288760f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
288860f15390Sbeveloper 
288960f15390Sbeveloper 	producer_get_latency_request request;
289060f15390Sbeveloper 	producer_get_latency_reply reply;
289160f15390Sbeveloper 	status_t rv;
289260f15390Sbeveloper 
289334c72144SAxel Dörfler 	rv = QueryPort(producer.port, PRODUCER_GET_LATENCY, &request,
289434c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
289560f15390Sbeveloper 	if (rv != B_OK)
289660f15390Sbeveloper 		return rv;
289760f15390Sbeveloper 
289834c72144SAxel Dörfler 	*_latency = reply.latency;
289960f15390Sbeveloper 
2900ab9afde3SMarcus Overhagen //	printf("BMediaRoster::GetLatencyFor producer %ld has maximum latency %Ld\n", producer.node, *out_latency);
2901aac800c2Sbeveloper 	return B_OK;
290252a38012Sejakowatz }
290352a38012Sejakowatz 
290452a38012Sejakowatz 
290552a38012Sejakowatz status_t
290652a38012Sejakowatz BMediaRoster::GetInitialLatencyFor(const media_node& producer,
290734c72144SAxel Dörfler 	bigtime_t* _latency, uint32* _flags)
290852a38012Sejakowatz {
2909b65a0ac5SJérôme Duval 	CALLED();
291034c72144SAxel Dörfler 	if (_latency == NULL)
2911b65a0ac5SJérôme Duval 		return B_BAD_VALUE;
291234c72144SAxel Dörfler 	if (IS_INVALID_NODE(producer)
291334c72144SAxel Dörfler 		|| (producer.kind & B_BUFFER_PRODUCER) == 0)
2914b65a0ac5SJérôme Duval 		return B_MEDIA_BAD_NODE;
2915b65a0ac5SJérôme Duval 
2916b65a0ac5SJérôme Duval 	producer_get_initial_latency_request request;
2917b65a0ac5SJérôme Duval 	producer_get_initial_latency_reply reply;
2918b65a0ac5SJérôme Duval 	status_t rv;
2919b65a0ac5SJérôme Duval 
292034c72144SAxel Dörfler 	rv = QueryPort(producer.port, PRODUCER_GET_INITIAL_LATENCY, &request,
292134c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2922b65a0ac5SJérôme Duval 	if (rv != B_OK)
2923b65a0ac5SJérôme Duval 		return rv;
2924b65a0ac5SJérôme Duval 
292534c72144SAxel Dörfler 	*_latency = reply.initial_latency;
292634c72144SAxel Dörfler 	if (_flags != NULL)
292734c72144SAxel Dörfler 		*_flags = reply.flags;
2928b65a0ac5SJérôme Duval 
2929332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::GetInitialLatencyFor producer %" B_PRId32 " has "
2930332cc6bcSAxel Dörfler 		"maximum initial latency %" B_PRId64 "\n", producer.node, *_latency);
2931aac800c2Sbeveloper 	return B_OK;
293252a38012Sejakowatz }
293352a38012Sejakowatz 
293452a38012Sejakowatz 
293552a38012Sejakowatz status_t
293634c72144SAxel Dörfler BMediaRoster::GetStartLatencyFor(const media_node& timeSource,
293734c72144SAxel Dörfler 	bigtime_t* _latency)
293852a38012Sejakowatz {
2939fc8b28b6SJérôme Duval 	CALLED();
294034c72144SAxel Dörfler 	if (_latency == NULL)
2941fc8b28b6SJérôme Duval 		return B_BAD_VALUE;
294234c72144SAxel Dörfler 	if (IS_INVALID_NODE(timeSource)
294334c72144SAxel Dörfler 		|| (timeSource.kind & B_TIME_SOURCE) == 0)
2944fc8b28b6SJérôme Duval 		return B_MEDIA_BAD_NODE;
2945fc8b28b6SJérôme Duval 
2946fc8b28b6SJérôme Duval 	timesource_get_start_latency_request request;
2947fc8b28b6SJérôme Duval 	timesource_get_start_latency_reply reply;
2948fc8b28b6SJérôme Duval 	status_t rv;
2949fc8b28b6SJérôme Duval 
295034c72144SAxel Dörfler 	rv = QueryPort(timeSource.port, TIMESOURCE_GET_START_LATENCY, &request,
295134c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2952fc8b28b6SJérôme Duval 	if (rv != B_OK)
2953fc8b28b6SJérôme Duval 		return rv;
2954fc8b28b6SJérôme Duval 
295534c72144SAxel Dörfler 	*_latency = reply.start_latency;
2956fc8b28b6SJérôme Duval 
2957332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::GetStartLatencyFor timesource %" B_PRId32 " has "
2958332cc6bcSAxel Dörfler 		"maximum initial latency %" B_PRId64 "\n", timeSource.node, *_latency);
2959aac800c2Sbeveloper 	return B_OK;
296052a38012Sejakowatz }
296152a38012Sejakowatz 
296252a38012Sejakowatz 
296352a38012Sejakowatz status_t
296434c72144SAxel Dörfler BMediaRoster::GetFileFormatsFor(const media_node& fileInterface,
296534c72144SAxel Dörfler 	media_file_format* _formats, int32* _numFormats)
296652a38012Sejakowatz {
2967b6f0f884SDario Casalinuovo 	CALLED();
2968b6f0f884SDario Casalinuovo 
2969b6f0f884SDario Casalinuovo 	if (IS_INVALID_NODE(fileInterface)
2970b6f0f884SDario Casalinuovo 		|| (fileInterface.kind & B_FILE_INTERFACE) == 0)
2971b6f0f884SDario Casalinuovo 		return B_MEDIA_BAD_NODE;
2972b6f0f884SDario Casalinuovo 
2973b6f0f884SDario Casalinuovo 	if (_numFormats == NULL || *_numFormats < 1)
2974b6f0f884SDario Casalinuovo 		return B_BAD_VALUE;
2975b6f0f884SDario Casalinuovo 
2976b6f0f884SDario Casalinuovo 	fileinterface_get_formats_request request;
2977b6f0f884SDario Casalinuovo 	fileinterface_get_formats_reply reply;
2978b6f0f884SDario Casalinuovo 
2979b6f0f884SDario Casalinuovo 	media_file_format* formats;
2980b6f0f884SDario Casalinuovo 	size_t needSize = sizeof(media_file_format) * *_numFormats;
2981b6f0f884SDario Casalinuovo 	size_t size = (needSize + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
2982b6f0f884SDario Casalinuovo 
2983b6f0f884SDario Casalinuovo 	area_id area = create_area("formats area", (void**)&formats,
2984b6f0f884SDario Casalinuovo 		B_ANY_ADDRESS, size, B_NO_LOCK,
2985b6f0f884SDario Casalinuovo 		B_READ_AREA | B_WRITE_AREA);
2986b6f0f884SDario Casalinuovo 
2987b6f0f884SDario Casalinuovo 	if (area < 0)
2988b6f0f884SDario Casalinuovo 		return B_NO_MEMORY;
2989b6f0f884SDario Casalinuovo 
2990b6f0f884SDario Casalinuovo 	request.num_formats = *_numFormats;
2991b6f0f884SDario Casalinuovo 	request.data_area = area;
2992b6f0f884SDario Casalinuovo 
2993b6f0f884SDario Casalinuovo 	status_t status = QueryPort(fileInterface.port,
2994b6f0f884SDario Casalinuovo 		FILEINTERFACE_GET_FORMATS, &request,
2995b6f0f884SDario Casalinuovo 		sizeof(request), &reply, sizeof(reply));
2996b6f0f884SDario Casalinuovo 
2997b6f0f884SDario Casalinuovo 	if (status == B_OK) {
2998b6f0f884SDario Casalinuovo 		memcpy(_formats, formats, sizeof(media_file_format)*reply.filled_slots);
2999b6f0f884SDario Casalinuovo 		*_numFormats = reply.filled_slots;
3000b6f0f884SDario Casalinuovo 	}
3001b6f0f884SDario Casalinuovo 	delete_area(area);
3002b6f0f884SDario Casalinuovo 	return status;
300352a38012Sejakowatz }
300452a38012Sejakowatz 
300552a38012Sejakowatz 
300652a38012Sejakowatz status_t
300734c72144SAxel Dörfler BMediaRoster::SetRefFor(const media_node& file_interface, const entry_ref& file,
300834c72144SAxel Dörfler 	bool createAndTruncate, bigtime_t* _length)
300952a38012Sejakowatz {
30106938364bSMaurice Kalinowski 	CALLED();
30116938364bSMaurice Kalinowski 
301242d17c1aSDario Casalinuovo 	if (IS_INVALID_NODE(file_interface)
301342d17c1aSDario Casalinuovo 		|| (file_interface.kind & B_FILE_INTERFACE) == 0)
301442d17c1aSDario Casalinuovo 		return B_MEDIA_BAD_NODE;
301542d17c1aSDario Casalinuovo 
30166938364bSMaurice Kalinowski 	fileinterface_set_ref_request request;
30176938364bSMaurice Kalinowski 	fileinterface_set_ref_reply reply;
30186938364bSMaurice Kalinowski 	status_t rv;
30196938364bSMaurice Kalinowski 
30206938364bSMaurice Kalinowski 	request.device = file.device;
30216938364bSMaurice Kalinowski 	request.directory = file.directory;
30226938364bSMaurice Kalinowski 	strcpy(request.name, file.name);
302334c72144SAxel Dörfler 	request.create = createAndTruncate;
302434c72144SAxel Dörfler 	if (_length != NULL)
302534c72144SAxel Dörfler 		request.duration = *_length;
30266938364bSMaurice Kalinowski 
302734c72144SAxel Dörfler 	rv = QueryPort(file_interface.port, FILEINTERFACE_SET_REF, &request,
302834c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
30296938364bSMaurice Kalinowski 	if (rv != B_OK)
30306938364bSMaurice Kalinowski 		return rv;
30316938364bSMaurice Kalinowski 
303234c72144SAxel Dörfler 	if (!createAndTruncate && _length)
303334c72144SAxel Dörfler 		*_length = reply.duration;
30346938364bSMaurice Kalinowski 
30356938364bSMaurice Kalinowski 	return B_OK;
303652a38012Sejakowatz }
303752a38012Sejakowatz 
303852a38012Sejakowatz 
303952a38012Sejakowatz status_t
304034c72144SAxel Dörfler BMediaRoster::GetRefFor(const media_node& node, entry_ref* _file,
304134c72144SAxel Dörfler 	BMimeType* mimeType)
304252a38012Sejakowatz {
30436938364bSMaurice Kalinowski 	CALLED();
30446938364bSMaurice Kalinowski 
304542d17c1aSDario Casalinuovo 	if (IS_INVALID_NODE(node)
304642d17c1aSDario Casalinuovo 		|| (node.kind & B_FILE_INTERFACE) == 0)
304742d17c1aSDario Casalinuovo 		return B_MEDIA_BAD_NODE;
304842d17c1aSDario Casalinuovo 
304934c72144SAxel Dörfler 	if (!_file)
30506938364bSMaurice Kalinowski 		return B_BAD_VALUE;
30516938364bSMaurice Kalinowski 
30526938364bSMaurice Kalinowski 	fileinterface_get_ref_request request;
30536938364bSMaurice Kalinowski 	fileinterface_get_ref_reply reply;
30546938364bSMaurice Kalinowski 	status_t rv;
30556938364bSMaurice Kalinowski 
305634c72144SAxel Dörfler 	rv = QueryPort(node.port, FILEINTERFACE_GET_REF, &request, sizeof(request),
305734c72144SAxel Dörfler 		&reply, sizeof(reply));
30586938364bSMaurice Kalinowski 	if (rv != B_OK)
30596938364bSMaurice Kalinowski 		return rv;
30606938364bSMaurice Kalinowski 
306134c72144SAxel Dörfler 	*_file = entry_ref(reply.device, reply.directory, reply.name);
30626938364bSMaurice Kalinowski 
306334c72144SAxel Dörfler 	if (mimeType)
306434c72144SAxel Dörfler 		mimeType->SetTo(reply.mimetype);
30656938364bSMaurice Kalinowski 
30666938364bSMaurice Kalinowski 	return B_OK;
306752a38012Sejakowatz }
306852a38012Sejakowatz 
306952a38012Sejakowatz 
307052a38012Sejakowatz status_t
307152a38012Sejakowatz BMediaRoster::SniffRefFor(const media_node& file_interface,
307234c72144SAxel Dörfler 	const entry_ref& file, BMimeType* mimeType, float* _capability)
307352a38012Sejakowatz {
30746938364bSMaurice Kalinowski 	CALLED();
307542d17c1aSDario Casalinuovo 
307642d17c1aSDario Casalinuovo 	if (IS_INVALID_NODE(file_interface)
307742d17c1aSDario Casalinuovo 		|| (file_interface.kind & B_FILE_INTERFACE) == 0)
307842d17c1aSDario Casalinuovo 		return B_MEDIA_BAD_NODE;
307942d17c1aSDario Casalinuovo 
308034c72144SAxel Dörfler 	if (mimeType == NULL || _capability == NULL)
30816938364bSMaurice Kalinowski 		return B_BAD_VALUE;
30826938364bSMaurice Kalinowski 
30836938364bSMaurice Kalinowski 	fileinterface_sniff_ref_request request;
30846938364bSMaurice Kalinowski 	fileinterface_sniff_ref_reply reply;
30856938364bSMaurice Kalinowski 	status_t rv;
30866938364bSMaurice Kalinowski 
30876938364bSMaurice Kalinowski 	request.device = file.device;
30886938364bSMaurice Kalinowski 	request.directory = file.directory;
30896938364bSMaurice Kalinowski 	strcpy(request.name, file.name);
30906938364bSMaurice Kalinowski 
309134c72144SAxel Dörfler 	rv = QueryPort(file_interface.port, FILEINTERFACE_SNIFF_REF, &request,
309234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
30936938364bSMaurice Kalinowski 	if (rv != B_OK)
30946938364bSMaurice Kalinowski 		return rv;
30956938364bSMaurice Kalinowski 
309634c72144SAxel Dörfler 	mimeType->SetTo(reply.mimetype);
309734c72144SAxel Dörfler 	*_capability = reply.capability;
30986938364bSMaurice Kalinowski 
30996938364bSMaurice Kalinowski 	return B_OK;
310052a38012Sejakowatz }
310152a38012Sejakowatz 
310252a38012Sejakowatz 
310334c72144SAxel Dörfler /*!	This is the generic "here's a file, now can someone please play it"
310434c72144SAxel Dörfler 	interface.
310534c72144SAxel Dörfler */
310652a38012Sejakowatz status_t
310734c72144SAxel Dörfler BMediaRoster::SniffRef(const entry_ref& file, uint64 requireNodeKinds,
310834c72144SAxel Dörfler 	dormant_node_info* _node, BMimeType* mimeType)
310952a38012Sejakowatz {
311005f452c3SDavid McPaul 	CALLED();
311105f452c3SDavid McPaul 
3112332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SniffRef looking for a node to handle %s: 0x%" B_PRIx64
3113332cc6bcSAxel Dörfler 		"\n", file.name, requireNodeKinds);
311405f452c3SDavid McPaul 
311505f452c3SDavid McPaul 	if (_node == NULL)
311605f452c3SDavid McPaul 		return B_BAD_VALUE;
311705f452c3SDavid McPaul 
311805f452c3SDavid McPaul 	BMimeType aMimeType;
311905f452c3SDavid McPaul 
312005f452c3SDavid McPaul 	dormant_node_info nodes[30];
312105f452c3SDavid McPaul 	int32 count = 30;
312205f452c3SDavid McPaul 	int32 highestCapability = -1;
312305f452c3SDavid McPaul 	float capability;
312405f452c3SDavid McPaul 
312505f452c3SDavid McPaul 	media_node node;
312605f452c3SDavid McPaul 
312705f452c3SDavid McPaul 	// Get all dormant nodes using GetDormantNodes
31286f7f87a2SDavid McPaul 	if (GetDormantNodes(nodes, &count, NULL, NULL, NULL, requireNodeKinds | B_FILE_INTERFACE, 0) == B_OK) {
312905f452c3SDavid McPaul 		// Call SniffRefFor on each node that matches requireNodeKinds
313005f452c3SDavid McPaul 		for (int32 i=0;i<count;i++) {
31316f7f87a2SDavid McPaul 			if (InstantiateDormantNode(nodes[i], &node) == B_OK) {
313205f452c3SDavid McPaul 
31336f7f87a2SDavid McPaul 				if (SniffRefFor(node, file, &aMimeType, &capability) == B_OK) {
313405f452c3SDavid McPaul 					// find the first node that has 100% capability
313505f452c3SDavid McPaul 					TRACE("%s has a %f%% chance of playing file\n",nodes[i].name, capability * 100.0);
313605f452c3SDavid McPaul 					if (capability == 1.0) {
313705f452c3SDavid McPaul 						highestCapability = i;
313805f452c3SDavid McPaul 						break;
313905f452c3SDavid McPaul 					}
314005f452c3SDavid McPaul 				}
314105f452c3SDavid McPaul 				ReleaseNode(node);
314205f452c3SDavid McPaul 			}
314305f452c3SDavid McPaul 		}
314405f452c3SDavid McPaul 
314505f452c3SDavid McPaul 		if (highestCapability != -1) {
314605f452c3SDavid McPaul 			*_node = nodes[highestCapability];
314705f452c3SDavid McPaul 
3148332cc6bcSAxel Dörfler 			TRACE("BMediaRoster::SniffRef: found a node %s addon-id %" B_PRId32
3149332cc6bcSAxel Dörfler 				", flavor_id %" B_PRId32 "\n",
3150332cc6bcSAxel Dörfler 			nodes[highestCapability].name, nodes[highestCapability].addon,
3151332cc6bcSAxel Dörfler 				nodes[highestCapability].flavor_id);
315205f452c3SDavid McPaul 
315305f452c3SDavid McPaul 			if (mimeType != NULL) {
315405f452c3SDavid McPaul 				//*mimeType = aMimeType; -- need a copy constructor
315505f452c3SDavid McPaul 			}
315605f452c3SDavid McPaul 
315705f452c3SDavid McPaul 			return B_OK;
315805f452c3SDavid McPaul 		}
315905f452c3SDavid McPaul 
316005f452c3SDavid McPaul 	}
316105f452c3SDavid McPaul 
316252a38012Sejakowatz 	return B_ERROR;
316352a38012Sejakowatz }
316452a38012Sejakowatz 
316552a38012Sejakowatz 
316652a38012Sejakowatz status_t
316752a38012Sejakowatz BMediaRoster::GetDormantNodeForType(const BMimeType& type,
316834c72144SAxel Dörfler 	uint64 requireNodeKinds, dormant_node_info* _node)
316952a38012Sejakowatz {
317052a38012Sejakowatz 	UNIMPLEMENTED();
317152a38012Sejakowatz 	return B_ERROR;
317252a38012Sejakowatz }
317352a38012Sejakowatz 
317452a38012Sejakowatz 
317552a38012Sejakowatz status_t
317634c72144SAxel Dörfler BMediaRoster::GetReadFileFormatsFor(const dormant_node_info& node,
317734c72144SAxel Dörfler 	media_file_format* _readFormats, int32 readCount, int32* _readCount)
317852a38012Sejakowatz {
317952a38012Sejakowatz 	UNIMPLEMENTED();
318052a38012Sejakowatz 	return B_ERROR;
318152a38012Sejakowatz }
318252a38012Sejakowatz 
318352a38012Sejakowatz 
318452a38012Sejakowatz status_t
318534c72144SAxel Dörfler BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info& node,
318634c72144SAxel Dörfler 	media_file_format* _write_formats, int32 writeCount, int32* _writeCount)
318752a38012Sejakowatz {
318852a38012Sejakowatz 	UNIMPLEMENTED();
318952a38012Sejakowatz 	return B_ERROR;
319052a38012Sejakowatz }
319152a38012Sejakowatz 
319252a38012Sejakowatz 
319352a38012Sejakowatz status_t
319434c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_output& output, media_format* _format,
319552a38012Sejakowatz 	uint32 flags)
319652a38012Sejakowatz {
31979bedd42cSbeveloper 	CALLED();
319834c72144SAxel Dörfler 	if (_format == NULL)
31999bedd42cSbeveloper 		return B_BAD_VALUE;
32009bedd42cSbeveloper 	if ((output.node.kind & B_BUFFER_PRODUCER) == 0)
32019bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
32029bedd42cSbeveloper 	if (IS_INVALID_SOURCE(output.source))
32039bedd42cSbeveloper 		return B_MEDIA_BAD_SOURCE;
32049bedd42cSbeveloper 
32059bedd42cSbeveloper 	producer_format_suggestion_requested_request request;
32069bedd42cSbeveloper 	producer_format_suggestion_requested_reply reply;
32079bedd42cSbeveloper 	status_t rv;
32089bedd42cSbeveloper 
32099bedd42cSbeveloper 	request.type = B_MEDIA_UNKNOWN_TYPE;
321034c72144SAxel Dörfler 	request.quality = 0; // TODO: what should this be?
32119bedd42cSbeveloper 
321234c72144SAxel Dörfler 	rv = QueryPort(output.source.port, PRODUCER_FORMAT_SUGGESTION_REQUESTED,
321334c72144SAxel Dörfler 		&request, sizeof(request), &reply, sizeof(reply));
32149bedd42cSbeveloper 	if (rv != B_OK)
32159bedd42cSbeveloper 		return rv;
32169bedd42cSbeveloper 
321734c72144SAxel Dörfler 	*_format = reply.format;
32189bedd42cSbeveloper 	return B_OK;
321952a38012Sejakowatz }
322052a38012Sejakowatz 
322152a38012Sejakowatz 
322252a38012Sejakowatz status_t
322334c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_input& input, media_format* _format,
322452a38012Sejakowatz 	uint32 flags)
322552a38012Sejakowatz {
32269bedd42cSbeveloper 	CALLED();
322734c72144SAxel Dörfler 	if (_format == NULL)
32289bedd42cSbeveloper 		return B_BAD_VALUE;
32299bedd42cSbeveloper 	if ((input.node.kind & B_BUFFER_CONSUMER) == 0)
32309bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
32319bedd42cSbeveloper 	if (IS_INVALID_DESTINATION(input.destination))
32329bedd42cSbeveloper 		return B_MEDIA_BAD_DESTINATION;
32339bedd42cSbeveloper 
32349bedd42cSbeveloper 	consumer_accept_format_request request;
32359bedd42cSbeveloper 	consumer_accept_format_reply reply;
32369bedd42cSbeveloper 	status_t rv;
32379bedd42cSbeveloper 
32389bedd42cSbeveloper 	request.dest = input.destination;
323912ed45b6SMurai Takashi 	request.format.Clear(); // wildcard
32409bedd42cSbeveloper 
324134c72144SAxel Dörfler 	rv = QueryPort(input.destination.port, CONSUMER_ACCEPT_FORMAT, &request,
324234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
32439bedd42cSbeveloper 	if (rv != B_OK)
32449bedd42cSbeveloper 		return rv;
32459bedd42cSbeveloper 
324634c72144SAxel Dörfler 	*_format = reply.format;
32479bedd42cSbeveloper 	return B_OK;
324852a38012Sejakowatz }
324952a38012Sejakowatz 
325052a38012Sejakowatz 
325152a38012Sejakowatz status_t
325234c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_node& node, media_format* _format,
325352a38012Sejakowatz 	float quality)
325452a38012Sejakowatz {
325552a38012Sejakowatz 	UNIMPLEMENTED();
325634c72144SAxel Dörfler 	if (_format == NULL)
32579bedd42cSbeveloper 		return B_BAD_VALUE;
32589bedd42cSbeveloper 	if (IS_INVALID_NODE(node))
32599bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
32609bedd42cSbeveloper 	if ((node.kind & (B_BUFFER_CONSUMER | B_BUFFER_PRODUCER)) == 0)
32619bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
32629bedd42cSbeveloper 
326352a38012Sejakowatz 	return B_ERROR;
326452a38012Sejakowatz }
326552a38012Sejakowatz 
326652a38012Sejakowatz 
326752a38012Sejakowatz ssize_t
326852a38012Sejakowatz BMediaRoster::GetNodeAttributesFor(const media_node& node,
326934c72144SAxel Dörfler 	media_node_attribute* _array, size_t maxCount)
327052a38012Sejakowatz {
3271c079d8d6SDario Casalinuovo 	CALLED();
3272c079d8d6SDario Casalinuovo 
3273c079d8d6SDario Casalinuovo 	if (IS_INVALID_NODE(node))
3274c079d8d6SDario Casalinuovo 		return B_MEDIA_BAD_NODE;
3275c079d8d6SDario Casalinuovo 
3276c079d8d6SDario Casalinuovo 	node_get_attributes_for_request request;
3277c079d8d6SDario Casalinuovo 	node_get_attributes_for_reply reply;
3278c079d8d6SDario Casalinuovo 	status_t status;
3279c079d8d6SDario Casalinuovo 
3280c079d8d6SDario Casalinuovo 	media_node_attribute* addr = NULL;
3281c079d8d6SDario Casalinuovo 	size_t totalSize = maxCount*sizeof(media_node_attribute);
3282c079d8d6SDario Casalinuovo 	size_t size = (totalSize + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
3283c079d8d6SDario Casalinuovo 
3284c079d8d6SDario Casalinuovo 	area_id dataArea = create_area("attributes area", (void**)&addr,
3285c079d8d6SDario Casalinuovo 		B_ANY_ADDRESS, size, B_NO_LOCK,
3286c079d8d6SDario Casalinuovo 		B_READ_AREA | B_WRITE_AREA);
3287c079d8d6SDario Casalinuovo 	// No need to memset the padding
3288c079d8d6SDario Casalinuovo 	memset(addr, 0, totalSize);
3289c079d8d6SDario Casalinuovo 
3290c079d8d6SDario Casalinuovo 	if (dataArea < 0)
3291c079d8d6SDario Casalinuovo 		return B_NO_MEMORY;
3292c079d8d6SDario Casalinuovo 
3293c079d8d6SDario Casalinuovo 	request.count = maxCount;
3294c079d8d6SDario Casalinuovo 	request.area = dataArea;
3295c079d8d6SDario Casalinuovo 
3296c079d8d6SDario Casalinuovo 	status = QueryPort(node.port, NODE_GET_ATTRIBUTES_FOR, &request,
3297c079d8d6SDario Casalinuovo 		sizeof(request), &reply, sizeof(reply));
3298c079d8d6SDario Casalinuovo 	if (status != B_OK)
3299c079d8d6SDario Casalinuovo 		return status;
3300c079d8d6SDario Casalinuovo 
3301c079d8d6SDario Casalinuovo 	memcpy(_array, addr, reply.filled_count
3302c079d8d6SDario Casalinuovo 		* sizeof(media_node_attribute));
3303c079d8d6SDario Casalinuovo 
3304c079d8d6SDario Casalinuovo 	delete_area(dataArea);
3305c079d8d6SDario Casalinuovo 	return reply.filled_count;
330652a38012Sejakowatz }
330752a38012Sejakowatz 
330852a38012Sejakowatz 
330952a38012Sejakowatz media_node_id
331034c72144SAxel Dörfler BMediaRoster::NodeIDFor(port_id port)
331152a38012Sejakowatz {
33129e9417d2Sbeveloper 	CALLED();
33139e9417d2Sbeveloper 
33149e9417d2Sbeveloper 	server_node_id_for_request request;
33159e9417d2Sbeveloper 	server_node_id_for_reply reply;
33169e9417d2Sbeveloper 	status_t rv;
33179e9417d2Sbeveloper 
331834c72144SAxel Dörfler 	request.port = port;
33199e9417d2Sbeveloper 
332034c72144SAxel Dörfler 	rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply,
332134c72144SAxel Dörfler 		sizeof(reply));
33229e9417d2Sbeveloper 	if (rv != B_OK) {
3323332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::NodeIDFor: failed (error %#" B_PRIx32 ")\n", rv);
33249e9417d2Sbeveloper 		return -1;
33259e9417d2Sbeveloper 	}
33269e9417d2Sbeveloper 
33279dec2310SAxel Dörfler 	return reply.node_id;
332852a38012Sejakowatz }
332952a38012Sejakowatz 
333052a38012Sejakowatz 
333152a38012Sejakowatz status_t
333234c72144SAxel Dörfler BMediaRoster::GetInstancesFor(media_addon_id addon, int32 flavor,
333334c72144SAxel Dörfler 	media_node_id* _id, int32* _count)
333452a38012Sejakowatz {
333585dfab2bSbeveloper 	CALLED();
333634c72144SAxel Dörfler 	if (_id == NULL)
333785dfab2bSbeveloper 		return B_BAD_VALUE;
333834c72144SAxel Dörfler 	if (_count && *_count <= 0)
333985dfab2bSbeveloper 		return B_BAD_VALUE;
334085dfab2bSbeveloper 
334185dfab2bSbeveloper 	server_get_instances_for_request request;
334285dfab2bSbeveloper 	server_get_instances_for_reply reply;
334385dfab2bSbeveloper 	status_t rv;
334485dfab2bSbeveloper 
33459c3b4706SAxel Dörfler 	request.max_count = (_count ? *_count : 1);
33469c3b4706SAxel Dörfler 	request.add_on_id = addon;
33479c3b4706SAxel Dörfler 	request.flavor_id = flavor;
334885dfab2bSbeveloper 
334934c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_INSTANCES_FOR, &request, sizeof(request),
335034c72144SAxel Dörfler 		&reply, sizeof(reply));
335185dfab2bSbeveloper 	if (rv != B_OK) {
33525ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetLiveNodes failed\n");
335385dfab2bSbeveloper 		return rv;
335452a38012Sejakowatz 	}
335552a38012Sejakowatz 
335634c72144SAxel Dörfler 	if (_count)
335734c72144SAxel Dörfler 		*_count = reply.count;
335885dfab2bSbeveloper 	if (reply.count > 0)
335934c72144SAxel Dörfler 		memcpy(_id, reply.node_id, sizeof(media_node_id) * reply.count);
336085dfab2bSbeveloper 
336185dfab2bSbeveloper 	return B_OK;
336285dfab2bSbeveloper }
336352a38012Sejakowatz 
336452a38012Sejakowatz 
336567483edaSDario Casalinuovo bool
336667483edaSDario Casalinuovo BMediaRoster::IsRunning()
336767483edaSDario Casalinuovo {
3368d009f286SDario Casalinuovo 	return be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)
3369d009f286SDario Casalinuovo 		&& be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE);
337067483edaSDario Casalinuovo }
337167483edaSDario Casalinuovo 
337267483edaSDario Casalinuovo 
337352a38012Sejakowatz ssize_t
337434c72144SAxel Dörfler BMediaRoster::AudioBufferSizeFor(int32 channelCount, uint32 sampleFormat,
337534c72144SAxel Dörfler 	float frameRate, bus_type busKind)
337652a38012Sejakowatz {
337734c72144SAxel Dörfler 	bigtime_t bufferDuration;
337834c72144SAxel Dörfler 	ssize_t bufferSize;
3379df6c2e83Sbeveloper 
33804c125ccaSPawel Dziepak 	if (busKind == B_ISA_BUS || busKind == B_PCMCIA_BUS)
338134c72144SAxel Dörfler 		bufferDuration = 25000;
33824c125ccaSPawel Dziepak 	else
33834c125ccaSPawel Dziepak 		bufferDuration = 10000;
3384df6c2e83Sbeveloper 
338534c72144SAxel Dörfler 	bufferSize = (sampleFormat & 0xf) * channelCount
338634c72144SAxel Dörfler 		* (ssize_t)((frameRate * bufferDuration) / 1000000.0);
3387df6c2e83Sbeveloper 
3388332cc6bcSAxel Dörfler 	printf("Suggested buffer duration %" B_PRId64 ", size %" B_PRIdSSIZE "\n",
3389332cc6bcSAxel Dörfler 		bufferDuration, bufferSize);
3390df6c2e83Sbeveloper 
339134c72144SAxel Dörfler 	return bufferSize;
339252a38012Sejakowatz }
339352a38012Sejakowatz 
339452a38012Sejakowatz 
339534c72144SAxel Dörfler /*!	Use MediaFlags to inquire about specific features of the Media Kit.
339634c72144SAxel Dörfler 	Returns < 0 for "not present", positive size for output data size.
339734c72144SAxel Dörfler 	0 means that the capability is present, but no data about it.
339834c72144SAxel Dörfler */
339952a38012Sejakowatz /*static*/ ssize_t
340034c72144SAxel Dörfler BMediaRoster::MediaFlags(media_flags cap, void* buffer, size_t maxSize)
340152a38012Sejakowatz {
340252a38012Sejakowatz 	UNIMPLEMENTED();
340352a38012Sejakowatz 	return 0;
340452a38012Sejakowatz }
340552a38012Sejakowatz 
340652a38012Sejakowatz 
340734c72144SAxel Dörfler //	#pragma mark - BLooper overrides
340834c72144SAxel Dörfler 
340934c72144SAxel Dörfler 
341034c72144SAxel Dörfler void
341152a38012Sejakowatz BMediaRoster::MessageReceived(BMessage* message)
341252a38012Sejakowatz {
3413cf4e2277Sbeveloper 	switch (message->what) {
341432afe10aSDario Casalinuovo 		case MEDIA_ROSTER_REQUEST_NOTIFICATIONS:
341532afe10aSDario Casalinuovo 		{
341632afe10aSDario Casalinuovo 			RosterNotification notification;
341732afe10aSDario Casalinuovo 			if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
341832afe10aSDario Casalinuovo 					!= B_OK) {
341932afe10aSDario Casalinuovo 				TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
342032afe10aSDario Casalinuovo 					"find what parameter");
342132afe10aSDario Casalinuovo 				return;
342232afe10aSDario Casalinuovo 			}
342332afe10aSDario Casalinuovo 			if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
342432afe10aSDario Casalinuovo 					&notification.messenger) != B_OK) {
342532afe10aSDario Casalinuovo 				TRACE("BMediaRoster MEDIA_ROSTER_REQUEST_NOTIFICATIONS can't"
342632afe10aSDario Casalinuovo 					"find messenger");
342732afe10aSDario Casalinuovo 				return;
342832afe10aSDario Casalinuovo 			}
342932afe10aSDario Casalinuovo 			sNotificationList.Insert(notification);
343032afe10aSDario Casalinuovo 			return;
343132afe10aSDario Casalinuovo 		}
343232afe10aSDario Casalinuovo 
343332afe10aSDario Casalinuovo 		case MEDIA_ROSTER_CANCEL_NOTIFICATIONS:
343432afe10aSDario Casalinuovo 		{
343532afe10aSDario Casalinuovo 			RosterNotification notification;
343632afe10aSDario Casalinuovo 			if (message->FindInt32(NOTIFICATION_PARAM_WHAT, &notification.what)
343732afe10aSDario Casalinuovo 					!= B_OK) {
343832afe10aSDario Casalinuovo 				TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
343932afe10aSDario Casalinuovo 					"find what parameter");
344032afe10aSDario Casalinuovo 				return;
344132afe10aSDario Casalinuovo 			}
344232afe10aSDario Casalinuovo 			if (message->FindMessenger(NOTIFICATION_PARAM_MESSENGER,
344332afe10aSDario Casalinuovo 					&notification.messenger) != B_OK) {
344432afe10aSDario Casalinuovo 				TRACE("BMediaRoster MEDIA_ROSTER_CANCEL_NOTIFICATIONS can't"
344532afe10aSDario Casalinuovo 					"find messenger");
344632afe10aSDario Casalinuovo 				return;
344732afe10aSDario Casalinuovo 			}
344832afe10aSDario Casalinuovo 			for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
344932afe10aSDario Casalinuovo 				RosterNotification* current;
345032afe10aSDario Casalinuovo 				if (sNotificationList.Get(i, &current) != true)
345132afe10aSDario Casalinuovo 					return;
345232afe10aSDario Casalinuovo 				if (current->what == notification.what
345332afe10aSDario Casalinuovo 						&& current->messenger == notification.messenger) {
345432afe10aSDario Casalinuovo 					sNotificationList.Remove(i);
345532afe10aSDario Casalinuovo 					return;
345632afe10aSDario Casalinuovo 				}
345732afe10aSDario Casalinuovo 			}
345832afe10aSDario Casalinuovo 			return;
345932afe10aSDario Casalinuovo 		}
346032afe10aSDario Casalinuovo 
346132afe10aSDario Casalinuovo 		case B_SOME_APP_LAUNCHED:
346232afe10aSDario Casalinuovo 		{
346332afe10aSDario Casalinuovo 			BString mimeSig;
346432afe10aSDario Casalinuovo 			if (message->FindString("be:signature", &mimeSig) != B_OK)
346532afe10aSDario Casalinuovo 				return;
346632afe10aSDario Casalinuovo 			if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
346732afe10aSDario Casalinuovo 					&& mimeSig != B_MEDIA_SERVER_SIGNATURE)
346832afe10aSDario Casalinuovo 				return;
346932afe10aSDario Casalinuovo 
347032afe10aSDario Casalinuovo 			TRACE("BMediaRoster::MessageReceived media services are going up.");
347132afe10aSDario Casalinuovo 
347232afe10aSDario Casalinuovo 			if (BMediaRoster::IsRunning()) {
347311c7bd86SDario Casalinuovo 				// Wait for media services to wake up and restore our friendship
347432afe10aSDario Casalinuovo 				if (MediaRosterEx(this)->BuildConnections() != B_OK) {
347532afe10aSDario Casalinuovo 					TRACE("BMediaRoster::MessageReceived can't reconnect"
347632afe10aSDario Casalinuovo 						"to media_server.");
347732afe10aSDario Casalinuovo 				}
347832afe10aSDario Casalinuovo 			}
347932afe10aSDario Casalinuovo 			return;
348032afe10aSDario Casalinuovo 		}
348132afe10aSDario Casalinuovo 
348232afe10aSDario Casalinuovo 		case B_SOME_APP_QUIT:
348332afe10aSDario Casalinuovo 		{
348432afe10aSDario Casalinuovo 			BString mimeSig;
348532afe10aSDario Casalinuovo 			if (message->FindString("be:signature", &mimeSig) != B_OK)
348632afe10aSDario Casalinuovo 				return;
348732afe10aSDario Casalinuovo 			if (mimeSig != B_MEDIA_ADDON_SERVER_SIGNATURE
348832afe10aSDario Casalinuovo 					&& mimeSig != B_MEDIA_SERVER_SIGNATURE)
348932afe10aSDario Casalinuovo 				return;
349032afe10aSDario Casalinuovo 
349132afe10aSDario Casalinuovo 			TRACE("BMediaRoster::MessageReceived media services are down.");
349232afe10aSDario Casalinuovo 
349332afe10aSDario Casalinuovo 			// Send the notification to our subscribers
349432afe10aSDario Casalinuovo 			if (!BMediaRoster::IsRunning() && sServerIsUp == true) {
349532afe10aSDario Casalinuovo 				sServerIsUp = false;
349632afe10aSDario Casalinuovo 				for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
349732afe10aSDario Casalinuovo 					RosterNotification* current;
349832afe10aSDario Casalinuovo 					if (sNotificationList.Get(i, &current) != true)
349932afe10aSDario Casalinuovo 						return;
350032afe10aSDario Casalinuovo 					if (current->what == B_MEDIA_SERVER_QUIT) {
350132afe10aSDario Casalinuovo 						if (current->messenger.SendMessage(
350232afe10aSDario Casalinuovo 								B_MEDIA_SERVER_QUIT) != B_OK) {
350332afe10aSDario Casalinuovo 							if(!current->messenger.IsValid())
350432afe10aSDario Casalinuovo 								sNotificationList.Remove(i);
350532afe10aSDario Casalinuovo 						}
350632afe10aSDario Casalinuovo 					}
350732afe10aSDario Casalinuovo 				}
350832afe10aSDario Casalinuovo 			}
350932afe10aSDario Casalinuovo 			return;
351032afe10aSDario Casalinuovo 		}
351132afe10aSDario Casalinuovo 
351211c7bd86SDario Casalinuovo 		case MEDIA_SERVER_ALIVE:
351311c7bd86SDario Casalinuovo 		{
351411c7bd86SDario Casalinuovo 			if (!BMediaRoster::IsRunning())
351511c7bd86SDario Casalinuovo 				return;
351611c7bd86SDario Casalinuovo 
351711c7bd86SDario Casalinuovo 			sServerIsUp = true;
351811c7bd86SDario Casalinuovo 
351911c7bd86SDario Casalinuovo 			TRACE("BMediaRoster::MessageReceived media services are"
352011c7bd86SDario Casalinuovo 				" finally up.");
352111c7bd86SDario Casalinuovo 
352276889670SDario Casalinuovo 			if (MediaRosterEx(this)->fLaunchNotification) {
352376889670SDario Casalinuovo 				progress_startup(100, NULL, NULL);
352476889670SDario Casalinuovo 				if (MediaRosterEx(this)->fAutoExit)
352576889670SDario Casalinuovo 					MediaRosterEx(this)->fLaunchNotification = false;
352676889670SDario Casalinuovo 			}
352776889670SDario Casalinuovo 
352811c7bd86SDario Casalinuovo 			// Send the notification to our subscribers
352911c7bd86SDario Casalinuovo 			for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
353011c7bd86SDario Casalinuovo 				RosterNotification* current;
353111c7bd86SDario Casalinuovo 				if (sNotificationList.Get(i, &current) != true)
353211c7bd86SDario Casalinuovo 					return;
353311c7bd86SDario Casalinuovo 				if (current->what == B_MEDIA_SERVER_STARTED) {
353411c7bd86SDario Casalinuovo 					if (current->messenger.SendMessage(
353511c7bd86SDario Casalinuovo 							B_MEDIA_SERVER_STARTED) != B_OK) {
353611c7bd86SDario Casalinuovo 						if(!current->messenger.IsValid())
353711c7bd86SDario Casalinuovo 							sNotificationList.Remove(i);
353811c7bd86SDario Casalinuovo 					}
353911c7bd86SDario Casalinuovo 				}
354011c7bd86SDario Casalinuovo 			}
354176889670SDario Casalinuovo 			return;
354211c7bd86SDario Casalinuovo 		}
354311c7bd86SDario Casalinuovo 
3544cf4e2277Sbeveloper 		case NODE_FINAL_RELEASE:
3545cf4e2277Sbeveloper 		{
35466423f87fSDario Casalinuovo 			// This function is called by a BMediaNode to delete
3547cf4e2277Sbeveloper 			// itself, as this needs to be done from another thread
3548cf4e2277Sbeveloper 			// context, it is done here.
3549cf4e2277Sbeveloper 
35506423f87fSDario Casalinuovo 			BMediaNode* node = NULL;
35516423f87fSDario Casalinuovo 			status_t err = message->FindPointer("node",
35526423f87fSDario Casalinuovo 				reinterpret_cast<void **>(&node));
35536423f87fSDario Casalinuovo 			if (err == B_OK && node != NULL)
35546423f87fSDario Casalinuovo 				node->Release();
35556423f87fSDario Casalinuovo 			else {
35566423f87fSDario Casalinuovo 				TRACE("BMediaRoster::MessageReceived: CRITICAL! received"
35576423f87fSDario Casalinuovo 					"a release request but the node can't be found.");
35586423f87fSDario Casalinuovo 			}
3559cf4e2277Sbeveloper 			return;
3560cf4e2277Sbeveloper 		}
356148b2cb37SDario Casalinuovo 
356248b2cb37SDario Casalinuovo 		default:
356348b2cb37SDario Casalinuovo 			BLooper::MessageReceived(message);
356448b2cb37SDario Casalinuovo 			break;
356548b2cb37SDario Casalinuovo 	}
356652a38012Sejakowatz }
356752a38012Sejakowatz 
356834c72144SAxel Dörfler 
356934c72144SAxel Dörfler bool
357052a38012Sejakowatz BMediaRoster::QuitRequested()
357152a38012Sejakowatz {
357232afe10aSDario Casalinuovo 	CALLED();
357352a38012Sejakowatz 	return true;
357452a38012Sejakowatz }
357552a38012Sejakowatz 
357634c72144SAxel Dörfler 
357734c72144SAxel Dörfler BHandler*
357834c72144SAxel Dörfler BMediaRoster::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
357934c72144SAxel Dörfler 	int32 form, const char* property)
358052a38012Sejakowatz {
3581286a3c91SJérôme Duval 	return BLooper::ResolveSpecifier(msg, index, specifier, form, property);
358252a38012Sejakowatz }
358352a38012Sejakowatz 
358452a38012Sejakowatz 
358534c72144SAxel Dörfler status_t
358652a38012Sejakowatz BMediaRoster::GetSupportedSuites(BMessage* data)
358752a38012Sejakowatz {
3588286a3c91SJérôme Duval 	return BLooper::GetSupportedSuites(data);
358952a38012Sejakowatz }
359052a38012Sejakowatz 
359152a38012Sejakowatz 
359252a38012Sejakowatz BMediaRoster::~BMediaRoster()
359352a38012Sejakowatz {
359452a38012Sejakowatz 	CALLED();
35956396865dSbeveloper 
35968b940bb4SStephan Aßmus 	// Unset the global instance pointer, the destructor is also called
35978b940bb4SStephan Aßmus 	// if a client app calls Lock(); and Quit(); directly.
35989def3bf7SStephan Aßmus 	sDefaultInstance = NULL;
359952a38012Sejakowatz }
360052a38012Sejakowatz 
360134c72144SAxel Dörfler //	#pragma mark - private BMediaRoster
360234c72144SAxel Dörfler 
3603f0a1eb2dSAxel Dörfler // FBC reserved virtuals
360452a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_0(void*) { return B_ERROR; }
360552a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_1(void*) { return B_ERROR; }
360652a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_2(void*) { return B_ERROR; }
360752a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_3(void*) { return B_ERROR; }
360852a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_4(void*) { return B_ERROR; }
360952a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_5(void*) { return B_ERROR; }
361052a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_6(void*) { return B_ERROR; }
361152a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_7(void*) { return B_ERROR; }
361252a38012Sejakowatz 
361352a38012Sejakowatz 
361434c72144SAxel Dörfler BMediaRoster::BMediaRoster()
36152f9ed888SAxel Dörfler 	:
36162f9ed888SAxel Dörfler 	BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY,
361734c72144SAxel Dörfler 		B_LOOPER_PORT_DEFAULT_CAPACITY)
361852a38012Sejakowatz {
361952a38012Sejakowatz 	CALLED();
36206396865dSbeveloper 
36216396865dSbeveloper 	// start the looper
36226396865dSbeveloper 	Run();
362352a38012Sejakowatz }
362452a38012Sejakowatz 
36259def3bf7SStephan Aßmus // #pragma mark - static variables
362652a38012Sejakowatz 
36279def3bf7SStephan Aßmus BMediaRoster* BMediaRoster::sDefaultInstance = NULL;
3628