2 # Copyright (C) 2005-2008 by Pieter Palmers
3 # 2007-2008 by Arnold Krille
5 # This file is part of FFADO
6 # FFADO = Free Firewire (pro-)audio drivers for linux
8 # FFADO is based upon FreeBoB.
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import dbus
.mainloop
.qt
26 dbus
.mainloop
.qt
.DBusQtMainLoop(set_as_default
=True)
29 log
= logging
.getLogger('dbus')
31 class ControlInterface
:
32 def __init__(self
, servername
, basepath
):
33 self
.basepath
=basepath
34 self
.servername
=servername
35 self
.bus
=dbus
.SessionBus()
37 def setContignuous(self
, subpath
, v
, idx
=None):
39 path
= self
.basepath
+ subpath
40 dev
= self
.bus
.get_object(self
.servername
, path
)
41 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Continuous')
45 dev_cont
.setValueIdx(idx
,v
)
47 log
.error("Failed to set Continuous %s on server %s" % (path
, self
.servername
))
49 def getContignuous(self
, subpath
, idx
=None):
51 path
= self
.basepath
+ subpath
52 dev
= self
.bus
.get_object(self
.servername
, path
)
53 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Continuous')
55 return dev_cont
.getValue()
57 return dev_cont
.getValueIdx(idx
)
59 log
.error("Failed to get Continuous %s on server %s" % (path
, self
.servername
))
62 def setDiscrete(self
, subpath
, v
, idx
=None):
64 path
= self
.basepath
+ subpath
65 dev
= self
.bus
.get_object(self
.servername
, path
)
66 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Discrete')
70 dev_cont
.setValueIdx(v
, idx
)
72 log
.error("Failed to set Discrete %s on server %s" % (path
, self
.servername
))
74 def getDiscrete(self
, subpath
, idx
=None):
76 path
= self
.basepath
+ subpath
77 dev
= self
.bus
.get_object(self
.servername
, path
)
78 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Discrete')
80 return dev_cont
.getValue()
82 return dev_cont
.getValueIdx(idx
)
84 log
.error("Failed to get Discrete %s on server %s" % (path
, self
.servername
))
87 def setText(self
, subpath
, v
):
89 path
= self
.basepath
+ subpath
90 dev
= self
.bus
.get_object(self
.servername
, path
)
91 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Text')
94 log
.error("Failed to set Text %s on server %s" % (path
, self
.servername
))
96 def getText(self
, subpath
):
98 path
= self
.basepath
+ subpath
99 dev
= self
.bus
.get_object(self
.servername
, path
)
100 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Text')
101 return dev_cont
.getValue()
103 log
.error("Failed to get Text %s on server %s" % (path
, self
.servername
))
106 def setMatrixMixerValue(self
, subpath
, row
, col
, v
):
108 path
= self
.basepath
+ subpath
109 dev
= self
.bus
.get_object(self
.servername
, path
)
110 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.MatrixMixer')
111 dev_cont
.setValue(row
, col
, v
)
113 log
.error("Failed to set MatrixMixer %s on server %s" % (path
, self
.servername
))
115 def getMatrixMixerValue(self
, subpath
, row
, col
):
117 path
= self
.basepath
+ subpath
118 dev
= self
.bus
.get_object(self
.servername
, path
)
119 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.MatrixMixer')
120 return dev_cont
.getValue(row
, col
)
122 log
.error("Failed to get MatrixMixer %s on server %s" % (path
, self
.servername
))
125 def enumSelect(self
, subpath
, v
):
127 path
= self
.basepath
+ subpath
128 dev
= self
.bus
.get_object(self
.servername
, path
)
129 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Enum')
132 log
.error("Failed to select %s on server %s" % (path
, self
.servername
))
134 def enumSelected(self
, subpath
):
136 path
= self
.basepath
+ subpath
137 dev
= self
.bus
.get_object(self
.servername
, path
)
138 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Enum')
139 return dev_cont
.selected()
141 log
.error("Failed to get selected enum %s on server %s" % (path
, self
.servername
))
144 def enumGetLabel(self
, subpath
, v
):
146 path
= self
.basepath
+ subpath
147 dev
= self
.bus
.get_object(self
.servername
, path
)
148 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Enum')
149 return dev_cont
.getEnumLabel(v
)
151 log
.error("Failed to get enum label %s on server %s" % (path
, self
.servername
))
154 def enumCount(self
, subpath
):
156 path
= self
.basepath
+ subpath
157 dev
= self
.bus
.get_object(self
.servername
, path
)
158 dev_cont
= dbus
.Interface(dev
, dbus_interface
='org.ffado.Control.Element.Enum')
159 return dev_cont
.count()
161 log
.error("Failed to get enum count %s on server %s" % (path
, self
.servername
))
164 class DeviceManagerInterface
:
165 """ Implementation of the singleton """
166 def __init__(self
, servername
, basepath
):
167 self
.basepath
=basepath
+ '/DeviceManager'
168 self
.servername
=servername
169 self
.bus
=dbus
.SessionBus()
170 self
.dev
= self
.bus
.get_object(self
.servername
, self
.basepath
)
171 self
.iface
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.Container')
173 self
.updateSignalHandlers
= []
174 self
.updateSignalHandlerArgs
= {}
175 self
.preUpdateSignalHandlers
= []
176 self
.preUpdateSignalHandlerArgs
= {}
177 self
.postUpdateSignalHandlers
= []
178 self
.postUpdateSignalHandlerArgs
= {}
179 self
.destroyedSignalHandlers
= []
180 self
.destroyedSignalHandlerArgs
= {}
182 # signal reception does not work yet since we need a mainloop for that
183 # and qt3 doesn't provide one for python/dbus
185 log
.debug("connecting to: Updated on %s (server: %s)" % (self
.basepath
, self
.servername
))
186 self
.dev
.connect_to_signal("Updated", self
.updateSignal
, \
187 dbus_interface
="org.ffado.Control.Element.Container")
188 self
.dev
.connect_to_signal("PreUpdate", self
.preUpdateSignal
, \
189 dbus_interface
="org.ffado.Control.Element.Container")
190 self
.dev
.connect_to_signal("PostUpdate", self
.postUpdateSignal
, \
191 dbus_interface
="org.ffado.Control.Element.Container")
192 self
.dev
.connect_to_signal("Destroyed", self
.destroyedSignal
, \
193 dbus_interface
="org.ffado.Control.Element.Container")
195 except dbus
.DBusException
:
196 traceback
.print_exc()
198 def registerPreUpdateCallback(self
, callback
, arg
=None):
199 if not callback
in self
.preUpdateSignalHandlers
:
200 self
.preUpdateSignalHandlers
.append(callback
)
201 # always update the argument
202 self
.preUpdateSignalHandlerArgs
[callback
] = arg
204 def registerPostUpdateCallback(self
, callback
, arg
=None):
205 if not callback
in self
.postUpdateSignalHandlers
:
206 self
.postUpdateSignalHandlers
.append(callback
)
207 # always update the argument
208 self
.postUpdateSignalHandlerArgs
[callback
] = arg
210 def registerUpdateCallback(self
, callback
, arg
=None):
211 if not callback
in self
.updateSignalHandlers
:
212 self
.updateSignalHandlers
.append(callback
)
213 # always update the argument
214 self
.updateSignalHandlerArgs
[callback
] = arg
216 def registerDestroyedCallback(self
, callback
, arg
=None):
217 if not callback
in self
.destroyedSignalHandlers
:
218 self
.destroyedSignalHandlers
.append(callback
)
219 # always update the argument
220 self
.destroyedSignalHandlerArgs
[callback
] = arg
222 def updateSignal(self
):
223 log
.debug("Received update signal")
224 for handler
in self
.updateSignalHandlers
:
225 arg
= self
.updateSignalHandlerArgs
[handler
]
232 log
.error("Failed to execute handler %s" % handler
)
234 def preUpdateSignal(self
):
235 log
.debug("Received pre-update signal")
236 for handler
in self
.preUpdateSignalHandlers
:
237 arg
= self
.preUpdateSignalHandlerArgs
[handler
]
244 log
.error("Failed to execute handler %s" % handler
)
246 def postUpdateSignal(self
):
247 log
.debug("Received post-update signal")
248 for handler
in self
.postUpdateSignalHandlers
:
249 arg
= self
.postUpdateSignalHandlerArgs
[handler
]
256 log
.error("Failed to execute handler %s" % handler
)
258 def destroyedSignal(self
):
259 log
.debug("Received destroyed signal")
260 for handler
in self
.destroyedSignalHandlers
:
261 arg
= self
.destroyedSignalHandlerArgs
[handler
]
268 log
.error("Failed to execute handler %s" % handler
)
270 def getNbDevices(self
):
271 return self
.iface
.getNbElements()
272 def getDeviceName(self
, idx
):
273 return self
.iface
.getElementName(idx
)
275 class ConfigRomInterface
:
276 def __init__(self
, servername
, devicepath
):
277 self
.basepath
=devicepath
+ '/ConfigRom'
278 self
.servername
=servername
279 self
.bus
=dbus
.SessionBus()
280 self
.dev
= self
.bus
.get_object(self
.servername
, self
.basepath
)
281 self
.iface
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.ConfigRomX')
283 return self
.iface
.getGUID()
284 def getVendorName(self
):
285 return self
.iface
.getVendorName()
286 def getModelName(self
):
287 return self
.iface
.getModelName()
288 def getVendorId(self
):
289 return self
.iface
.getVendorId()
290 def getModelId(self
):
291 return self
.iface
.getModelId()
292 def getUnitVersion(self
):
293 return self
.iface
.getUnitVersion()
295 class ClockSelectInterface
:
296 def __init__(self
, servername
, devicepath
):
297 self
.basepath
=devicepath
+ '/Generic/ClockSelect'
298 self
.servername
=servername
299 self
.bus
=dbus
.SessionBus()
300 self
.dev
= self
.bus
.get_object(self
.servername
, self
.basepath
)
301 self
.iface
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.AttributeEnum')
302 self
.iface_element
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.Element')
304 return self
.iface
.count()
305 def select(self
, idx
):
306 return self
.iface
.select(idx
)
308 return self
.iface
.selected()
309 def getEnumLabel(self
, idx
):
310 return self
.iface
.getEnumLabel(idx
)
311 def attributeCount(self
):
312 return self
.iface
.attributeCount()
313 def getAttributeValue(self
, idx
):
314 return self
.iface
.getAttributeValue(idx
)
315 def getAttributeName(self
, idx
):
316 return self
.iface
.getAttributeName(idx
)
317 def canChangeValue(self
):
318 return self
.iface_element
.canChangeValue()
321 def __init__(self
, servername
, basepath
):
322 self
.basepath
= basepath
323 self
.servername
= servername
324 self
.bus
= dbus
.SessionBus()
325 self
.dev
= self
.bus
.get_object(self
.servername
, self
.basepath
)
326 self
.iface
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.Enum')
327 self
.iface_element
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.Element')
329 return self
.iface
.count()
330 def select(self
, idx
):
331 return self
.iface
.select(idx
)
333 return self
.iface
.selected()
334 def getEnumLabel(self
, idx
):
335 return self
.iface
.getEnumLabel(idx
)
336 def canChangeValue(self
):
337 return self
.iface_element
.canChangeValue()
338 def devConfigChanged(self
, idx
):
339 return self
.iface
.devConfigChanged(idx
)
341 class SamplerateSelectInterface(EnumInterface
):
342 def __init__(self
, servername
, devicepath
):
343 EnumInterface
.__init
__(self
, servername
, devicepath
+ '/Generic/SamplerateSelect')
345 class StreamingStatusInterface(EnumInterface
):
346 def __init__(self
, servername
, devicepath
):
347 EnumInterface
.__init
__(self
, servername
, devicepath
+ '/Generic/StreamingStatus')
350 def __init__(self
, servername
, basepath
):
351 self
.basepath
=basepath
352 self
.servername
=servername
353 self
.bus
=dbus
.SessionBus()
354 self
.dev
= self
.bus
.get_object( self
.servername
, self
.basepath
)
355 self
.iface
= dbus
.Interface( self
.dev
, dbus_interface
="org.ffado.Control.Element.Text" )
356 self
.iface_element
= dbus
.Interface(self
.dev
, dbus_interface
='org.ffado.Control.Element.Element')
358 return self
.iface
.getValue()
359 def setText(self
,text
):
360 self
.iface
.setValue(text
)
361 def canChangeValue(self
):
362 return self
.iface_element
.canChangeValue()