172445Sassar/*
272445Sassar * Copyright (c) 1999-2000, Eric Moon.
3178825Sdfr * All rights reserved.
472445Sassar *
572445Sassar * Redistribution and use in source and binary forms, with or without
672445Sassar * modification, are permitted provided that the following conditions
7178825Sdfr * are met:
872445Sassar *
972445Sassar * 1. Redistributions of source code must retain the above copyright
1072445Sassar *    notice, this list of conditions, and the following disclaimer.
1190926Snectar *
1272445Sassar * 2. Redistributions in binary form must reproduce the above copyright
13178825Sdfr *    notice, this list of conditions, and the following disclaimer in the
1472445Sassar *    documentation and/or other materials provided with the distribution.
1572445Sassar *
1672445Sassar * 3. The name of the author may not be used to endorse or promote products
1772445Sassar *    derived from this software without specific prior written permission.
1890926Snectar *
1990926Snectar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
2072445Sassar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2190926Snectar * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22178825Sdfr * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23178825Sdfr * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24178825Sdfr * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25178825Sdfr * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26178825Sdfr * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27178825Sdfr * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28178825Sdfr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29178825Sdfr */
30178825Sdfr
31178825Sdfr
3272445Sassar// route_app_io.cpp
3372445Sassar
3490926Snectar#include "route_app_io.h"
35178825Sdfr
36178825Sdfr#include <MediaDefs.h>
37178825Sdfr#include <MediaNode.h>
38178825Sdfr#include <MediaRoster.h>
3990926Snectar
40178825Sdfr#include "NodeManager.h"
4190926Snectar#include "NodeRef.h"
4290926Snectar#include "NodeSetIOContext.h"
4390926Snectar
44178825Sdfr__BEGIN_CORTEX_NAMESPACE
45178825Sdfr
4690926Snectar// -------------------------------------------------------- //
4790926Snectar
4890926Snectarconst char* const _NODE_SET_ELEMENT = "cortex_node_set";
49178825Sdfrconst char* const _UI_STATE_ELEMENT = "cortex_ui_state";
5090926Snectar
51178825Sdfrconst char* const _DORMANT_NODE_ELEMENT = "dormant_node";
5290926Snectarconst char* const _KIND_ELEMENT = "kind";
5390926Snectarconst char* const _FLAVOR_ID_ELEMENT = "flavor_id";
5490926Snectarconst char* const _CYCLE_ELEMENT = "cycle";
55178825Sdfrconst char* const _FLAG_ELEMENT = "flag";
56178825Sdfrconst char* const _RUN_MODE_ELEMENT = "run_mode";
5790926Snectarconst char* const _TIME_SOURCE_ELEMENT = "time_source";
5890926Snectarconst char* const _RECORDING_DELAY_ELEMENT = "recording_delay";
5990926Snectarconst char* const _CONNECTION_ELEMENT = "connection";
6090926Snectarconst char* const _OUTPUT_ELEMENT = "output";
61178825Sdfrconst char* const _INPUT_ELEMENT = "input";
62178825Sdfrconst char* const _NODE_GROUP_ELEMENT = "node_group";
63178825Sdfrconst char* const _NAME_ELEMENT = "name";
64178825Sdfrconst char* const _REF_ELEMENT = "ref";
65178825Sdfrconst char* const _LIVE_NODE_ELEMENT = "live_node";
66178825Sdfr
67178825Sdfrconst char* const _AUDIO_INPUT_KEY = "AUDIO_INPUT";
68178825Sdfrconst char* const _AUDIO_OUTPUT_KEY = "AUDIO_OUTPUT";
69178825Sdfrconst char* const _AUDIO_MIXER_KEY = "AUDIO_MIXER";
7090926Snectarconst char* const _VIDEO_INPUT_KEY = "VIDEO_INPUT";
7190926Snectarconst char* const _VIDEO_OUTPUT_KEY = "VIDEO_OUTPUT";
7272445Sassar
73__END_CORTEX_NAMESPACE
74
75// -------------------------------------------------------- //
76__USE_CORTEX_NAMESPACE
77// -------------------------------------------------------- //
78
79void __CORTEX_NAMESPACE__ _write_simple(
80	const char* element,
81	const char* value,
82	ExportContext& context) {
83
84	context.beginElement(element);
85	context.beginContent();
86	context.writeString(value);
87	context.endElement();
88}
89
90void __CORTEX_NAMESPACE__ _write_node_kinds(
91	int64 kinds,
92	ExportContext& context) {
93
94	if(kinds & B_BUFFER_PRODUCER)
95		_write_simple(_KIND_ELEMENT, "B_BUFFER_PRODUCER", context);
96	if(kinds & B_BUFFER_CONSUMER)
97		_write_simple(_KIND_ELEMENT, "B_BUFFER_CONSUMER", context);
98	if(kinds & B_TIME_SOURCE)
99		_write_simple(_KIND_ELEMENT, "B_TIME_SOURCE", context);
100	if(kinds & B_CONTROLLABLE)
101		_write_simple(_KIND_ELEMENT, "B_CONTROLLABLE", context);
102	if(kinds & B_FILE_INTERFACE)
103		_write_simple(_KIND_ELEMENT, "B_FILE_INTERFACE", context);
104	if(kinds & B_ENTITY_INTERFACE)
105		_write_simple(_KIND_ELEMENT, "B_ENTITY_INTERFACE", context);
106	if(kinds & B_PHYSICAL_INPUT)
107		_write_simple(_KIND_ELEMENT, "B_PHYSICAL_INPUT", context);
108	if(kinds & B_PHYSICAL_OUTPUT)
109		_write_simple(_KIND_ELEMENT, "B_PHYSICAL_OUTPUT", context);
110	if(kinds & B_SYSTEM_MIXER)
111		_write_simple(_KIND_ELEMENT, "B_SYSTEM_MIXER", context);
112}
113
114void __CORTEX_NAMESPACE__ _read_node_kind(
115	int64& ioKind,
116	const char* data,
117	ImportContext& context) {
118
119	if(!strcmp(data, "B_BUFFER_PRODUCER"))
120		ioKind |= B_BUFFER_PRODUCER;
121	else if(!strcmp(data, "B_BUFFER_CONSUMER"))
122		ioKind |= B_BUFFER_CONSUMER;
123	else if(!strcmp(data, "B_TIME_SOURCE"))
124		ioKind |= B_TIME_SOURCE;
125	else if(!strcmp(data, "B_CONTROLLABLE"))
126		ioKind |= B_CONTROLLABLE;
127	else if(!strcmp(data, "B_FILE_INTERFACE"))
128		ioKind |= B_FILE_INTERFACE;
129	else if(!strcmp(data, "B_ENTITY_INTERFACE"))
130		ioKind |= B_ENTITY_INTERFACE;
131	else if(!strcmp(data, "B_PHYSICAL_INPUT"))
132		ioKind |= B_PHYSICAL_INPUT;
133	else if(!strcmp(data, "B_PHYSICAL_OUTPUT"))
134		ioKind |= B_PHYSICAL_OUTPUT;
135	else if(!strcmp(data, "B_SYSTEM_MIXER"))
136		ioKind |= B_SYSTEM_MIXER;
137	else {
138		BString err;
139		err << "_read_noderef_kind(): unknown node kind '" << data << "'\n";
140		context.reportWarning(err.String());
141	}
142}
143
144// fills in either key or outName/kind for the provided
145// node.  If the given node is one of the default system nodes,
146// an appropriate 'preset' key value will be returned.
147
148status_t __CORTEX_NAMESPACE__ _get_node_signature(
149	const NodeManager*			manager,
150	const NodeSetIOContext*	context,
151	media_node_id						node,
152	BString&								outKey,
153	BString&								outName,
154	int64&									outKind) {
155
156	ASSERT(manager);
157	ASSERT(context);
158
159	// get ref
160	NodeRef* ref;
161	status_t err = manager->getNodeRef(node, &ref);
162	if(err < B_OK) {
163		PRINT((
164			"!!! ConnectionIO::_getNodeSignature(): node %ld not found\n",
165			node));
166		return err;
167	}
168
169	// check against system-default nodes
170	if(ref == manager->audioInputNode()) {
171		outKey = _AUDIO_INPUT_KEY;
172		return B_OK;
173	}
174	else if(ref == manager->audioOutputNode()) {
175		outKey = _AUDIO_OUTPUT_KEY;
176		return B_OK;
177	}
178	else if(ref == manager->audioMixerNode()) {
179		outKey = _AUDIO_MIXER_KEY;
180		return B_OK;
181	}
182	else if(ref == manager->videoInputNode()) {
183		outKey = _VIDEO_INPUT_KEY;
184		return B_OK;
185	}
186	else if(ref == manager->videoOutputNode()) {
187		outKey = _VIDEO_OUTPUT_KEY;
188		return B_OK;
189	}
190
191	// check context for a key (found if the node has already
192	// been exported)
193	const char* key;
194	err = context->getKeyFor(node, &key);
195	if(err == B_OK) {
196		outKey = key;
197		return B_OK;
198	}
199
200	// return name/kind signature
201	outName = ref->name();
202	outKind = ref->kind();
203	return B_OK;
204}
205
206
207// given a name and kind, looks for a matching node
208
209status_t __CORTEX_NAMESPACE__ _match_node_signature(
210	const char*							name,
211	int64										kind,
212	media_node_id*					outNode) {
213
214	// fetch matching nodes
215	BMediaRoster* roster = BMediaRoster::Roster();
216	const int32 bufferSize = 64;
217	live_node_info buffer[bufferSize];
218	int32 count = bufferSize;
219	status_t err = roster->GetLiveNodes(
220		buffer,
221		&count,
222		0,
223		0,
224		name,
225		kind); // is this argument supported yet? +++++
226
227	if(err < B_OK)
228		return err;
229
230	for(int32 n = 0; n < count; ++n) {
231		PRINT(("# %ld\n", buffer[n].node.node));
232		if((buffer[n].node.kind & kind) != kind) {
233			PRINT(("# - kind mismatch\n"));
234			continue;
235		}
236
237		*outNode = buffer[n].node.node;
238		return B_OK;
239	}
240
241	return B_NAME_NOT_FOUND;
242}
243
244// given a key, looks for a system-default node
245
246status_t __CORTEX_NAMESPACE__ _match_system_node_key(
247	const char*							key,
248	const NodeManager*			manager,
249	media_node_id*					outNode) {
250
251	if(!strcmp(key, _AUDIO_INPUT_KEY)) {
252		if(manager->audioInputNode()) {
253			*outNode = manager->audioInputNode()->id();
254			return B_OK;
255		}
256		return B_NAME_NOT_FOUND;
257	}
258	else if(!strcmp(key, _AUDIO_OUTPUT_KEY)) {
259		if(manager->audioOutputNode()) {
260			*outNode = manager->audioOutputNode()->id();
261			return B_OK;
262		}
263		return B_NAME_NOT_FOUND;
264	}
265	else if(!strcmp(key, _AUDIO_MIXER_KEY)) {
266		if(manager->audioMixerNode()) {
267			*outNode = manager->audioMixerNode()->id();
268			return B_OK;
269		}
270		return B_NAME_NOT_FOUND;
271	}
272	else if(!strcmp(key, _VIDEO_INPUT_KEY)) {
273		if(manager->videoInputNode()) {
274			*outNode = manager->videoInputNode()->id();
275			return B_OK;
276		}
277		return B_NAME_NOT_FOUND;
278	}
279	else if(!strcmp(key, _VIDEO_OUTPUT_KEY)) {
280		if(manager->videoOutputNode()) {
281			*outNode = manager->videoOutputNode()->id();
282			return B_OK;
283		}
284		return B_NAME_NOT_FOUND;
285	}
286	return B_NAME_NOT_FOUND;
287}
288
289// adds mappings for the simple string-content elements to the
290// given document type
291
292void __CORTEX_NAMESPACE__ _add_string_elements(
293	XML::DocumentType*			docType) {
294
295	docType->addMapping(new Mapping<StringContent>(_NAME_ELEMENT));
296	docType->addMapping(new Mapping<StringContent>(_KIND_ELEMENT));
297	docType->addMapping(new Mapping<StringContent>(_FLAG_ELEMENT));
298	docType->addMapping(new Mapping<StringContent>(_FLAVOR_ID_ELEMENT));
299	docType->addMapping(new Mapping<StringContent>(_CYCLE_ELEMENT));
300	docType->addMapping(new Mapping<StringContent>(_RUN_MODE_ELEMENT));
301	docType->addMapping(new Mapping<StringContent>(_TIME_SOURCE_ELEMENT));
302	docType->addMapping(new Mapping<StringContent>(_RECORDING_DELAY_ELEMENT));
303	docType->addMapping(new Mapping<StringContent>(_REF_ELEMENT));
304}
305
306// END -- route_app_io.cpp --
307
308