root/trunk/libffado/support/dbus/controlserver.cpp

Revision 1655, 26.2 kB (checked in by arnonym, 15 years ago)

Thinking about getting structured info about the router-channels.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "controlserver.h"
25 #include "libcontrol/Element.h"
26 #include "libcontrol/BasicElements.h"
27 #include "libcontrol/MatrixMixer.h"
28 #include "libcontrol/CrossbarRouter.h"
29 #include "libutil/Time.h"
30 #include "libutil/PosixMutex.h"
31
32 namespace DBusControl {
33
34 IMPL_DEBUG_MODULE( Element, Element, DEBUG_LEVEL_NORMAL );
35
36 // --- Element
37 Element::Element( DBus::Connection& connection, std::string p, Element* parent, Control::Element &slave)
38 : DBus::ObjectAdaptor(connection, p)
39 , m_Parent(parent)
40 , m_Slave(slave)
41 , m_UpdateLock( NULL )
42 {
43     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Element on '%s'\n",
44                  path().c_str() );
45     // allocate a lock
46     if(parent == NULL) {
47         m_UpdateLock = new Util::PosixMutex("CTLSVEL");
48     } else {
49         m_UpdateLock = NULL;
50     }
51     // set verbose level AFTER allocating the lock
52     setVerboseLevel(m_Slave.getVerboseLevel());
53 }
54
55 void Element::setVerboseLevel( const DBus::Int32 &i)
56 {
57     setDebugLevel(i);
58     m_Slave.setVerboseLevel(i);
59     if(m_UpdateLock) m_UpdateLock->setVerboseLevel(i);
60 }
61
62 DBus::Int32 Element::getVerboseLevel()
63 {
64     return getDebugLevel();
65 }
66
67 DBus::Bool
68 Element::canChangeValue()
69 {
70     return m_Slave.canChangeValue();
71 }
72
73 void
74 Element::Lock()
75 {
76     if(m_Parent) {
77         m_Parent->Lock();
78     } else {
79         m_UpdateLock->Lock();
80     }
81 }
82
83 void
84 Element::Unlock()
85 {
86     if(m_Parent) {
87         m_Parent->Unlock();
88     } else {
89         m_UpdateLock->Unlock();
90     }
91 }
92
93 bool
94 Element::isLocked()
95 {
96     if(m_Parent) {
97         return m_Parent->isLocked();
98     } else {
99         return m_UpdateLock->isLocked();
100     }
101 }
102
103 Util::Mutex*
104 Element::getLock()
105 {
106     if(m_Parent) {
107         return m_Parent->getLock();
108     } else {
109         return m_UpdateLock;
110     }
111 }
112
113 DBus::UInt64
114 Element::getId( )
115 {
116     return m_Slave.getId();
117 }
118
119 DBus::String
120 Element::getName( )
121 {
122     return DBus::String(m_Slave.getName());
123 }
124
125 DBus::String
126 Element::getLabel( )
127 {
128     return DBus::String(m_Slave.getLabel());
129 }
130
131 DBus::String
132 Element::getDescription( )
133 {
134     return DBus::String(m_Slave.getDescription());
135 }
136
137 // --- Container
138 Container::Container( DBus::Connection& connection, std::string p, Element* parent, Control::Container &slave)
139 : Element(connection, p, parent, slave)
140 , m_Slave(slave)
141 {
142     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Container on '%s'\n",
143                  path().c_str() );
144
145     setDebugLevel(slave.getVerboseLevel());
146
147     // register an update signal handler
148     m_updateFunctor = new MemberSignalFunctor1< Container*,
149                       void (Container::*)(int) >
150                       ( this, &Container::updated, (int)Control::Container::eS_Updated );
151     if(m_updateFunctor) {
152         if(!slave.addSignalHandler(m_updateFunctor)) {
153             debugWarning("Could not add update signal functor\n");
154         }
155     } else {
156         debugWarning("Could not create update signal functor\n");
157     }
158
159     // build the initial tree
160     m_Slave = slave;
161     updateTree();
162 }
163
164 Container::~Container() {
165     debugOutput( DEBUG_LEVEL_VERBOSE, "Deleting Container on '%s'\n",
166                  path().c_str() );
167
168     Destroyed(); //send dbus signal
169
170     if(m_updateFunctor) {
171         if(!m_Slave.remSignalHandler(m_updateFunctor)) {
172             debugWarning("Could not remove update signal functor\n");
173         }
174     }
175     delete m_updateFunctor;
176
177     for ( ElementVectorIterator it = m_Children.begin();
178       it != m_Children.end();
179       ++it )
180     {
181         delete (*it);
182     }
183 }
184
185 void
186 Container::setVerboseLevel( const DBus::Int32 & i)
187 {
188     Element::setVerboseLevel(i);
189     for ( ElementVectorIterator it = m_Children.begin();
190       it != m_Children.end();
191       ++it )
192     {
193         (*it)->setVerboseLevel(i);
194     }
195 }
196
197 DBus::Int32
198 Container::getNbElements( ) {
199     return m_Slave.countElements();
200 }
201
202 DBus::String
203 Container::getElementName( const DBus::Int32& i ) {
204     int nbElements=m_Slave.countElements();
205     if (i<nbElements) {
206         m_Slave.lockControl();
207         const Control::ElementVector elements = m_Slave.getElementVector();
208         Control::Element *e = elements.at(i);
209         std::string name;
210         if(e) name = e->getName();
211         m_Slave.unlockControl();
212         return name;
213     } else return "";
214 }
215 //     Util::MutexLockHelper lock(*m_access_lock);
216
217 // NOTE: call with tree locked
218 void
219 Container::updateTree()
220 {
221     bool something_changed = false;
222     debugOutput( DEBUG_LEVEL_VERBOSE, "Updating tree...\n");
223     // send a pre update signal
224     PreUpdate();
225     debugOutput( DEBUG_LEVEL_VERBOSE, "Add handlers for elements...\n");
226     // add handlers for the slaves that don't have one yet
227     const Control::ElementVector elements = m_Slave.getElementVector();
228     for ( Control::ConstElementVectorIterator it = elements.begin();
229       it != elements.end();
230       ++it )
231     {
232         Element *e = findElementForControl((*it));
233         if(e == NULL) { // element not in tree
234             e = createHandler(this, *(*it));
235             if (e) {
236                 e->setVerboseLevel(getDebugLevel());
237                 m_Children.push_back(e);
238                 debugOutput( DEBUG_LEVEL_VERBOSE, "Created handler %p for Control::Element %s...\n",
239                             e, (*it)->getName().c_str());
240                 something_changed = true;
241             } else {
242                 debugWarning("Failed to create handler for Control::Element %s\n",
243                     (*it)->getName().c_str());
244             }
245         } else {
246             // element already present
247             debugOutput( DEBUG_LEVEL_VERBOSE, "Already have handler (%p) for Control::Element %s...\n",
248                          e, (*it)->getName().c_str());
249         }
250     }
251
252     debugOutput( DEBUG_LEVEL_VERBOSE, "Remove handlers without element...\n");
253     std::vector<Element *> to_remove;
254     // remove handlers that don't have a slave anymore
255     for ( ElementVectorIterator it = m_Children.begin();
256       it != m_Children.end();
257       ++it )
258     {
259         Element *e = *it;
260         bool found = false;
261         for ( Control::ConstElementVectorIterator it2 = elements.begin();
262               it2 != elements.end();
263               ++it2 )
264         {
265             if(&(e)->m_Slave == *it2) {
266                 found = true;
267                 debugOutput( DEBUG_LEVEL_VERBOSE, "Slave for handler %p at %s is present: Control::Element %s...\n",
268                             e, e->path().c_str(), (*it)->getName().c_str());
269                 break;
270             }
271         }
272
273         if (!found) {
274             debugOutput(DEBUG_LEVEL_VERBOSE,
275                         "going to remove handler %p on path %s since slave is gone\n",
276                         e, e->path().c_str());
277             // can't remove while iterating
278             to_remove.push_back(e);
279             something_changed = true;
280         }
281     }
282     // do the actual remove
283     while(to_remove.size()) {
284         Element * e = *(to_remove.begin());
285         removeElement(e);
286         to_remove.erase(to_remove.begin());
287     }
288
289     if(something_changed) {
290         debugOutput(DEBUG_LEVEL_VERBOSE,
291                     "send dbus signal for path %s since something changed\n",
292                     path().c_str());
293         // send a dbus signal
294         Updated();
295     }
296     // send a post update signal
297     PostUpdate();
298 }
299
300 void
301 Container::removeElement(Element *e)
302 {
303     debugOutput(DEBUG_LEVEL_VERBOSE,
304                 "removing handler %p on path %s\n",
305                 e, path().c_str());
306     for ( ElementVectorIterator it = m_Children.begin();
307       it != m_Children.end();
308       ++it )
309     {
310         if(*it == e) {
311             m_Children.erase(it);
312             delete e;
313             return;
314         }
315     }
316     debugError("BUG: Element %p not found!\n", e);
317 }
318
319 // NOTE: call with access lock held!
320 Element *
321 Container::findElementForControl(Control::Element *e)
322 {
323     for ( ElementVectorIterator it = m_Children.begin();
324       it != m_Children.end();
325       ++it )
326     {
327         if(&(*it)->m_Slave == e) return (*it);
328     }
329     return NULL;
330 }
331
332 void
333 Container::updated(int new_nb_elements)
334 {
335     debugOutput( DEBUG_LEVEL_VERBOSE, "Got updated signal, new count='%d'\n",
336                  new_nb_elements );
337     // we lock the tree first
338     Lock();
339
340     // also lock the slave tree
341     m_Slave.lockControl();
342
343     // update our tree
344     updateTree();
345
346     // now unlock the slave tree
347     m_Slave.unlockControl();
348
349     // and unlock the access
350     Unlock();
351 }
352
353 /**
354  * \brief create a correct DBusControl counterpart for a given Control::Element
355  */
356 Element *
357 Container::createHandler(Element *parent, Control::Element& e) {
358     debugOutput( DEBUG_LEVEL_VERBOSE, "Creating handler for '%s'\n",
359                  e.getName().c_str() );
360     try {
361         if (dynamic_cast<Control::Container *>(&e) != NULL) {
362             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Container\n");
363            
364             return new Container(conn(), std::string(path()+"/"+e.getName()),
365                 parent, *dynamic_cast<Control::Container *>(&e));
366         }
367        
368         if (dynamic_cast<Control::Continuous *>(&e) != NULL) {
369             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Continuous\n");
370            
371             return new Continuous(conn(), std::string(path()+"/"+e.getName()),
372                 parent, *dynamic_cast<Control::Continuous *>(&e));
373         }
374        
375         if (dynamic_cast<Control::Discrete *>(&e) != NULL) {
376             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Discrete\n");
377            
378             return new Discrete(conn(), std::string(path()+"/"+e.getName()),
379                 parent, *dynamic_cast<Control::Discrete *>(&e));
380         }
381        
382         if (dynamic_cast<Control::Text *>(&e) != NULL) {
383             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Text\n");
384            
385             return new Text(conn(), std::string(path()+"/"+e.getName()),
386                 parent, *dynamic_cast<Control::Text *>(&e));
387         }
388    
389         if (dynamic_cast<Control::Register *>(&e) != NULL) {
390             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Register\n");
391            
392             return new Register(conn(), std::string(path()+"/"+e.getName()),
393                 parent, *dynamic_cast<Control::Register *>(&e));
394         }
395    
396         // note that we have to check this before checking the Enum,
397         // since Enum is a base class
398         if (dynamic_cast<Control::AttributeEnum *>(&e) != NULL) {
399             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::AttributeEnum\n");
400            
401             return new AttributeEnum(conn(), std::string(path()+"/"+e.getName()),
402                 parent, *dynamic_cast<Control::AttributeEnum *>(&e));
403         }
404        
405         if (dynamic_cast<Control::Enum *>(&e) != NULL) {
406             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Enum\n");
407            
408             return new Enum(conn(), std::string(path()+"/"+e.getName()),
409                 parent, *dynamic_cast<Control::Enum *>(&e));
410         }
411        
412         if (dynamic_cast<ConfigRom *>(&e) != NULL) {
413             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a ConfigRom\n");
414            
415             return new ConfigRomX(conn(), std::string(path()+"/"+e.getName()),
416                 parent, *dynamic_cast<ConfigRom *>(&e));
417         }
418        
419         if (dynamic_cast<Control::MatrixMixer *>(&e) != NULL) {
420             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::MatrixMixer\n");
421            
422             return new MatrixMixer(conn(), std::string(path()+"/"+e.getName()),
423                 parent, *dynamic_cast<Control::MatrixMixer *>(&e));
424         }
425        
426         if (dynamic_cast<Control::CrossbarRouter *>(&e) != NULL) {
427             debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::CrossbarRouter\n");
428            
429             return new CrossbarRouter(conn(), std::string(path()+"/"+e.getName()),
430                 parent, *dynamic_cast<Control::CrossbarRouter *>(&e));
431         }
432        
433         debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n");
434         return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e);
435     } catch (...) {
436         debugWarning("Could not register %s\n", std::string(path()+"/"+e.getName()).c_str());
437         if(e.isControlLocked()) {
438             e.unlockControl();
439         }
440         if(isLocked()) {
441             Unlock();
442         }
443         return NULL;
444     };
445 }
446
447 // --- Continuous
448
449 Continuous::Continuous( DBus::Connection& connection, std::string p, Element* parent, Control::Continuous &slave)
450 : Element(connection, p, parent, slave)
451 , m_Slave(slave)
452 {
453     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Continuous on '%s'\n",
454                  path().c_str() );
455 }
456
457 DBus::Double
458 Continuous::setValue( const DBus::Double& value )
459 {
460     m_Slave.setValue(value);
461 /*   
462     SleepRelativeUsec(1000*500);
463    
464     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%lf) => %lf\n", value, m_Slave.getValue() );
465    
466     return m_Slave.getValue();*/
467     return value;
468 }
469
470 DBus::Double
471 Continuous::getValue(  )
472 {
473     double val = m_Slave.getValue();
474     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue() => %lf\n", val );
475     return val;
476 }
477
478 DBus::Double
479 Continuous::setValueIdx( const DBus::Int32 & idx, const DBus::Double& value )
480 {
481     m_Slave.setValue(idx, value);
482 /*   
483     SleepRelativeUsec(1000*500);
484    
485     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%lf) => %lf\n", value, m_Slave.getValue() );
486    
487     return m_Slave.getValue();*/
488     return value;
489 }
490
491 DBus::Double
492 Continuous::getValueIdx( const DBus::Int32 & idx )
493 {
494     double val = m_Slave.getValue(idx);
495     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue(%d) => %lf\n", idx, val );
496     return val;
497 }
498
499 DBus::Double
500 Continuous::getMinimum()
501 {
502     double val = m_Slave.getMinimum();
503     debugOutput( DEBUG_LEVEL_VERBOSE, "getMinimum() => %lf\n", val );
504     return val;
505 }
506
507 DBus::Double
508 Continuous::getMaximum()
509 {
510     double val = m_Slave.getMaximum();
511     debugOutput( DEBUG_LEVEL_VERBOSE, "getMaximum() => %lf\n", val );
512     return val;
513 }
514
515 // --- Discrete
516
517 Discrete::Discrete( DBus::Connection& connection, std::string p, Element* parent, Control::Discrete &slave)
518 : Element(connection, p, parent, slave)
519 , m_Slave(slave)
520 {
521     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Discrete on '%s'\n",
522                  path().c_str() );
523 }
524
525 DBus::Int32
526 Discrete::setValue( const DBus::Int32& value )
527 {
528     m_Slave.setValue(value);
529    
530 /*    SleepRelativeUsec(1000*500);
531     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%d) => %d\n", value, m_Slave.getValue() );
532    
533     return m_Slave.getValue();*/
534     return value;
535 }
536
537 DBus::Int32
538 Discrete::getValue()
539 {
540     int32_t val = m_Slave.getValue();
541     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue() => %d\n", val );
542     return val;
543 }
544
545 DBus::Int32
546 Discrete::setValueIdx( const DBus::Int32& idx, const DBus::Int32& value )
547 {
548     m_Slave.setValue(idx, value);
549    
550 /*    SleepRelativeUsec(1000*500);
551     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%d) => %d\n", value, m_Slave.getValue() );
552    
553     return m_Slave.getValue();*/
554     return value;
555 }
556
557 DBus::Int32
558 Discrete::getValueIdx( const DBus::Int32& idx )
559 {
560     int32_t val = m_Slave.getValue(idx);
561     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue(%d) => %d\n", idx, val );
562     return val;
563 }
564
565 // --- Text
566
567 Text::Text( DBus::Connection& connection, std::string p, Element* parent, Control::Text &slave)
568 : Element(connection, p, parent, slave)
569 , m_Slave(slave)
570 {
571     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Text on '%s'\n",
572                  path().c_str() );
573 }
574
575 DBus::String
576 Text::setValue( const DBus::String& value )
577 {
578     m_Slave.setValue(value);
579    
580 /*    SleepRelativeUsec(1000*500);
581     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%d) => %d\n", value, m_Slave.getValue() );
582    
583     return m_Slave.getValue();*/
584     return value;
585 }
586
587 DBus::String
588 Text::getValue()
589 {
590     std::string val = m_Slave.getValue();
591     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue() => %s\n", val.c_str() );
592     return val;
593 }
594
595 // --- Register
596
597 Register::Register( DBus::Connection& connection, std::string p, Element* parent, Control::Register &slave)
598 : Element(connection, p, parent, slave)
599 , m_Slave(slave)
600 {
601     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Register on '%s'\n",
602                  path().c_str() );
603 }
604
605 DBus::UInt64
606 Register::setValue( const DBus::UInt64& addr, const DBus::UInt64& value )
607 {
608     m_Slave.setValue(addr, value);
609    
610 /*    SleepRelativeUsec(1000*500);
611     debugOutput( DEBUG_LEVEL_VERBOSE, "setValue(%d) => %d\n", value, m_Slave.getValue() );
612    
613     return m_Slave.getValue();*/
614     return value;
615 }
616
617 DBus::UInt64
618 Register::getValue( const DBus::UInt64& addr )
619 {
620     DBus::UInt64 val = m_Slave.getValue(addr);
621     debugOutput( DEBUG_LEVEL_VERBOSE, "getValue(%lld) => %lld\n", addr, val );
622     return val;
623 }
624
625 // --- Enum
626
627 Enum::Enum( DBus::Connection& connection, std::string p, Element* parent, Control::Enum &slave)
628 : Element(connection, p, parent, slave)
629 , m_Slave(slave)
630 {
631     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Enum on '%s'\n",
632                  path().c_str() );
633 }
634
635 DBus::Int32
636 Enum::select( const DBus::Int32& idx )
637 {
638     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "select(%d)\n", idx );
639     return  m_Slave.select(idx);
640 }
641
642 DBus::Int32
643 Enum::selected()
644 {
645     int retval = m_Slave.selected();
646     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "selected() => %d\n", retval );
647     return retval;
648 }
649
650 DBus::Int32
651 Enum::count()
652 {
653     int retval = m_Slave.count();
654     debugOutput( DEBUG_LEVEL_VERBOSE, "count() => %d\n", retval );
655     return retval;
656 }
657
658 DBus::String
659 Enum::getEnumLabel( const DBus::Int32 & idx )
660 {
661     std::string retval = m_Slave.getEnumLabel(idx);
662     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "getEnumLabel(%d) => %s\n", idx, retval.c_str() );
663     return retval;
664 }
665
666 // --- AttributeEnum
667 AttributeEnum::AttributeEnum( DBus::Connection& connection, std::string p, Element* parent, Control::AttributeEnum &slave)
668 : Element(connection, p, parent, slave)
669 , m_Slave(slave)
670 {
671     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Enum on '%s'\n",
672                  path().c_str() );
673 }
674
675 DBus::Int32
676 AttributeEnum::select( const DBus::Int32& idx )
677 {
678     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "select(%d)\n", idx );
679     return  m_Slave.select(idx);
680 }
681
682 DBus::Int32
683 AttributeEnum::selected()
684 {
685     int retval = m_Slave.selected();
686     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "selected() => %d\n", retval );
687     return retval;
688 }
689
690 DBus::Int32
691 AttributeEnum::count()
692 {
693     int retval = m_Slave.count();
694     debugOutput( DEBUG_LEVEL_VERBOSE, "count() => %d\n", retval );
695     return retval;
696 }
697
698 DBus::Int32
699 AttributeEnum::attributeCount()
700 {
701     int retval = m_Slave.attributeCount();
702     debugOutput( DEBUG_LEVEL_VERBOSE, "attributeCount() => %d\n", retval );
703     return retval;
704 }
705
706 DBus::String
707 AttributeEnum::getEnumLabel( const DBus::Int32 & idx )
708 {
709     std::string retval = m_Slave.getEnumLabel(idx);
710     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "getEnumLabel(%d) => %s\n", idx, retval.c_str() );
711     return retval;
712 }
713
714 DBus::String
715 AttributeEnum::getAttributeValue( const DBus::Int32 & idx )
716 {
717     std::string retval = m_Slave.getAttributeValue(idx);
718     debugOutput( DEBUG_LEVEL_VERBOSE, "getAttributeValue(%d) => %s\n", idx, retval.c_str() );
719     return retval;
720 }
721
722 DBus::String
723 AttributeEnum::getAttributeName( const DBus::Int32 & idx )
724 {
725     std::string retval = m_Slave.getAttributeName(idx);
726     debugOutput( DEBUG_LEVEL_VERBOSE, "getAttributeName(%d) => %s\n", idx, retval.c_str() );
727     return retval;
728 }
729
730 // --- ConfigRom
731
732 ConfigRomX::ConfigRomX( DBus::Connection& connection, std::string p, Element* parent, ConfigRom &slave)
733 : Element(connection, p, parent, slave)
734 , m_Slave(slave)
735 {
736     debugOutput( DEBUG_LEVEL_VERBOSE, "Created ConfigRomX on '%s'\n",
737                  path().c_str() );
738 }
739
740 DBus::String
741 ConfigRomX::getGUID( )
742 {
743     return m_Slave.getGuidString();
744 }
745
746 DBus::String
747 ConfigRomX::getVendorName( )
748 {
749     return m_Slave.getVendorName();
750 }
751
752 DBus::String
753 ConfigRomX::getModelName( )
754 {
755     return m_Slave.getModelName();
756 }
757
758 DBus::Int32
759 ConfigRomX::getVendorId( )
760 {
761     return m_Slave.getNodeVendorId();
762 }
763
764 DBus::Int32
765 ConfigRomX::getModelId( )
766 {
767     return m_Slave.getModelId();
768 }
769
770 DBus::Int32
771 ConfigRomX::getUnitVersion( )
772 {
773     return m_Slave.getUnitVersion();
774 }
775
776 // --- MatrixMixer
777
778 MatrixMixer::MatrixMixer( DBus::Connection& connection, std::string p, Element* parent, Control::MatrixMixer &slave)
779 : Element(connection, p, parent, slave)
780 , m_Slave(slave)
781 {
782     debugOutput( DEBUG_LEVEL_VERBOSE, "Created MatrixMixer on '%s'\n",
783                  path().c_str() );
784 }
785
786 DBus::String
787 MatrixMixer::getRowName( const DBus::Int32& row) {
788     return m_Slave.getRowName(row);
789 }
790
791 DBus::String
792 MatrixMixer::getColName( const DBus::Int32& col) {
793     return m_Slave.getColName(col);
794 }
795
796 DBus::Int32
797 MatrixMixer::canWrite( const DBus::Int32& row, const DBus::Int32& col) {
798     return m_Slave.canWrite(row,col);
799 }
800
801 DBus::Double
802 MatrixMixer::setValue( const DBus::Int32& row, const DBus::Int32& col, const DBus::Double& val ) {
803     return m_Slave.setValue(row,col,val);
804 }
805
806 DBus::Double
807 MatrixMixer::getValue( const DBus::Int32& row, const DBus::Int32& col) {
808     return m_Slave.getValue(row,col);
809 }
810
811 DBus::Int32
812 MatrixMixer::getRowCount( ) {
813     return m_Slave.getRowCount();
814 }
815
816 DBus::Int32
817 MatrixMixer::getColCount( ) {
818     return m_Slave.getColCount();
819 }
820
821 // --- CrossbarRouter
822
823 CrossbarRouter::CrossbarRouter( DBus::Connection& connection, std::string p, Element* parent, Control::CrossbarRouter &slave)
824 : Element(connection, p, parent, slave)
825 , m_Slave(slave)
826 {
827     debugOutput( DEBUG_LEVEL_VERBOSE, "Created CrossbarRouter on '%s'\n",
828                  path().c_str() );
829 }
830
831 DBus::String
832 CrossbarRouter::getSourceName(const DBus::Int32 &idx)
833 {
834     return m_Slave.getSourceName(idx);
835 }
836
837 DBus::String
838 CrossbarRouter::getDestinationName(const DBus::Int32 &idx)
839 {
840     return m_Slave.getDestinationName(idx);
841 }
842
843 DBus::Int32
844 CrossbarRouter::getSourceIndex(const DBus::String &name)
845 {
846     return m_Slave.getSourceIndex(name);
847 }
848
849 DBus::Int32
850 CrossbarRouter::getDestinationIndex(const DBus::String &name)
851 {
852     return m_Slave.getDestinationIndex(name);
853 }
854
855 std::vector< DBus::String >
856 CrossbarRouter::getSourceNames()
857 {
858     return m_Slave.getSourceNames();
859 }
860
861 std::vector< DBus::String >
862 CrossbarRouter::getDestinationNames()
863 {
864     return m_Slave.getDestinationNames();
865 }
866
867 std::vector< DBus::Struct<DBus::String, int> >
868 CrossbarRouter::getSources()
869 {
870     return std::vector< DBus::Struct<DBus::String, int> >();
871 }
872
873 std::vector< DBus::Struct<DBus::String, int> >
874 CrossbarRouter::getDestinations()
875 {
876     return std::vector< DBus::Struct<DBus::String, int> >();
877 }
878
879 std::vector< DBus::Int32 >
880 CrossbarRouter::getDestinationsForSource(const DBus::Int32 &idx)
881 {
882     return m_Slave.getDestinationsForSource(idx);
883 }
884
885 DBus::Int32
886 CrossbarRouter::getSourceForDestination(const DBus::Int32 &idx)
887 {
888     return m_Slave.getSourceForDestination(idx);
889 }
890
891 DBus::Bool
892 CrossbarRouter::canConnect(const DBus::Int32 &source, const DBus::Int32 &dest)
893 {
894     return m_Slave.canConnect(source, dest);
895 }
896
897 DBus::Bool
898 CrossbarRouter::setConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest, const DBus::Bool &enable)
899 {
900     return m_Slave.setConnectionState(source, dest, enable);
901 }
902
903 DBus::Bool
904 CrossbarRouter::getConnectionState(const DBus::Int32 &source, const DBus::Int32 &dest)
905 {
906     return m_Slave.getConnectionState(source, dest);
907 }
908
909 DBus::Bool
910 CrossbarRouter::canConnectNamed(const DBus::String& source, const DBus::String& dest)
911 {
912     return m_Slave.canConnect(source, dest);
913 }
914
915 DBus::Bool
916 CrossbarRouter::setConnectionStateNamed(const DBus::String &source, const DBus::String &dest, const DBus::Bool &enable)
917 {
918     return m_Slave.setConnectionState(source, dest, enable);
919 }
920
921 DBus::Bool
922 CrossbarRouter::getConnectionStateNamed(const DBus::String &source, const DBus::String &dest)
923 {
924     return m_Slave.getConnectionState(source, dest);
925 }
926
927 DBus::Bool
928 CrossbarRouter::clearAllConnections()
929 {
930     return m_Slave.clearAllConnections();
931 }
932
933 DBus::Int32
934 CrossbarRouter::getNbSources()
935 {
936     return m_Slave.getNbSources();
937 }
938
939 DBus::Int32
940 CrossbarRouter::getNbDestinations()
941 {
942     return m_Slave.getNbDestinations();
943 }
944
945 DBus::Bool
946 CrossbarRouter::hasPeakMetering()
947 {
948     return m_Slave.hasPeakMetering();
949 }
950
951 DBus::Double
952 CrossbarRouter::getPeakValue(const DBus::Int32 &source, const DBus::Int32 &dest)
953 {
954     return m_Slave.getPeakValue(source, dest);
955 }
956 std::vector< DBus::Struct<int, double> >
957 CrossbarRouter::getPeakValues()
958 {
959     //return std::vector< DBus::Struct<int, int, double> >();
960     std::vector< DBus::Struct<int, double> > out;
961     Control::CrossbarRouter::PeakValues values = m_Slave.getPeakValues();
962     for ( unsigned int i=0; i<values.size(); ++i ) {
963         DBus::Struct<int, double> tmp;
964         tmp._1 = values[i].destination;
965         tmp._2 = values[i].peakvalue;
966         out.push_back(tmp);
967     }
968     return out;
969 }
970
971 std::vector< DBus::Int32 >
972 CrossbarRouter::getConnectionMap()
973 {
974     std::vector< DBus::Int32 >connmap;
975     unsigned int nb_sources = m_Slave.getNbSources();
976     unsigned int nb_destinations = m_Slave.getNbDestinations();
977     unsigned int nb_entries = nb_sources * nb_destinations;
978
979     int map_data[nb_entries];
980
981     if(!m_Slave.getConnectionMap(map_data)) {
982         debugError("Could not fetch connection map\n");
983         return connmap;
984     }
985
986     for(unsigned int i=0; i<nb_entries; i++) {
987         connmap.push_back(map_data[i]);
988     }
989     return connmap;
990 }
991
992 DBus::Int32
993 CrossbarRouter::setConnectionMap(const std::vector< DBus::Int32 >&connmap)
994 {
995     unsigned int nb_sources = m_Slave.getNbSources();
996     unsigned int nb_destinations = m_Slave.getNbDestinations();
997     unsigned int nb_entries = nb_sources * nb_destinations;
998
999     if(connmap.size() != nb_entries) {
1000         debugError("bogus map size\n");
1001         return false;
1002     }
1003
1004     int map_data[nb_entries];
1005     for (unsigned int i=0; i<nb_entries; i++) {
1006         map_data[i] = connmap.at(i);
1007     }
1008     return m_Slave.setConnectionMap(map_data);
1009 }
1010
1011
1012 } // end of namespace Control
Note: See TracBrowser for help on using the browser.