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