134c72144SAxel Dörfler/*
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
9255a01c7Sbeveloper/*
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ßmuschar __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>
64b84955d4SBarrett#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örflernamespace BPrivate {
77f0a1eb2dSAxel Dörflernamespace media {
7852a38012Sejakowatz
79f0a1eb2dSAxel Dörfler
8032afe10aSDario Casalinuovostruct RosterNotification {
8132afe10aSDario Casalinuovo	BMessenger	messenger;
8232afe10aSDario Casalinuovo	int32		what;
8332afe10aSDario Casalinuovo};
8432afe10aSDario Casalinuovo
8505962bb1SDario Casalinuovo
8676889670SDario Casalinuovostruct SyncedMessage {
8776889670SDario Casalinuovo	BMessage* message;
8876889670SDario Casalinuovo};
8976889670SDario Casalinuovo
9076889670SDario Casalinuovo
9167060664SDario Casalinuovostruct 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 Casalinuovostatic bool sServerIsUp = false;
11232afe10aSDario Casalinuovostatic List<RosterNotification> sNotificationList;
113d15321ffSDario Casalinuovostatic BLocker sInitLocker("BMediaRoster::Roster locker");
11467060664SDario Casalinuovostatic List<LocalNode> sRegisteredNodes;
11532afe10aSDario Casalinuovo
1167d337b23SDario Casalinuovo
1177d337b23SDario Casalinuovoclass MediaRosterUndertaker {
1187d337b23SDario Casalinuovopublic:
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 Casalinuovostatic MediaRosterUndertaker sMediaRosterUndertaker;
1537d337b23SDario Casalinuovo
1549dec2310SAxel Dörfler}	// namespace media
1559dec2310SAxel Dörfler}	// namespace BPrivate
15652a38012Sejakowatz
1578b04ffc1Sbeveloperusing namespace BPrivate::media;
15852a38012Sejakowatz
1599dec2310SAxel Dörfler
16034c72144SAxel DörflerBMediaRosterEx::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) {
175d009f286SDario Casalinuovo		*_error = B_ERROR;
176d009f286SDario Casalinuovo	}
17732afe10aSDario Casalinuovo	sServerIsUp = BMediaRoster::IsRunning();
17832afe10aSDario Casalinuovo}
17932afe10aSDario Casalinuovo
18032afe10aSDario Casalinuovo
1817d337b23SDario Casalinuovovoid
1827d337b23SDario CasalinuovoBMediaRosterEx::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 Casalinuovostatus_t
19532afe10aSDario CasalinuovoBMediaRosterEx::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 CasalinuovoBMediaRosterEx::~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 Casalinuovovoid
23167060664SDario CasalinuovoBMediaRosterEx::RegisterLocalNode(BMediaNode* node)
23267060664SDario Casalinuovo{
23367060664SDario Casalinuovo	sRegisteredNodes.Insert(LocalNode(node));
23467060664SDario Casalinuovo}
23567060664SDario Casalinuovo
23667060664SDario Casalinuovo
23767060664SDario Casalinuovovoid
23867060664SDario CasalinuovoBMediaRosterEx::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 Casalinuovovoid
24776889670SDario CasalinuovoBMediaRosterEx::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
25754187cc6Sbeveloperstatus_t
25834c72144SAxel DörflerBMediaRosterEx::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();
27234c72144SAxel Dörfler
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
28154187cc6Sbeveloperstatus_t
2829dec2310SAxel DörflerBMediaRosterEx::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
29454187cc6Sbeveloperstatus_t
2959dec2310SAxel DörflerBMediaRosterEx::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;
30034c72144SAxel Dörfler
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
31054187cc6Sbeveloperstatus_t
3119dec2310SAxel DörflerBMediaRosterEx::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;
31634c72144SAxel Dörfler
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}
32434c72144SAxel Dörfler
32534c72144SAxel Dörfler
3266aee58a4SJérôme Duvalstatus_t
3276aee58a4SJérôme DuvalBMediaRosterEx::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 %"
352332cc6bcSAxel Dörfler			B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
353332cc6bcSAxel Dörfler			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) {
358c74afb57SJérôme Duval			ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %" B_PRId32 ", port %"
359c74afb57SJérôme Duval				B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
360c74afb57SJérôme Duval				BPrivate::current_team());
361c74afb57SJérôme Duval		}
3626aee58a4SJérôme Duval	}
3636aee58a4SJérôme Duval	return rv;
3646aee58a4SJérôme Duval}
3656aee58a4SJérôme Duval
3666aee58a4SJérôme Duval
36754187cc6Sbeveloperstatus_t
36854187cc6SbeveloperBMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator)
36954187cc6Sbeveloper{
37054187cc6Sbeveloper	server_set_node_creator_request request;
37154187cc6Sbeveloper	server_set_node_creator_reply reply;
37234c72144SAxel Dörfler
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
3803620737cSbeveloperstatus_t
38134c72144SAxel DörflerBMediaRosterEx::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)
39652a38012Sejakowatz		return rv;
3978c6a6096Sbeveloper
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
4073620737cSbeveloperstatus_t
40834c72144SAxel DörflerBMediaRosterEx::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;
41334c72144SAxel Dörfler
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;
42434c72144SAxel Dörfler
42534c72144SAxel Dörfler	return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply,
42634c72144SAxel Dörfler		sizeof(reply));
42752a38012Sejakowatz}
42852a38012Sejakowatz
42934c72144SAxel Dörfler
4303620737cSbeveloperstatus_t
43134c72144SAxel DörflerBMediaRosterEx::GetAllOutputs(const media_node& node, List<media_output>* list)
4323620737cSbeveloper{
4333620737cSbeveloper	int32 cookie;
4343620737cSbeveloper	status_t rv;
4353620737cSbeveloper	status_t result;
43634c72144SAxel Dörfler
437332cc6bcSAxel Dörfler	PRINT(4, "BMediaRosterEx::GetAllOutputs() node %" B_PRId32 ", port %"
438332cc6bcSAxel Dörfler		B_PRId32 "\n", node.node, node.port);
43965b73ae4SMarcus Overhagen
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	}
44534c72144SAxel Dörfler
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));
47234c72144SAxel Dörfler
4733620737cSbeveloper	return result;
4743620737cSbeveloper}
4753620737cSbeveloper
47634c72144SAxel Dörfler
4774d2d96e0Sbeveloperstatus_t
47834c72144SAxel DörflerBMediaRosterEx::GetAllOutputs(BBufferProducer* node, List<media_output>* list)
4794d2d96e0Sbeveloper{
4804d2d96e0Sbeveloper	int32 cookie;
4814d2d96e0Sbeveloper	status_t result;
48234c72144SAxel Dörfler
483332cc6bcSAxel Dörfler	PRINT(4, "BMediaRosterEx::GetAllOutputs() (by pointer) node %" B_PRId32
484332cc6bcSAxel Dörfler		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
48534c72144SAxel Dörfler
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
5073620737cSbeveloperstatus_t
50834c72144SAxel DörflerBMediaRosterEx::GetAllInputs(const media_node& node, List<media_input>* list)
5093620737cSbeveloper{
5103620737cSbeveloper	int32 cookie;
5113620737cSbeveloper	status_t rv;
5123620737cSbeveloper	status_t result;
5135ac4fbd7Sbeveloper
514332cc6bcSAxel Dörfler	PRINT(4, "BMediaRosterEx::GetAllInputs() node %" B_PRId32 ", port %"
515332cc6bcSAxel Dörfler		B_PRId32 "\n", node.node, node.port);
51665b73ae4SMarcus Overhagen
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	}
52234c72144SAxel Dörfler
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));
54934c72144SAxel Dörfler
5503620737cSbeveloper	return result;
5513620737cSbeveloper}
5523620737cSbeveloper
55334c72144SAxel Dörfler
5544d2d96e0Sbeveloperstatus_t
55534c72144SAxel DörflerBMediaRosterEx::GetAllInputs(BBufferConsumer* node, List<media_input>* list)
5564d2d96e0Sbeveloper{
5574d2d96e0Sbeveloper	int32 cookie;
5584d2d96e0Sbeveloper	status_t result;
55934c72144SAxel Dörfler
560332cc6bcSAxel Dörfler	PRINT(4, "BMediaRosterEx::GetAllInputs() (by pointer) node %" B_PRId32
561332cc6bcSAxel Dörfler		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
56234c72144SAxel Dörfler
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
5843620737cSbeveloperstatus_t
58534c72144SAxel DörflerBMediaRosterEx::PublishOutputs(const media_node& node, List<media_output>* list)
5863620737cSbeveloper{
5873620737cSbeveloper	server_publish_outputs_request request;
5883620737cSbeveloper	server_publish_outputs_reply reply;
58934c72144SAxel Dörfler	media_output* output;
59034c72144SAxel Dörfler	media_output* outputs;
5913620737cSbeveloper	int32 count;
592a7b41a96Sbeveloper	status_t rv;
59334c72144SAxel Dörfler
59476669a29Sbeveloper	count = list->CountItems();
595332cc6bcSAxel Dörfler	TRACE("PublishOutputs: publishing %" B_PRId32 "\n", count);
59634c72144SAxel Dörfler
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);
61634c72144SAxel Dörfler
61776669a29Sbeveloper	int i;
61876669a29Sbeveloper	for (i = 0, list->Rewind(); list->GetNext(&output); i++) {
61976669a29Sbeveloper		ASSERT(i < count);
6203620737cSbeveloper		outputs[i] = *output;
6213620737cSbeveloper	}
62234c72144SAxel Dörfler
62334c72144SAxel Dörfler	rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request),
62434c72144SAxel Dörfler		&reply, sizeof(reply));
62534c72144SAxel Dörfler
626a7b41a96Sbeveloper	if (request.area != -1)
627a7b41a96Sbeveloper		delete_area(request.area);
62834c72144SAxel Dörfler
629a7b41a96Sbeveloper	return rv;
6303620737cSbeveloper}
6313620737cSbeveloper
63234c72144SAxel Dörfler
6333620737cSbeveloperstatus_t
63434c72144SAxel DörflerBMediaRosterEx::PublishInputs(const media_node& node, List<media_input>* list)
6353620737cSbeveloper{
6363620737cSbeveloper	server_publish_inputs_request request;
6373620737cSbeveloper	server_publish_inputs_reply reply;
63834c72144SAxel Dörfler	media_input* input;
63934c72144SAxel Dörfler	media_input* inputs;
6403620737cSbeveloper	int32 count;
641a7b41a96Sbeveloper	status_t rv;
64234c72144SAxel Dörfler
64376669a29Sbeveloper	count = list->CountItems();
644332cc6bcSAxel Dörfler	TRACE("PublishInputs: publishing %" B_PRId32 "\n", count);
64534c72144SAxel Dörfler
6463620737cSbeveloper	request.node = node;
6473620737cSbeveloper	request.count = count;
6483620737cSbeveloper	if (count > MAX_INPUTS) {
64934c72144SAxel Dörfler		void* start_addr;
6503620737cSbeveloper		size_t size;
65140f36b03Sbeveloper