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 48const char* const _NODE_SET_ELEMENT = "cortex_node_set"; 49const char* const _UI_STATE_ELEMENT = "cortex_ui_state"; 50 51const char* const _DORMANT_NODE_ELEMENT = "dormant_node"; 52const char* const _KIND_ELEMENT = "kind"; 53const char* const _FLAVOR_ID_ELEMENT = "flavor_id"; 54const char* const _CYCLE_ELEMENT = "cycle"; 55const char* const _FLAG_ELEMENT = "flag"; 56const char* const _RUN_MODE_ELEMENT = "run_mode"; 57const char* const _TIME_SOURCE_ELEMENT = "time_source"; 58const char* const _RECORDING_DELAY_ELEMENT = "recording_delay"; 59const char* const _CONNECTION_ELEMENT = "connection"; 60const char* const _OUTPUT_ELEMENT = "output"; 61const char* const _INPUT_ELEMENT = "input"; 62const char* const _NODE_GROUP_ELEMENT = "node_group"; 63const char* const _NAME_ELEMENT = "name"; 64const char* const _REF_ELEMENT = "ref"; 65const char* const _LIVE_NODE_ELEMENT = "live_node"; 66 67const char* const _AUDIO_INPUT_KEY = "AUDIO_INPUT"; 68const char* const _AUDIO_OUTPUT_KEY = "AUDIO_OUTPUT"; 69const char* const _AUDIO_MIXER_KEY = "AUDIO_MIXER"; 70const char* const _VIDEO_INPUT_KEY = "VIDEO_INPUT"; 71const char* const _VIDEO_OUTPUT_KEY = "VIDEO_OUTPUT"; 72 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 %" 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 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(("# %" 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 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