xref: /haiku/src/apps/cortex/RouteApp/route_app_io.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // route_app_io.cpp
33 
34 #include "route_app_io.h"
35 
36 #include <MediaDefs.h>
37 #include <MediaNode.h>
38 #include <MediaRoster.h>
39 
40 #include "NodeManager.h"
41 #include "NodeRef.h"
42 #include "NodeSetIOContext.h"
43 
44 __BEGIN_CORTEX_NAMESPACE
45 
46 // -------------------------------------------------------- //
47 
48 const char* const _NODE_SET_ELEMENT = "cortex_node_set";
49 const char* const _UI_STATE_ELEMENT = "cortex_ui_state";
50 
51 const char* const _DORMANT_NODE_ELEMENT = "dormant_node";
52 const char* const _KIND_ELEMENT = "kind";
53 const char* const _FLAVOR_ID_ELEMENT = "flavor_id";
54 const char* const _CYCLE_ELEMENT = "cycle";
55 const char* const _FLAG_ELEMENT = "flag";
56 const char* const _RUN_MODE_ELEMENT = "run_mode";
57 const char* const _TIME_SOURCE_ELEMENT = "time_source";
58 const char* const _RECORDING_DELAY_ELEMENT = "recording_delay";
59 const char* const _CONNECTION_ELEMENT = "connection";
60 const char* const _OUTPUT_ELEMENT = "output";
61 const char* const _INPUT_ELEMENT = "input";
62 const char* const _NODE_GROUP_ELEMENT = "node_group";
63 const char* const _NAME_ELEMENT = "name";
64 const char* const _REF_ELEMENT = "ref";
65 const char* const _LIVE_NODE_ELEMENT = "live_node";
66 
67 const char* const _AUDIO_INPUT_KEY = "AUDIO_INPUT";
68 const char* const _AUDIO_OUTPUT_KEY = "AUDIO_OUTPUT";
69 const char* const _AUDIO_MIXER_KEY = "AUDIO_MIXER";
70 const char* const _VIDEO_INPUT_KEY = "VIDEO_INPUT";
71 const char* const _VIDEO_OUTPUT_KEY = "VIDEO_OUTPUT";
72 
73 __END_CORTEX_NAMESPACE
74 
75 // -------------------------------------------------------- //
76 __USE_CORTEX_NAMESPACE
77 // -------------------------------------------------------- //
78 
79 void __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 
90 void __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 
114 void __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 
148 status_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 %" B_PRId32
165 			" not found\n", 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 
209 status_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(("# %" B_PRId32 "\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 
246 status_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 
292 void __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