continue
if l[:15].lower() == "signed-off-by: ":
continue
+ if l[:10].lower() == "acked-by: ":
+ continue
+ if l[:6].lower() == "from: ":
+ continue
+ if l[:4].lower() == "cc: ":
+ continue
print(': %s %s' % (first, esc(l)))
first = " "
print('</text>')
['/soc/codecs/Kconfig', 'SoC Layer'],
['/soc/codecs/l3.(c|h)', 'SoC L3 bus'],
['/soc/codecs/ac97.(c|h)', 'SoC Codec AC97'],
+ ['/include/wm2000.h', 'SoC Codec WM2000'],
+ ['/soc/codecs/wm2000.(c|h)', 'SoC Codec WM2000'],
['/soc/codecs/wm8350.(c|h)', 'SoC Codec WM8350'],
['/soc/codecs/wm8400.(c|h)', 'SoC Codec WM8400'],
['/soc/codecs/wm8510.(c|h)', 'SoC Codec WM8510'],
['/soc/codecs/wm8776.(c|h)', 'SoC Codec WM8776'],
['/soc/codecs/wm8794.(c|h)', 'SoC Codec WM8794'],
['/soc/codecs/wm8900.(c|h)', 'SoC Codec WM8900'],
+ ['/include/wm8903.h', 'SoC Codec WM8903'],
['/soc/codecs/wm8903.(c|h)', 'SoC Codec WM8903'],
['/include/wm8904.h', 'SoC Codec WM8904'],
['/soc/codecs/wm8904.(c|h)', 'SoC Codec WM8904'],
['/soc/codecs/wm8940.(c|h)', 'SoC Codec WM8940'],
['/include/wm8955.h', 'SoC Codec WM8955'],
['/soc/codecs/wm8955.(c|h)', 'SoC Codec WM8955'],
+ ['/include/wm8960.h', 'SoC Codec WM8960'],
['/soc/codecs/wm8960.(c|h)', 'SoC Codec WM8960'],
['/soc/codecs/wm8961.(c|h)', 'SoC Codec WM8961'],
['/soc/codecs/wm8971.(c|h)', 'SoC Codec WM8971'],
['/soc/codecs/wm8974.(c|h)', 'SoC Codec WM8974'],
+ ['/soc/codecs/wm8978.(c|h)', 'SoC Codec WM8978'],
['/soc/codecs/wm8988.(c|h)', 'SoC Codec WM8988'],
['/soc/codecs/wm8990.(c|h)', 'SoC Codec WM8990'],
['/soc/codecs/wm_hubs.(c|h)', 'SoC Codec WM8993/4'],
['/include/wm8993.h', 'SoC Codec WM8993/4'],
['/soc/codecs/wm8993.(c|h)', 'SoC Codec WM8993/4'],
+ ['/soc/codecs/wm8994.(c|h)', 'SoC Codec WM8994'],
['/include/wm9081.h', 'SoC Codec WM9081'],
['/soc/codecs/wm9081.(c|h)', 'SoC Codec WM9081'],
['/soc/codecs/wm9705.(c|h)', 'SoC Codec WM9705'],
['/soc/codecs/cs4270.(c|h)', 'SoC Codec CS4270'],
['/soc/codecs/ad1836.(c|h)', 'SoC Codec AD1836'],
['/soc/codecs/ad1938.(c|h)', 'SoC Codec AD1938'],
+ ['/soc/codecs/ad193x.(c|h)', 'SoC Codec AD193X'],
['/soc/codecs/ad1963.(c|h)', 'SoC Codec AD1963'],
['/soc/codecs/ad1980.(c|h)', 'SoC Codec AD1980'],
['/soc/codecs/tlv320aic23.(c|h)', 'SoC Codec TLV320AIC23'],
['/soc/codecs/ssm2602.(c|h)', 'SoC Codec SSM2602'],
['/soc/codecs/ad73311.(c|h)', 'SoC Codec AD73311'],
['/soc/codecs/twl4030.(c|h)', 'SoC Codec TWL4030'],
+ ['/soc/codecs/twl6040.(c|h)', 'SoC Codec TWL6040'],
['/soc/codecs/pcm3008.(c|h)', 'SoC Codec PCM3008'],
['/soc/codecs/cx20442.(c|h)', 'SoC Codec CX20442'],
['/soc/codecs/max9877.(c|h)', 'SoC Codec MAX9877'],
['/soc/codecs/spdif_transciever.(c|h)', 'SoC Codec DIT SPDI/F'],
['/soc/codecs/ads117x.(c|h)', 'SoC Codec ads1174/8'],
['/soc/codecs/da7210.(c|h)', 'SoC Codec DA7210'],
+ ['/soc/codecs/cq93vc.(c|h)', 'SoC Codec CQ0093 Voice'],
['/include/tpa6130a2-plat.h', 'SoC Codec TPA6130A2'],
['/soc/codecs/tpa6130a2.(c|h)', 'SoC Codec TPA6130A2'],
['/soc/codecs', 'ERROR'],
['/soc/at91/.*', 'SoC Audio for the Atmel AT91 System-on-Chip'],
['/soc/imx/.*', 'SoC Audio for Freecale i.MX1x i.MX2x CPUs'],
['/soc/txx9/.*', 'SoC Audio for TXx9'],
+ ['/soc/pxa/z2.c', 'SoC PXA2xx Aeronix Zipit Z2'],
['/soc/pxa/spitz.c', 'SoC PXA2xx Spitz'],
['/soc/pxa/corgi.c', 'SoC PXA2xx Corgi'],
['/soc/pxa/poodle.c', 'SoC PXA2xx Poodle'],
['/soc', 'ERROR'],
['/usb/usx2y/.*', 'USB USX2Y'],
['/usb/caiaq/.*', 'USB caiaq'],
+ ['/usb/misc/ua101.(c|h)', 'USB Edirol UA101 driver'],
['/usb/Kconfig', 'USB'],
['/usb/Makefile', 'USB'],
- ['/usb/usbaudio.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/card.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/midi.(c|h|inc|patch)', 'USB generic driver'],
['/usb/usbmidi.(c|h|inc|patch)', 'USB generic driver'],
- ['/usb/usbmixer.(c|h|patch)', 'USB generic driver'],
- ['/usb/usbquirks.(c|h)', 'USB generic driver'],
- ['/usb/usbmixer_maps.c', 'USB generic driver'],
- ['/usb/usbcompat.h', 'USB generic driver'],
- ['/usb/ua101.(c|h)', 'Edirol UA-101 driver'],
+ ['/usb/mixer.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/usbmixer.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/usbmixer_maps.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/usbaudio.(c|h|inc|patch)', 'USB generic driver'],
+ ['/usb/mixer_quirks.(c|h|patch)', 'USB generic driver'],
+ ['/usb/quirks.(c|h|patch)', 'USB generic driver'],
+ ['/usb/quirks-table.(c|h|patch)', 'USB generic driver'],
+ ['/usb/usbquirks.(c|h|patch)', 'USB generic driver'],
+ ['/usb/endpoint.(c|h|patch)', 'USB generic driver'],
+ ['/usb/helper.(c|h|patch)', 'USB generic driver'],
+ ['/usb/debug.(c|h|patch)', 'USB generic driver'],
+ ['/usb/urb.(c|h|patch)', 'USB generic driver'],
+ ['/usb/pcm.(c|h)', 'USB generic driver'],
+ ['/usb/format.(c|h)', 'USB generic driver'],
+ ['/usb/proc.(c|h)', 'USB generic driver'],
+ ['/usb/mixer_maps.c', 'USB generic driver'],
+ ['/usb/usbcompat.(c|h)', 'USB generic driver'],
+ ['/usb/ua101.(c|h)', 'USB Edirol UA101 driver'],
['/usb', 'ERROR'],
['/include/atmel-abdac.h', 'Atmel on-chip Audio Bitstream DAC (ABDAC)'],
['/include/atmel-ac97c.h', 'Atmel on-chip Audio Bitstream DAC (ABDAC)'],
['/include/compat_22.h', 'ALSA Core'],
['/include/linux/pci_ids.h', 'ALSA Core'],
['/include/autoconf.*', 'ALSA Core'],
+ ['/include/alsa-autoconf.*', 'ALSA Core'],
['/include/platform_device_compat.h', 'ALSA Core'],
['/include/typedefs.h', 'ALSA Core'],
['/include/old/gf1.h', 'OLD GF1 header'],
['/sb16_csp/.*', 'sb16_csp'],
['/sscape_ctl/.*', 'sscape_ctl'],
['/usx2yloader/.*', 'usx2yloader'],
+ ['/hwmixvolume/.*', 'hwmixvolume'],
['/seq/sbiload/.*', 'sbiload'],
['/seq/cvscompile', 'Core'],
['/seq/hgcompile', 'Core'],
GERRORS = 0
TMPDIR = '/dev/shm/alsatool'
SMTP_SERVER = 'localhost'
-GIT_KERNEL_MERGE = 'v2.6.32'
-GIT_DRIVER_MERGE = 'v1.0.21'
+GIT_KERNEL_MERGE = 'v2.6.33'
+GIT_DRIVER_MERGE = 'v1.0.22'
GIT_MERGE_REPOS = [
('git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git', 'master', 'linux-2.6', 'http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'),
('git://git.alsa-project.org/alsa-kernel.git', 'fixes', 'perex-fixes', 'http://git.alsa-project.org/http/alsa-kernel.git'),
rmtree("alsa-kernel-repo/Documentation/DocBook")
mkdir("alsa-kernel-repo/Documentation/DocBook")
system("mv alsa-kernel-repo/Documentation/alsa-driver-api.tmpl alsa-kernel-repo/Documentation/DocBook")
- for i in ['.git-ok-commits', '.hgignore', '.hgtags', '.gitignore', 'kernel', 'scripts', 'oss']:
+ for i in ['.git-ok-commits', '.hgignore', '.hgtags', '.gitignore', 'kernel', 'scripts',
+ 'oss', 'usb/usbmixer.h', 'usb/usbmixer_maps.c']:
if isdir("alsa-kmirror-repo/%s" % i):
rmtree("alsa-kmirror-repo/%s" % i)
elif exists("alsa-kmirror-repo/%s" % i):
'usb/caiaq/caiaq-device.c', 'usb/caiaq/caiaq-device.h',
'usb/caiaq/caiaq-input.c', 'usb/caiaq/caiaq-input.h',
'usb/caiaq/caiaq-midi.c', 'usb/caiaq/caiaq-midi.h',
+ 'usb/usbmixer.h',
+ 'usb/usbmixer_maps.c',
'isa/wavefront/yss225.c'
]:
if isdir("alsa-kernel-repo/%s" % i):
PIN_WIDGET_CONTROL_VREF, DIG1_BITS, GPIO_IDS, \
HDA_INPUT, HDA_OUTPUT
from hda_proc import DecodeProcFile, DecodeAlsaInfoFile, HDACodecProc
+from hda_guilib import *
+from hda_graph import create_graph
CODEC_TREE = {}
DIFF_TREE = {}
def read_nodes3(card, codec, proc_file):
c = HDACodecProc(card, codec, proc_file)
c.analyze()
+ c.graph(dump=True)
if not card in CODEC_TREE:
CODEC_TREE[card] = {}
DIFF_TREE[card] = {}
ITALIC_COLUMN
) = range(5)
-def get_fixed_font():
- return pango.FontDescription("Misc Fixed,Courier Bold 9")
-
class HDAAnalyzer(gtk.Window):
info_buffer = None
node_window = None
button.connect("clicked", self.__diff_clicked)
self.tooltips.set_tip(button, "Show settings diff for selected codec.")
hbox1.pack_start(button)
+ button = gtk.Button("Graph")
+ button.connect("clicked", self.__graph_clicked)
+ self.tooltips.set_tip(button, "Show graph for selected codec.")
+ hbox1.pack_start(button)
vbox.pack_start(hbox1, False, False)
hbox.pack_start(vbox, False, False)
self.notebook = gtk.Notebook()
hbox.pack_start(self.notebook, expand=True)
- self.node_window = self.__create_node()
+ self.node_window = gtk.Table()
self._new_notebook_page(self.node_window, '_Node editor')
scrolled_window, self.info_buffer = self.__create_text(self.__dump_visibility)
gtk.main_quit()
+ def simple_dialog(self, type, msg):
+ dialog = gtk.MessageDialog(self,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ type, gtk.BUTTONS_OK, msg)
+ dialog.run()
+ dialog.destroy()
+
def __about_clicked(self, button):
dialog = gtk.Dialog('About', self,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
msg = "Setting for codec %s/%s (%s) was reverted!" % (self.codec.card, self.codec.device, self.codec.name)
type = gtk.MESSAGE_INFO
- dialog = gtk.MessageDialog(self,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- type, gtk.BUTTONS_OK, msg)
- dialog.run()
- dialog.destroy()
+ self.simple_dialog(type, msg)
def __diff_clicked(self, button):
if not self.codec:
+ self.simple_dialog(gtk.MESSAGE_WARNING, "Please, select a codec in left codec/node tree.")
return
dialog = gtk.Dialog('Diff', self,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
dialog.run()
dialog.destroy()
+ def __graph_clicked(self, button):
+ if not self.codec:
+ self.simple_dialog(gtk.MESSAGE_WARNING, "Please, select a codec in left codec/node tree.")
+ return
+ create_graph(self.codec)
+
def __refresh(self):
self.load()
self.__dump_visibility(None, None)
for i in CODEC_TREE[self.card]:
card = CODEC_TREE[self.card][i].mcard
break
- self.__build_card(card)
+ self.node_window.add(NodeGui(card=card))
elif codec:
- self.__build_codec(codec)
+ self.node_window.add(NodeGui(codec=codec))
else:
return
else:
- self.__build_node(n)
+ self.node_window.add(NodeGui(node=n))
self.node_window.show_all()
def _new_notebook_page(self, widget, label):
return scrolled_window, buffer
- def __create_node(self):
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window.set_shadow_type(gtk.SHADOW_IN)
- return scrolled_window
-
- def __new_text_view(self, text=None):
- text_view = gtk.TextView()
- text_view.set_border_width(4)
- fontName = get_fixed_font()
- text_view.modify_font(fontName)
- if not text is None:
- buffer = gtk.TextBuffer(None)
- iter = buffer.get_iter_at_offset(0)
- if text[-1] == '\n':
- text = text[:-1]
- buffer.insert(iter, text)
- text_view.set_buffer(buffer)
- text_view.set_editable(False)
- text_view.set_cursor_visible(False)
- return text_view
-
- def __build_node_caps(self, node):
- frame = gtk.Frame('Node Caps')
- frame.set_border_width(4)
- if len(node.wcaps_list) == 0:
- return frame
- str = ''
- for i in node.wcaps_list:
- str += node.wcap_name(i) + '\n'
- frame.add(self.__new_text_view(text=str))
- return frame
-
- def __node_connection_toggled(self, widget, row, data):
- model, node = data
- if not model[row][0]:
- node.set_active_connection(int(row))
- for r in model:
- r[0] = False
- idx = 0
- for r in model:
- r[0] = node.active_connection == idx
- idx += 1
-
- def __build_connection_list(self, node):
- frame = gtk.Frame('Connection List')
- frame.set_border_width(4)
- sw = gtk.ScrolledWindow()
- #sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
- sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- frame.add(sw)
- if node.conn_list and node.connections:
- model = gtk.ListStore(
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_STRING
- )
- idx = 0
- for i in node.connections:
- iter = model.append()
- node1 = self.codec.get_node(node.connections[idx])
- model.set(iter, 0, node.active_connection == idx,
- 1, node1.name())
- idx += 1
- treeview = gtk.TreeView(model)
- treeview.set_rules_hint(True)
- treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
- treeview.set_size_request(300, 30 + len(node.connections) * 25)
- renderer = gtk.CellRendererToggle()
- renderer.set_radio(True)
- if node.active_connection != None:
- renderer.connect("toggled", self.__node_connection_toggled, (model, node))
- column = gtk.TreeViewColumn("Active", renderer, active=0)
- treeview.append_column(column)
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn("Destination Node", renderer, text=1, editable=False)
- treeview.append_column(column)
- sw.add(treeview)
- return frame
-
- def __amp_mute_toggled(self, button, data):
- caps, vals, idx = data
- val = button.get_active()
- vals.set_mute(idx, val)
- button.set_active(vals.vals[idx] & 0x80)
-
- def __amp_value_changed(self, adj, data):
- caps, vals, idx = data
- val = int(adj.get_value())
- vals.set_value(idx, val)
- adj.set_value(vals.vals[idx] & 0x7f)
-
- def __build_amps(self, node):
-
- def build_caps(title, caps, vals):
- if caps and caps.ofs is None:
- caps = caps.dir == HDA_INPUT and \
- node.codec.amp_caps_in or node.codec.amp_caps_out
- title += ' (Global)'
- frame = gtk.Frame(title)
- frame.set_border_width(4)
- vbox = gtk.VBox(False, 0)
- if caps:
- str = 'Offset: %d\n' % caps.ofs
- str += 'Number of steps: %d\n' % caps.nsteps
- str += 'Step size: %d\n' % caps.stepsize
- str += 'Mute: %s\n' % (caps.mute and "True" or "False")
- vbox.pack_start(self.__new_text_view(text=str), True, True, 0)
- idx = 0
- frame1 = None
- vbox1 = None
- for val in vals.vals:
- if vals.stereo and idx & 1 == 0:
- frame1 = gtk.Frame()
- vbox.pack_start(frame1, False, False)
- vbox1 = gtk.VBox(False, 0)
- frame1.add(vbox1)
- hbox = gtk.HBox(False, 0)
- label = gtk.Label('Val[%d]' % idx)
- hbox.pack_start(label, False, False)
- if caps.mute:
- checkbutton = gtk.CheckButton('Mute')
- checkbutton.set_active(val & 0x80 and True or False)
- checkbutton.connect("toggled", self.__amp_mute_toggled, (caps, vals, idx))
- hbox.pack_start(checkbutton, False, False)
- if caps.stepsize > 0:
- adj = gtk.Adjustment((val & 0x7f) % (caps.nsteps+1), 0.0, caps.nsteps+1, 1.0, 1.0, 1.0)
- scale = gtk.HScale(adj)
- scale.set_digits(0)
- scale.set_value_pos(gtk.POS_RIGHT)
- adj.connect("value_changed", self.__amp_value_changed, (caps, vals, idx))
- hbox.pack_start(scale, True, True)
- if vbox1:
- vbox1.pack_start(hbox, False, False)
- else:
- vbox.pack_start(hbox, False, False)
- idx += 1
- frame.add(vbox)
- return frame
-
- hbox = gtk.HBox(False, 0)
- c = build_caps('Input Amplifier',
- node.in_amp and node.amp_caps_in or None,
- node.in_amp and node.amp_vals_in or None)
- hbox.pack_start(c)
- c = build_caps('Output Amplifier',
- node.out_amp and node.amp_caps_out or None,
- node.out_amp and node.amp_vals_out or None)
- hbox.pack_start(c)
-
- return hbox
-
- def __pincap_eapdbtl_toggled(self, button, data):
- node, name = data
- node.eapdbtl_set_value(name, button.get_active())
- button.set_active(name in node.pincap_eapdbtl)
-
- def __pinctls_toggled(self, button, data):
- node, name = data
- node.pin_widget_control_set_value(name, button.get_active())
- button.set_active(name in node.pinctl)
-
- def __pinctls_vref_change(self, combobox, node):
- index = combobox.get_active()
- idx1 = 0
- for name in PIN_WIDGET_CONTROL_VREF:
- if not name: continue
- if idx1 == index:
- node.pin_widget_control_set_value('vref', name)
- break
- idx1 += 1
- idx = idx1 = 0
- for name in PIN_WIDGET_CONTROL_VREF:
- if name == node.pinctl_vref:
- combobox.set_active(idx1)
- break
- if name != None:
- idx1 += 1
-
- def __build_pin(self, node):
- hbox = gtk.HBox(False, 0)
-
- if node.pincap or node.pincap_vref or node.pincap_eapdbtl:
- vbox = gtk.VBox(False, 0)
- if node.pincap or node.pincap_vref:
- frame = gtk.Frame('PIN Caps')
- frame.set_border_width(4)
- str = ''
- for i in node.pincap:
- str += node.pincap_name(i) + '\n'
- for i in node.pincap_vref:
- str += 'VREF_%s\n' % i
- frame.add(self.__new_text_view(text=str))
- vbox.pack_start(frame)
- if 'EAPD' in node.pincap:
- frame = gtk.Frame('EAPD')
- frame.set_border_width(4)
- vbox1 = gtk.VBox(False, 0)
- for name in EAPDBTL_BITS:
- checkbutton = gtk.CheckButton(name)
- checkbutton.set_active(node.pincap_eapdbtls & (1 << EAPDBTL_BITS[name]))
- checkbutton.connect("toggled", self.__pincap_eapdbtl_toggled, (node, name))
- vbox1.pack_start(checkbutton, False, False)
- frame.add(vbox1)
- vbox.pack_start(frame, False, False)
- hbox.pack_start(vbox)
-
- vbox = gtk.VBox(False, 0)
-
- frame = gtk.Frame('Config Default')
- frame.set_border_width(4)
- str = 'Jack connection: %s\n' % node.jack_conn_name
- str += 'Jack type: %s\n' % node.jack_type_name
- str += 'Jack location: %s\n' % node.jack_location_name
- str += 'Jack location2: %s\n' % node.jack_location2_name
- str += 'Jack connector: %s\n' % node.jack_connector_name
- str += 'Jack color: %s\n' % node.jack_color_name
- if 'NO_PRESENCE' in node.defcfg_misc:
- str += 'No presence\n'
- frame.add(self.__new_text_view(text=str))
- vbox.pack_start(frame)
-
- frame = gtk.Frame('Widget Control')
- frame.set_border_width(4)
- vbox1 = gtk.VBox(False, 0)
- for name in PIN_WIDGET_CONTROL_BITS:
- checkbutton = gtk.CheckButton(name)
- checkbutton.set_active(node.pinctls & (1 << PIN_WIDGET_CONTROL_BITS[name]))
- checkbutton.connect("toggled", self.__pinctls_toggled, (node, name))
- vbox1.pack_start(checkbutton, False, False)
- if node.pincap_vref:
- combobox = gtk.combo_box_new_text()
- idx = idx1 = active = 0
- for name in PIN_WIDGET_CONTROL_VREF:
- if name == node.pinctl_vref: active = idx1
- if name:
- combobox.append_text(name)
- idx1 += 1
- idx += 1
- combobox.set_active(active)
- combobox.connect("changed", self.__pinctls_vref_change, node)
- hbox1 = gtk.HBox(False, 0)
- label = gtk.Label('VREF')
- hbox1.pack_start(label, False, False)
- hbox1.pack_start(combobox)
- vbox1.pack_start(hbox1, False, False)
- frame.add(vbox1)
- vbox.pack_start(frame, False, False)
-
- hbox.pack_start(vbox)
- return hbox
-
- def __build_mix(self, node):
- hbox = gtk.HBox(False, 0)
- return hbox
-
- def __sdi_select_changed(self, adj, node):
- val = int(adj.get_value())
- node.sdi_select_set_value(val)
- adj.set_value(node.sdi_select)
-
- def __dig1_toggled(self, button, data):
- node, name = data
- val = button.get_active()
- node.dig1_set_value(name, val)
- button.set_active(name in node.dig1)
-
- def __dig1_category_activate(self, entry, node):
- val = entry.get_text()
- if val.lower().startswith('0x'):
- val = int(val[2:], 16)
- else:
- try:
- val = int(val)
- except:
- print "Unknown category value '%s'" % val
- return
- node.dig1_set_value('category', val)
- entry.set_text("0x%02x" % node.dig1_category)
-
- def __build_aud(self, node):
- vbox = gtk.VBox(False, 0)
-
- frame = gtk.Frame('Converter')
- frame.set_border_width(4)
- str = 'Audio Stream:\t%s\n' % node.aud_stream
- str += 'Audio Channel:\t%s\n' % node.aud_channel
- if node.format_ovrd:
- str += 'Rates:\t\t%s\n' % node.pcm_rates[:6]
- if len(node.pcm_rates) > 6:
- str += '\t\t\t\t%s\n' % node.pcm_rates[6:]
- str += 'Bits:\t\t%s\n' % node.pcm_bits
- str += 'Streams:\t%s\n' % node.pcm_streams
- else:
- str += 'Global Rates:\t%s\n' % node.codec.pcm_rates[:6]
- if len(node.codec.pcm_rates) > 6:
- str += '\t\t%s\n' % node.codec.pcm_rates[6:]
- str += 'Global Bits:\t%s\n' % node.codec.pcm_bits
- str += 'Global Streams:\t%s\n' % node.codec.pcm_streams
- frame.add(self.__new_text_view(text=str))
- vbox.pack_start(frame)
-
- if not node.sdi_select is None:
- hbox1 = gtk.HBox(False, 0)
- frame = gtk.Frame('SDI Select')
- adj = gtk.Adjustment(node.sdi_select, 0.0, 16.0, 1.0, 1.0, 1.0)
- scale = gtk.HScale(adj)
- scale.set_digits(0)
- scale.set_value_pos(gtk.POS_LEFT)
- scale.set_size_request(200, 16)
- adj.connect("value_changed", self.__sdi_select_changed, node)
- frame.add(scale)
- hbox1.pack_start(frame, False, False)
- vbox.pack_start(hbox1, False, False)
-
- if node.digital:
- hbox1 = gtk.HBox(False, 0)
- frame = gtk.Frame('Digital Converter')
- vbox1 = gtk.VBox(False, 0)
- for name in DIG1_BITS:
- checkbutton = gtk.CheckButton(name)
- checkbutton.set_active(node.digi1 & (1 << DIG1_BITS[name]))
- checkbutton.connect("toggled", self.__dig1_toggled, (node, name))
- vbox1.pack_start(checkbutton, False, False)
- frame.add(vbox1)
- hbox1.pack_start(frame)
- frame = gtk.Frame('Digital Converter Category')
- entry = gtk.Entry()
- entry.set_text("0x%x" % node.dig1_category)
- entry.set_width_chars(4)
- entry.connect("activate", self.__dig1_category_activate, node)
- frame.add(entry)
- hbox1.pack_start(frame)
- vbox.pack_start(hbox1, False, False)
-
- return vbox
-
- def __build_device(self, device):
- vbox = gtk.VBox(False, 0)
- frame = gtk.Frame('Device')
- frame.set_border_width(4)
- hbox = gtk.HBox(False, 0)
- s = 'name=' + str(device.name) + ', type=' + \
- str(device.type) + ', device=' + str(device.device)
- label = gtk.Label(s)
- hbox.pack_start(label, False, False)
- frame.add(hbox)
- vbox.pack_start(frame)
- return vbox
-
- def __build_controls(self, ctrls):
- vbox = gtk.VBox(False, 0)
- frame = gtk.Frame('Controls')
- frame.set_border_width(4)
- vbox1 = gtk.VBox(False, 0)
- for ctrl in ctrls:
- hbox1 = gtk.HBox(False, 0)
- vbox1.pack_start(hbox1, False, False)
- s = 'name=' + str(ctrl.name) + ', index=' + str(ctrl.index) + \
- ', device=' + str(ctrl.device)
- label = gtk.Label(s)
- hbox1.pack_start(label, False, False)
- if ctrl.amp_chs:
- hbox1 = gtk.HBox(False, 0)
- vbox1.pack_start(hbox1, False, False)
- s = ' chs=' + str(ctrl.amp_chs) + ', dir=' + str(ctrl.amp_dir) + \
- ', idx=' + str(ctrl.amp_idx) + ', ofs=' + str(ctrl.amp_ofs)
- label = gtk.Label(s)
- hbox1.pack_start(label, False, False)
- frame.add(vbox1)
- vbox.pack_start(frame)
- return vbox
-
- def __build_proc(self, node):
- frame = gtk.Frame('Processing Caps')
- frame.set_border_width(4)
- str = 'benign=%i\nnumcoef=%i\n' % (node.proc_benign, node.proc_numcoef)
- frame.add(self.__new_text_view(text=str))
- return frame
-
- def __build_node(self, node):
- w = self.node_window
-
- mframe = gtk.Frame(node.name())
- mframe.set_border_width(4)
-
- vbox = gtk.VBox(False, 0)
- dev = node.get_device()
- if not dev is None:
- vbox.pack_start(self.__build_device(dev), False, False)
- ctrls = node.get_controls()
- if ctrls:
- vbox.pack_start(self.__build_controls(ctrls), False, False)
- hbox = gtk.HBox(False, 0)
- hbox.pack_start(self.__build_node_caps(node))
- hbox.pack_start(self.__build_connection_list(node))
- vbox.pack_start(hbox, False, False)
- if node.in_amp or node.out_amp:
- vbox.pack_start(self.__build_amps(node), False, False)
- if node.wtype_id == 'PIN':
- vbox.pack_start(self.__build_pin(node), False, False)
- elif node.wtype_id in ['AUD_IN', 'AUD_OUT']:
- vbox.pack_start(self.__build_aud(node), False, False)
- else:
- if not node.wtype_id in ['AUD_MIX', 'BEEP', 'AUD_SEL']:
- print 'Node type %s has no GUI support' % node.wtype_id
- if node.proc_wid:
- vbox.pack_start(self.__build_proc(node), False, False)
-
- mframe.add(vbox)
- w.add_with_viewport(mframe)
-
- def __build_codec_info(self, codec):
- vbox = gtk.VBox(False, 0)
-
- frame = gtk.Frame('Codec Identification')
- frame.set_border_width(4)
- str = 'Audio Fcn Group: %s\n' % (codec.afg and "0x%02x" % codec.afg or "N/A")
- str += 'Modem Fcn Group: %s\n' % (codec.mfg and "0x%02x" % codec.mfg or "N/A")
- str += 'Vendor ID:\t 0x%08x\n' % codec.vendor_id
- str += 'Subsystem ID:\t 0x%08x\n' % codec.subsystem_id
- str += 'Revision ID:\t 0x%08x\n' % codec.revision_id
- frame.add(self.__new_text_view(text=str))
- vbox.pack_start(frame, False, False)
-
- frame = gtk.Frame('PCM Global Capabilities')
- frame.set_border_width(4)
- str = 'Rates:\t\t %s\n' % codec.pcm_rates[:6]
- if len(codec.pcm_rates) > 6:
- str += '\t\t %s\n' % codec.pcm_rates[6:]
- str += 'Bits:\t\t %s\n' % codec.pcm_bits
- str += 'Streams:\t %s\n' % codec.pcm_streams
- frame.add(self.__new_text_view(text=str))
- vbox.pack_start(frame, False, False)
-
- return vbox
-
- def __build_codec_amps(self, codec):
-
- def build_caps(title, caps):
- frame = gtk.Frame(title)
- frame.set_border_width(4)
- if caps and caps.ofs != None:
- str = 'Offset:\t\t %d\n' % caps.ofs
- str += 'Number of steps: %d\n' % caps.nsteps
- str += 'Step size:\t %d\n' % caps.stepsize
- str += 'Mute:\t\t %s\n' % (caps.mute and "True" or "False")
- frame.add(self.__new_text_view(text=str))
- return frame
-
- hbox = gtk.HBox(False, 0)
- c = build_caps('Global Input Amplifier Caps', codec.amp_caps_in)
- hbox.pack_start(c)
- c = build_caps('Global Output Amplifier Caps', codec.amp_caps_out)
- hbox.pack_start(c)
-
- return hbox
-
- def __gpio_toggled(self, button, (codec, id, idx)):
- codec.gpio.set(id, idx, button.get_active())
- button.set_active(codec.gpio.test(id, idx))
-
- def __build_codec_gpio(self, codec):
- frame = gtk.Frame('GPIO')
- frame.set_border_width(4)
- hbox = gtk.HBox(False, 0)
- str = 'IO Count: %d\n' % codec.gpio_max
- str += 'O Count: %d\n' % codec.gpio_o
- str += 'I Count: %d\n' % codec.gpio_i
- str += 'Unsolicited: %s\n' % (codec.gpio_unsol and "True" or "False")
- str += 'Wake: %s\n' % (codec.gpio_wake and "True" or "False")
- hbox.pack_start(self.__new_text_view(text=str), False, False)
- frame.add(hbox)
- for id in GPIO_IDS:
- id1 = id == 'direction' and 'out-dir' or id
- frame1 = gtk.Frame(id1)
- frame1.set_border_width(4)
- vbox1 = gtk.VBox(False, 0)
- for i in range(codec.gpio_max):
- checkbutton = gtk.CheckButton('[%d]' % i)
- checkbutton.set_active(codec.gpio.test(id, i))
- checkbutton.connect("toggled", self.__gpio_toggled, (codec, id, i))
- vbox1.pack_start(checkbutton, False, False)
- frame1.add(vbox1)
- hbox.pack_start(frame1, False, False)
- return frame
-
- def __build_codec(self, codec):
- w = self.node_window
-
- mframe = gtk.Frame(codec.name)
- mframe.set_border_width(4)
-
- vbox = gtk.VBox(False, 0)
- vbox.pack_start(self.__build_codec_info(codec), False, False)
- vbox.pack_start(self.__build_codec_amps(codec), False, False)
- vbox.pack_start(self.__build_codec_gpio(codec), False, False)
- mframe.add(vbox)
- w.add_with_viewport(mframe)
-
- def __build_card_info(self, card):
- str = 'Card: %s\n' % card.card
- str += 'Id: %s\n' % card.id
- str += 'Driver: %s\n' % card.driver
- str += 'Name: %s\n' % card.name
- str += 'LongName: %s\n' % card.longname
- return self.__new_text_view(text=str)
-
- def __build_card(self, card):
- w = self.node_window
-
- mframe = gtk.Frame(card.name)
- mframe.set_border_width(4)
-
- vbox = gtk.VBox(False, 0)
- vbox.pack_start(self.__build_card_info(card), False, False)
- mframe.add(vbox)
- w.add_with_viewport(mframe)
-
def monitor():
from time import sleep
print "Watching %s cards" % len(CODEC_TREE)
if len(argv) > 1 and argv[1] in ('-m', '-monitor', '--monitor'):
cmd = 'monitor'
del argv[1]
+ if len(argv) > 1 and argv[1] in ('-g', '-graph', '--graph'):
+ cmd = 'graph'
+ del argv[1]
if read_nodes(sys.argv[1:]) == 0:
print "No HDA codecs were found or insufficient priviledges for "
print "/dev/snd/controlC* and /dev/snd/hwdepC*D* device files."
if cmd == 'monitor':
monitor()
return 1
+ if cmd == 'graph':
+ for card in CODEC_TREE:
+ for codec in CODEC_TREE:
+ create_graph(CODEC_TREE[card][codec])
HDAAnalyzer()
gtk.main()
return 1
return self.proc_codec.get_controls(nid)
return None
+ def connections(self, nid, dir=0):
+ if dir == 0:
+ if nid in self.nodes:
+ conn = self.nodes[nid].connections
+ if conn:
+ return len(conn)
+ return 0
+ res = 0
+ for nid in self.nodes:
+ node = self.nodes[nid]
+ if nid != nid and node.connections and nid in node.connections:
+ res += 1
+ return res
+
+ def graph(self, dump=False):
+
+ def mfind(nid):
+ for y in range(len(res)):
+ if nid in res[y]:
+ return (y, res[y].index(nid))
+ return None, None
+
+ def doplace(nid, y, x):
+ node = self.nodes[nid]
+ if node.wtype_id == 'AUD_MIX':
+ if y == 0:
+ y += 1
+ while 1:
+ x += 1
+ if x >= len(res[0]) - 1:
+ x = 1
+ y += 1
+ if y >= len(res) - 1:
+ raise ValueError, "cannot place nid to graph matrix"
+ if res[y][x+1] is None and \
+ res[y][x-1] is None and \
+ res[y+1][x] is None and \
+ res[y-1][x] is None and \
+ res[y][x] is None:
+ res[y][x] = nid
+ return True
+ if y == 0:
+ for idx in range(len(res)-2):
+ if res[idx+1][x] is None:
+ res[idx+1][x] = nid
+ return True
+ elif y == len(res)-1:
+ for idx in reversed(range(len(res)-2)):
+ if res[idx+1][x] is None:
+ res[idx+1][x] = nid
+ return True
+ elif x == 0:
+ for idx in range(len(res[0])-2):
+ if res[y][idx+1] is None:
+ res[y][idx+1] = nid
+ return True
+ elif x == len(res)-1:
+ for idx in range(len(res[0])-2):
+ if res[y][idx+1] is None:
+ res[y][idx+1] = nid
+ return True
+ else:
+ if y+1 < len(res) and res[y+1][x] is None:
+ res[y+1][x] = nid
+ return True
+ if y-1 != 0 and res[y-1][x] is None:
+ res[y-1][x] = nid
+ return True
+ if x+1 < len(res[0]) and res[y][x+1] is None:
+ res[y][x+1] = nid
+ return True
+ if x-1 != 0 and res[y][x-1] is None:
+ res[y][x-1] = nid
+ return True
+ if y+1 < len(res):
+ return doplace(nid, y+1, 1)
+ if x+1 < len(res[0]):
+ return doplace(nid, 1, x+1)
+ raise ValueError, "cannot place nid to graph matrix"
+ return False
+
+ res = []
+ unplaced = []
+ # determine all termination widgets
+ terms = {'AUD_IN':[], 'AUD_OUT':[], 'PIN_IN':[], 'PIN_OUT':[]}
+ for nid in self.nodes:
+ node = self.nodes[nid]
+ if node.wtype_id in ['AUD_IN', 'AUD_OUT', 'PIN']:
+ id = node.wtype_id
+ if id == 'PIN':
+ id = 'IN' in node.pinctl and 'PIN_IN' or 'PIN_OUT'
+ terms[id].append(nid)
+ else:
+ unplaced.append(nid)
+ for id in terms:
+ terms[id].sort()
+ # build the matrix
+ x = max(len(terms['AUD_IN']), len(terms['AUD_OUT'])) + 2
+ y = max(len(terms['PIN_IN']), len(terms['PIN_OUT'])) + 2
+ if x == 2 and y == 2:
+ return None
+ for a in range(y):
+ res.append([None]*x)
+ if 'PIN_IN' in terms:
+ for idx in range(len(terms['PIN_IN'])):
+ res[idx+1][0] = terms['PIN_IN'][idx]
+ if 'PIN_OUT' in terms:
+ for idx in range(len(terms['PIN_OUT'])):
+ res[idx+1][-1] = terms['PIN_OUT'][idx]
+ if 'AUD_IN' in terms:
+ idx = 1
+ for nid in terms['AUD_IN']:
+ res[0][idx] = nid
+ idx += 1
+ if 'AUD_OUT' in terms:
+ idx = 1
+ for nid in terms['AUD_OUT']:
+ res[-1][idx] = nid
+ idx += 1
+ # check and resize the matrix for unplaced nodes
+ while len(res)**len(res[0]) < len(unplaced):
+ res.insert(-2, [None]*x)
+ # assign unplaced nids - check connections
+ unplaced.sort()
+ while unplaced:
+ change = len(unplaced)
+ for idx in range(len(res)):
+ for idx1 in range(len(res[idx])):
+ nid = res[idx][idx1]
+ if nid is None:
+ continue
+ node = self.nodes[nid]
+ if not node or not node.connections:
+ continue
+ for conn in node.connections:
+ if conn in unplaced and doplace(conn, idx, idx1):
+ unplaced.remove(conn)
+ for nid in unplaced:
+ node = self.nodes[nid]
+ if not node.connections:
+ continue
+ for conn in node.connections:
+ placed = False
+ y, x = mfind(nid)
+ if doplace(nid, y, x):
+ unplaced.remove(nid)
+ break
+ if len(unplaced) == change:
+ break
+ y = len(res)
+ x = 0
+ for nid in unplaced:
+ if y >= len(res):
+ res.append([None]*len(res[0]))
+ res[y][x] = nid
+ x += 1
+ if x >= len(res[0]):
+ y += 1
+ x = 0
+ # do extra check
+ check = []
+ for y in range(len(res)):
+ for x in range(len(res[0])):
+ nid = res[y][x]
+ if not nid is None:
+ if nid in check:
+ raise ValueError, "double nid in graph matrix"
+ if not nid in self.nodes:
+ raise ValueError, "unknown nid in graph matrix"
+ check.append(nid)
+ if len(check) != len(self.nodes):
+ raise ValueError, "not all nids in graph matrix"
+ # do addition dump
+ if dump:
+ print "****", len(self.nodes)
+ for nodes in res:
+ str = ''
+ for node2 in nodes:
+ str += node2 is None and '-- ' or '%02x ' % node2
+ print str
+ print "****"
+ return res
+
def HDA_card_list():
from dircache import listdir
result = []
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2008-2010 by Jaroslav Kysela <perex@perex.cz>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+import gobject
+import gtk
+from gtk import gdk
+import pango
+import cairo
+from hda_guilib import *
+
+from hda_codec import EAPDBTL_BITS, PIN_WIDGET_CONTROL_BITS, \
+ PIN_WIDGET_CONTROL_VREF, DIG1_BITS, GPIO_IDS, \
+ HDA_INPUT, HDA_OUTPUT
+
+GRAPH_WINDOWS = {}
+
+class Node:
+
+ def __init__(self, codec, node, x, y, nodesize, extra):
+ self.codec = codec
+ self.node = node
+ self.extra = extra
+ sx = sy = nodesize
+ self.myarea = [extra+x*(sx+extra), extra+y*(sy+extra), sx, sy]
+ self.src_routes = []
+ self.dst_routes = []
+ self.win = None
+
+ def expose(self, cr, event, graph):
+
+ width = self.myarea[2]
+ height = self.myarea[3]
+
+ cr.select_font_face("Misc Fixed",
+ cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+ cr.set_font_size(14)
+ if graph.startnode == self:
+ cr.set_line_width(1.8)
+ cr.set_source_rgb(0, 0, 1)
+ elif graph.endnode == self:
+ cr.set_line_width(1.8)
+ cr.set_source_rgb(1, 0, 0)
+ else:
+ cr.set_line_width(0.8)
+ cr.set_source_rgb(0, 0, 0)
+ cr.rectangle(*self.myarea)
+ cr.stroke()
+
+ cr.set_line_width(0.4)
+ cr.move_to(self.myarea[0]+5, self.myarea[1]+13)
+ cr.text_path("0x%02x: %s" % (self.node.nid, self.node.wtype_id))
+ cr.stroke()
+
+ cr.set_line_width(0.2)
+ cr.rectangle(self.myarea[0], self.myarea[1] + (height/4)*3, width/2, height/4)
+ cr.rectangle(self.myarea[0]+width/2, self.myarea[1] + (height/4)*3, width/2, height/4)
+ cr.stroke()
+
+ cr.set_font_size(11)
+ cr.move_to(self.myarea[0]+20, self.myarea[1] + (height/4)*3+15)
+ cr.text_path('IN')
+ cr.stroke()
+ cr.move_to(self.myarea[0]+width/2+20, self.myarea[1] + (height/4)*3+15)
+ cr.text_path('OUT')
+ cr.stroke()
+
+ def has_x(self, x):
+ x1 = self.myarea[0]
+ x2 = x1 + self.myarea[2]
+ return x >= x1 and x <= x2
+
+ def compressx(self, first, size):
+ if self.myarea[0] > first:
+ self.myarea[0] -= size
+
+ def has_y(self, y):
+ y1 = self.myarea[1]
+ y2 = y1 + self.myarea[3]
+ return y >= y1 and y <= y2
+
+ def compressy(self, first, size):
+ if self.myarea[1] > first:
+ self.myarea[1] -= size
+
+ def in_area(self, x, y):
+ if x >= self.myarea[0] and \
+ y >= self.myarea[1] and \
+ x < self.myarea[0] + self.myarea[2] and \
+ y < self.myarea[1] + self.myarea[3]:
+ wherex = x - self.myarea[0]
+ wherey = y - self.myarea[1]
+ if wherey >= (self.myarea[3]/4) * 3:
+ if wherex >= self.myarea[2]/2:
+ return "dst"
+ else:
+ return "src"
+ else:
+ return "body"
+
+ def mouse_move(self, x, y, graph):
+ what = self.in_area(x, y)
+ if not what is None:
+ if what == "dst":
+ for r in self.dst_routes:
+ r.highlight = True
+ elif what == "src":
+ for r in self.src_routes:
+ r.highlight = True
+ else:
+ graph.popup = self.codec.dump_node(self.node)
+ return True
+
+class Route:
+
+ def __init__(self, codec, src_node, dst_node, routes, nodes):
+ self.codec = codec
+ self.src = src_node
+ self.dst = dst_node
+ self.lines = []
+ self.analyze_routes(routes, nodes)
+ src_node.dst_routes.append(self)
+ dst_node.src_routes.append(self)
+ self.highlight = False
+ self.marked = False
+
+ def shortdest(self):
+ return "0x%02x->0x%02x" % (self.src.node.nid, self.dst.node.nid)
+
+ def longdesc(self):
+ src = self.src.node
+ dst = self.dst.node
+ return "%s 0x%02x -> %s 0x%02x" % (src.wtype_id.replace('_', '-'),
+ src.nid, dst.wtype_id.replace('_', '-'), dst.nid)
+
+ def expose(self, cr, event):
+ width = self.src.myarea[2]
+ height = self.src.myarea[3]
+
+ if 0: # direct green lines
+ cr.set_line_width(0.3)
+ cr.set_source_rgb(0.2, 1.0, 0.2)
+ cr.move_to(self.src.myarea[0]+(width/4)*3, self.src.myarea[1]+height)
+ cr.line_to(self.dst.myarea[0]+width/4, self.dst.myarea[1]+height)
+ cr.stroke()
+
+ for line in self.lines:
+ if self.marked:
+ cr.set_line_width(1.8)
+ cr.set_source_rgb(1, 0, 1)
+ elif self.highlight:
+ cr.set_line_width(1.5)
+ cr.set_source_rgb(1, 0, 0)
+ else:
+ cr.set_line_width(0.5)
+ cr.set_source_rgb(0, 0, 0)
+ if len(line) > 4:
+ cr.set_source_rgb(0, 1, 0)
+ cr.move_to(line[0], line[1])
+ cr.line_to(line[2], line[3])
+ cr.stroke()
+
+ def select_line(self, routes, nodes, possible):
+
+ def check_dot(posx, posy, line):
+ if posx == line[0] and posx == line[2]:
+ if line[1] < line[3]:
+ if posy >= line[1] and posy <= line[3]:
+ #print "Clash1", posx, posy, line
+ return True
+ else:
+ if posy >= line[3] and posy <= line[1]:
+ #print "Clash2", posx, posy, line
+ return True
+ if posy == line[1] and posy == line[3]:
+ if line[0] < line[2]:
+ if posx >= line[0] and posx <= line[2]:
+ #print "Clash3", posx, posy, line
+ return True
+ else:
+ if posx >= line[2] and posx <= line[0]:
+ #print "Clash4", posx, posy, line
+ return True
+ if posx == line[0] and posy == line[1]:
+ #print "Clash5", posx, posy, line
+ return True
+ if posx == line[2] and posy == line[3]:
+ #print "Clash6", posx, posy, line
+ return True
+ return False
+
+ for p in possible:
+ found = False
+ for route in routes:
+ if found:
+ break
+ for line in route.lines:
+ if check_dot(line[0], line[1], p) or \
+ check_dot(line[2], line[3], p) or \
+ check_dot(p[0], p[1], line) or \
+ check_dot(p[2], p[3], line):
+ #print "Found1", p
+ found = True
+ break
+ if nodes and not found:
+ x1, y1, x2, y2 = p
+ if x1 > x2 or y1 > y2:
+ x2, y2, x1, y1 = p
+ for node in nodes:
+ xx1, yy1, xx2, yy2 = node.myarea
+ xx2 += xx1
+ yy2 += yy1
+ if x1 < xx2 and x2 >= xx1 and y1 < yy2 and y2 >= yy1:
+ #print "Found2", x1, y1, x2, y2, xx1, yy1, xx2, yy2
+ found = True
+ break
+ if not found:
+ #print "OK x1=%s,y1=%s,x2=%s,y2=%s" % (p[0], p[1], p[2], p[3])
+ return p
+
+ def analyze_routes(self, routes, nodes):
+ posx, posy, width, height = self.src.myarea
+ dposx, dposy, dwidth, dheight = self.dst.myarea
+ extra = self.src.extra
+
+ possible = []
+ startx = posx >= dposx and posx - extra or posx + width
+ xrange = range(5, extra-1, 5)
+ if posx >= dposx:
+ xrange.reverse()
+ a = range(width+extra+5, width+extra*2-1, 5)
+ a.reverse()
+ xrange = xrange + a
+ for i in range(2, 10):
+ a = range(width*i+extra*i+5, width*i+extra*(i+1)-1, 5)
+ a.reverse()
+ xrange = xrange + a
+ else:
+ xrange += range(width+extra+5, width+extra*2-1, 5)
+ for i in range(2, 10):
+ xrange += range(width*i+extra*i+5, width*i+extra*(i+1)-1, 5)
+ for j in xrange:
+ possible.append([startx + j, posy + height + 5,
+ startx + j, dposy + height + 5])
+ sel = self.select_line(routes, None, possible)
+ if not sel:
+ raise ValueError, "unable to route"
+
+ self.lines.append(sel)
+
+ def finish(self, routes, nodes):
+
+ if not self.lines:
+ return
+
+ posx, posy, width, height = self.src.myarea
+ dposx, dposy, dwidth, dheight = self.dst.myarea
+ extra = self.src.extra
+ sel = self.lines[0]
+ res = True
+
+ x = posx+(width/2)
+ y = posy+height
+ for tryit in range(3):
+ possible = []
+ fixup = sel[0] > posx and -1 or 1
+ r = range(tryit*extra, (tryit+1)*extra-5-1, 5)
+ if tryit == 2:
+ r = range(-height-extra+5, -height-5, 5)
+ r.reverse()
+ for i in range(tryit*extra, (tryit+1)*extra-5-1, 5):
+ possible.append([x+5+fixup, sel[1]+i, sel[0]-fixup, sel[1]+i])
+ sel1 = self.select_line(routes, nodes, possible)
+ if sel1:
+ sel1[0] -= fixup
+ sel1[2] += fixup
+ possible = []
+ for j in range(0, width/2-10, 5):
+ possible.append([sel1[0]+j, y, sel1[0]+j, sel1[1]])
+ sel2 = self.select_line(routes, nodes, possible)
+ if sel2:
+ sel1[0] = sel2[0]
+ self.lines[0][1] = sel1[1]
+ self.lines.append(sel1)
+ self.lines.append(sel2)
+ tryit = -1
+ break
+ if tryit >= 0:
+ self.lines.append([x+5, y, sel[0], sel[1], 1])
+ print "[1] displaced route 0x%x->0x%x %s %s" % (self.src.node.nid, self.dst.node.nid, repr(self.lines[-1]), repr(sel))
+ res = False
+
+ x = dposx
+ y = dposy+height
+ for tryit in range(3):
+ possible = []
+ fixup = sel[2] > posx and -1 or 1
+ r = range(tryit * extra, (tryit+1)*extra-5-1, 5)
+ if tryit == 2:
+ r = range(-height-extra+5, -height-5, 5)
+ r.reverse()
+ for i in r:
+ possible.append([x+(width/2-1)+fixup, sel[3]+i, sel[2]-fixup, sel[3]+i])
+ sel1 = self.select_line(routes, nodes, possible)
+ if sel1:
+ sel1[0] -= fixup + (width/2-1) - 5
+ sel1[2] += fixup
+ possible = []
+ for j in range(0, width/2-10, 5):
+ possible.append([sel1[0]+j, y, sel1[0]+j, sel1[1]])
+ sel2 = self.select_line(routes, nodes, possible)
+ if sel2:
+ sel1[0] = sel2[0]
+ self.lines[0][3] = sel1[3]
+ self.lines.append(sel1)
+ self.lines.append(sel2)
+ tryit = -1
+ break
+ if tryit >= 0:
+ self.lines.append([x+5, y, sel[2], sel[3], 1])
+ print "[2] displaced route 0x%x->0x%x %s %s" % (self.src.node.nid, self.dst.node.nid, repr(self.lines[-1]), repr(sel))
+ res = False
+
+ return res
+
+ def has_x(self, x):
+ for line in self.lines:
+ if line[0] == x or line[2] == x:
+ return True
+ return False
+
+ def compressx(self, first, size):
+ idx = 0
+ while idx < len(self.lines):
+ line = self.lines[idx]
+ if line[0] > first:
+ line[0] -= size
+ self.lines[idx] = line
+ if line[2] > first:
+ line[2] -= size
+ self.lines[idx] = line
+ idx += 1
+
+ def has_y(self, y):
+ for line in self.lines:
+ if line[1] == y or line[3] == y:
+ return True
+ return False
+
+ def compressy(self, first, size):
+ idx = 0
+ while idx < len(self.lines):
+ line = self.lines[idx]
+ if line[1] > first:
+ line[1] -= size
+ self.lines[idx] = line
+ if line[3] > first:
+ line[3] -= size
+ self.lines[idx] = line
+ idx += 1
+
+ def in_area(self, x, y):
+ for line in self.lines:
+ x1, y1, x2, y2 = line
+ if x1 > x2 or y1 > y2:
+ x2, y2, x1, y1 = line
+ if x1 == x2 and abs(x1 - x) < 2:
+ if y1 <= y and y2 >= y:
+ return True
+ elif y1 == y2 and abs(y1 - y) < 2:
+ if x1 <= x and x2 >= x:
+ return True
+
+ def mouse_move(self, x, y, graph):
+ if self.in_area(x, y):
+ self.highlight = True
+ return True
+
+class CodecGraphLayout(gtk.Layout):
+
+ def __init__(self, adj1, adj2, codec, mytitle):
+ gtk.Layout.__init__(self, adj1, adj2)
+ self.set_events(0)
+ self.add_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.POINTER_MOTION_MASK |
+ gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
+ self.expose_handler = self.connect("expose-event", self.expose)
+ self.click_handler = self.connect("button-press-event", self.button_click)
+ self.release_handler = self.connect("button-release-event", self.button_release)
+ self.motion_handler = self.connect("motion-notify-event", self.mouse_move)
+
+ self.popup_win = None
+ self.popup = None
+
+ self.codec = codec
+ self.mytitle = mytitle
+ self.graph = codec.graph(dump=False)
+ self.startnode = None
+ self.endnode = None
+ ok = False
+ for extra in [150, 200, 300]:
+ if self.build(extra):
+ ok = True
+ break
+ break
+ if not ok:
+ print "Not all routes are placed correctly!!!"
+
+ def __destroy(self, widget):
+ if self.popup_win:
+ self.popup_win.destroy()
+
+ def build(self, extra=50):
+ self.nodes = []
+ self.routes = []
+ maxconns = 0
+ for nid in self.codec.nodes:
+ node = self.codec.nodes[nid]
+ conns = max(self.codec.connections(nid, 0),
+ self.codec.connections(nid, 1))
+ if conns > maxconns:
+ maxconns = conns
+ nodesize = max((maxconns * 5 + 10) * 2, 100)
+ if self.graph:
+ for y in range(len(self.graph)):
+ for x in range(len(self.graph[0])):
+ nid = self.graph[y][x]
+ if not nid is None:
+ node = self.codec.nodes[nid]
+ w = Node(self.codec, node, x, y, nodesize, extra)
+ self.nodes.append(w)
+ sx = len(self.graph[0])*(nodesize+extra)+extra
+ sy = len(self.graph)*(nodesize+extra)+extra
+ self.set_size(sx, sy)
+ for node in self.nodes:
+ if not node.node.connections:
+ continue
+ for conn in node.node.connections:
+ for node1 in self.nodes:
+ if node1.node.nid == conn:
+ r = Route(self.codec, node1, node, self.routes, self.nodes)
+ self.routes.append(r)
+ break
+ res = True
+ for route in self.routes:
+ if not route.finish(self.routes, self.nodes):
+ res = False
+ break
+ # final step - optimize drawings
+ while 1:
+ size = self.compressx(sx)
+ if not size:
+ break
+ sx -= size
+ while 1:
+ size = self.compressy(sy)
+ if not size:
+ break
+ sy -= size
+ self.set_size(sx, sy)
+ return res
+
+ def expose(self, widget, event):
+ if not self.flags() & gtk.REALIZED:
+ return
+
+ # background
+ cr = self.bin_window.cairo_create()
+ cr.set_source_rgb(1.0, 1.0, 1.0)
+ cr.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+ cr.clip()
+ cr.paint()
+
+ # draw nodes
+ for node in self.nodes:
+ node.expose(cr, event, self)
+
+ # draw routes
+ for route in self.routes:
+ route.expose(cr, event)
+
+ def compressx(self, sx):
+ first = None
+ for a in range(15, sx, 5):
+ found = False
+ for node in self.nodes:
+ if node.has_x(a):
+ found = True
+ break
+ if not found:
+ for route in self.routes:
+ if route.has_x(a):
+ found = True
+ break
+ if not found:
+ if first is None:
+ first = a
+ last = a
+ elif first is not None:
+ size = (last - first) + 5
+ for node in self.nodes:
+ node.compressx(first, size)
+ for route in self.routes:
+ route.compressx(first, size)
+ return size
+ return None
+
+ def compressy(self, sy):
+ first = None
+ for a in range(15, sy, 5):
+ found = False
+ for node in self.nodes:
+ if node.has_y(a):
+ found = True
+ break
+ if not found:
+ for route in self.routes:
+ if route.has_y(a):
+ found = True
+ break
+ if not found:
+ if first is None:
+ first = a
+ last = a
+ elif first is not None:
+ size = (last - first) + 5
+ for node in self.nodes:
+ node.compressy(first, size)
+ for route in self.routes:
+ route.compressy(first, size)
+ return size
+ return None
+
+ def find_node(self, event):
+ for node in self.nodes:
+ what = node.in_area(event.x, event.y)
+ if not what is None:
+ return (node, what)
+ return (None, None)
+
+ def find_route(self, event):
+ for route in self.routes:
+ if route.in_area(event.x, event.y):
+ return route
+
+ def show_popup(self, event):
+ screen_width = gtk.gdk.screen_width()
+ screeen_height = gtk.gdk.screen_height()
+
+ if self.popup_win:
+ self.popup_win.destroy()
+ self.popup_win = gtk.Window(gtk.WINDOW_POPUP)
+ label = gtk.Label()
+ label.modify_font(get_fixed_font())
+ label.set_text(self.popup)
+ self.popup_win.add(label)
+ popup_width, popup_height = self.popup_win.get_size()
+
+ rootwin = self.get_screen().get_root_window()
+ x, y, mods = rootwin.get_pointer()
+
+ pos_x = x - popup_width/2
+ if pos_x < 0:
+ pos_x = 0
+ elif pos_x + popup_width > screen_width:
+ pos_x = screen_width - popup_width
+
+ pos_y = y + 3
+ if pos_y + popup_height > screeen_height:
+ pos_y = event.y - 3 - popup_height
+
+ self.popup_win.move(int(pos_x), int(pos_y))
+ self.popup_win.show_all()
+
+ def mouse_move(self, widget, event):
+ oldpopup = self.popup
+ self.popup = None
+ for route in self.routes:
+ route.highlight = False
+ found = False
+ for node in self.nodes:
+ if node.mouse_move(event.x, event.y, self):
+ self.queue_draw()
+ found = True
+ break
+ if not found:
+ for route in self.routes:
+ if route.mouse_move(event.x, event.y, self):
+ self.queue_draw()
+ found = True
+ break
+ if self.popup:
+ if oldpopup != self.popup:
+ self.show_popup(event)
+ else:
+ if self.popup_win:
+ self.popup_win.destroy()
+
+ def mark_it(self, widget, node, what, enable):
+ if what == "start":
+ if enable:
+ if not self.startnode:
+ self.startnode = node
+ self.queue_draw()
+ else:
+ if self.startnode:
+ self.startnode = None
+ self.queue_draw()
+ elif what == "end":
+ if enable:
+ if not self.endnode:
+ self.endnode = node
+ self.queue_draw()
+ else:
+ if self.endnode:
+ self.endnode = None
+ self.queue_draw()
+
+ def mark_route(self, widget, route, what, enable):
+ if what == "mark":
+ if enable:
+ if not route.marked:
+ route.marked = enable
+ self.queue_draw()
+ else:
+ if route.marked:
+ route.marked = False
+ self.queue_draw()
+
+ def node_win_destroy(self, widget, node):
+ node.win = None
+
+ def open_node(self, widget, node):
+ if self.popup_win:
+ self.popup_win.destroy()
+ if not node.win:
+ win = gtk.Window()
+ win.set_default_size(500, 600)
+ gui = NodeGui(node=node.node)
+ win.set_title(self.mytitle + ' ' + gui.mytitle)
+ win.add(gui)
+ win.connect("destroy", self.node_win_destroy, node)
+ win.show_all()
+ node.win = win
+ else:
+ node.win.present()
+
+ def button_click(self, widget, event):
+ if event.button != 3:
+ return False
+ node, what = self.find_node(event)
+ m = None
+ if node:
+ m = gtk.Menu()
+ i = gtk.MenuItem("Open")
+ i.connect("activate", self.open_node, node)
+ i.show()
+ m.append(i)
+ if what in ["src", "dst"]:
+ routes1 = node.src_routes
+ text = "Mark Route From"
+ if what == "dst":
+ routes1 = node.dst_routes
+ text = "Mark Route To"
+ routes = []
+ for route in routes1:
+ if not route.marked:
+ routes.append(route)
+ if routes:
+ i = None
+ if len(routes) == 1:
+ i = gtk.MenuItem(text + ' ' + routes[0].longdesc())
+ i.connect("activate", self.mark_route, routes[0], "mark", True)
+ else:
+ menu = gtk.Menu()
+ for route in routes:
+ i = gtk.MenuItem(route.longdesc())
+ i.connect("activate", self.mark_route, route, "mark", True)
+ i.show()
+ menu.append(i)
+ i = gtk.MenuItem(text)
+ i.set_submenu(menu)
+ if i:
+ i.show()
+ m.append(i)
+ if what in ["src", "dst"]:
+ routes1 = node.src_routes
+ text = "Unmark Route From"
+ if what == "dst":
+ routes1 = node.dst_routes
+ text = "Unmark Route To"
+ routes = []
+ for route in routes1:
+ if route.marked:
+ routes.append(route)
+ if routes:
+ i = None
+ if len(routes) == 1:
+ i = gtk.MenuItem(text + ' ' + routes[0].longdesc())
+ i.connect("activate", self.mark_route, routes[0], "mark", False)
+ else:
+ menu = gtk.Menu()
+ for route in routes:
+ i = gtk.MenuItem(route.longdesc())
+ i.connect("activate", self.mark_route, route, "mark", False)
+ i.show()
+ menu.append(i)
+ i = gtk.MenuItem(text)
+ i.set_submenu(menu)
+ if i:
+ i.show()
+ m.append(i)
+ if not self.startnode:
+ i = gtk.MenuItem("Mark as start point")
+ i.connect("activate", self.mark_it, node, "start", True)
+ else:
+ i = gtk.MenuItem("Clear start point")
+ i.connect("activate", self.mark_it, None, "start", False)
+ i.show()
+ m.append(i)
+ if not self.endnode:
+ i = gtk.MenuItem("Mark as finish point")
+ i.connect("activate", self.mark_it, node, "end", True)
+ else:
+ i = gtk.MenuItem("Clear finish point")
+ i.connect("activate", self.mark_it, None, "end", False)
+ i.show()
+ m.append(i)
+ else:
+ route = self.find_route(event)
+ if route:
+ m = gtk.Menu()
+ if not route.marked:
+ i = gtk.MenuItem("Mark selected route %s" % route.shortdesc())
+ i.connect("activate", self.mark_route, route, "mark", True)
+ else:
+ i = gtk.MenuItem("Clear selected route %s" % route.shortdesc())
+ i.connect("activate", self.mark_route, route, "mark", False)
+ i.show()
+ m.append(i)
+ if m:
+ m.popup(None, None, None, event.button, event.time, None)
+ return False
+
+ def button_release(self, widget, event):
+
+ pass
+
+gobject.type_register(CodecGraphLayout)
+
+class CodecGraph(gtk.Window):
+
+ def __init__(self, codec):
+ gtk.Window.__init__(self)
+ self.codec = codec
+ self.connect('destroy', self.__destroy)
+ self.set_default_size(800, 600)
+ self.set_title(self.__class__.__name__ + ' ' + self.codec.name)
+ self.set_border_width(0)
+
+ table = gtk.Table(2, 2, False)
+ self.add(table)
+
+ self.layout = CodecGraphLayout(None, None, codec, self.get_title())
+ table.attach(self.layout, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND,
+ gtk.FILL|gtk.EXPAND, 0, 0)
+ vScrollbar = gtk.VScrollbar(None)
+ table.attach(vScrollbar, 1, 2, 0, 1, gtk.FILL|gtk.SHRINK,
+ gtk.FILL|gtk.SHRINK, 0, 0)
+ hScrollbar = gtk.HScrollbar(None)
+ table.attach(hScrollbar, 0, 1, 1, 2, gtk.FILL|gtk.SHRINK,
+ gtk.FILL|gtk.SHRINK, 0, 0)
+ vAdjust = self.layout.get_vadjustment()
+ vScrollbar.set_adjustment(vAdjust)
+ hAdjust = self.layout.get_hadjustment()
+ hScrollbar.set_adjustment(hAdjust)
+ self.show_all()
+ GRAPH_WINDOWS[codec] = self
+
+ def __destroy(self, widget):
+ del GRAPH_WINDOWS[self.codec]
+
+def create_graph(codec):
+ if codec in GRAPH_WINDOWS:
+ GRAPH_WINDOWS[codec].present()
+ else:
+ CodecGraph(codec)
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2008-2010 by Jaroslav Kysela <perex@perex.cz>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+import gobject
+import gtk
+import pango
+
+from hda_codec import HDACodec, HDA_card_list, \
+ EAPDBTL_BITS, PIN_WIDGET_CONTROL_BITS, \
+ PIN_WIDGET_CONTROL_VREF, DIG1_BITS, GPIO_IDS, \
+ HDA_INPUT, HDA_OUTPUT
+
+def get_fixed_font():
+ return pango.FontDescription("Misc Fixed,Courier Bold 9")
+
+class NodeGui(gtk.ScrolledWindow):
+
+ def __init__(self, card=None, codec=None, node=None, doframe=False):
+ gtk.ScrolledWindow.__init__(self)
+ self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.set_shadow_type(gtk.SHADOW_IN)
+ if card and not codec and not node:
+ self.__build_card(card, doframe)
+ elif codec and not card and not node:
+ self.__build_codec(codec, doframe)
+ elif node and not card and not codec:
+ self.__build_node(node, doframe)
+ self.show_all()
+
+ def __create_text(self, callback):
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scrolled_window.set_shadow_type(gtk.SHADOW_IN)
+
+ text_view = gtk.TextView()
+ fontName = get_fixed_font()
+ text_view.modify_font(fontName)
+ scrolled_window.add(text_view)
+
+ buffer = gtk.TextBuffer(None)
+ text_view.set_buffer(buffer)
+ text_view.set_editable(False)
+ text_view.set_cursor_visible(False)
+ text_view.connect("visibility-notify-event", callback)
+
+ text_view.set_wrap_mode(True)
+
+ return scrolled_window, buffer
+
+ def __new_text_view(self, text=None):
+ text_view = gtk.TextView()
+ text_view.set_border_width(4)
+ fontName = get_fixed_font()
+ text_view.modify_font(fontName)
+ if not text is None:
+ buffer = gtk.TextBuffer(None)
+ iter = buffer.get_iter_at_offset(0)
+ if text[-1] == '\n':
+ text = text[:-1]
+ buffer.insert(iter, text)
+ text_view.set_buffer(buffer)
+ text_view.set_editable(False)
+ text_view.set_cursor_visible(False)
+ return text_view
+
+ def __build_node_caps(self, node):
+ frame = gtk.Frame('Node Caps')
+ frame.set_border_width(4)
+ if len(node.wcaps_list) == 0:
+ return frame
+ str = ''
+ for i in node.wcaps_list:
+ str += node.wcap_name(i) + '\n'
+ frame.add(self.__new_text_view(text=str))
+ return frame
+
+ def __node_connection_toggled(self, widget, row, data):
+ model, node = data
+ if not model[row][0]:
+ node.set_active_connection(int(row))
+ for r in model:
+ r[0] = False
+ idx = 0
+ for r in model:
+ r[0] = node.active_connection == idx
+ idx += 1
+
+ def __build_connection_list(self, node):
+ frame = gtk.Frame('Connection List')
+ frame.set_border_width(4)
+ sw = gtk.ScrolledWindow()
+ #sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ frame.add(sw)
+ if node.conn_list and node.connections:
+ model = gtk.ListStore(
+ gobject.TYPE_BOOLEAN,
+ gobject.TYPE_STRING
+ )
+ idx = 0
+ for i in node.connections:
+ iter = model.append()
+ node1 = node.codec.get_node(node.connections[idx])
+ model.set(iter, 0, node.active_connection == idx,
+ 1, node1.name())
+ idx += 1
+ treeview = gtk.TreeView(model)
+ treeview.set_rules_hint(True)
+ treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
+ treeview.set_size_request(300, 30 + len(node.connections) * 25)
+ renderer = gtk.CellRendererToggle()
+ renderer.set_radio(True)
+ if node.active_connection != None:
+ renderer.connect("toggled", self.__node_connection_toggled, (model, node))
+ column = gtk.TreeViewColumn("Active", renderer, active=0)
+ treeview.append_column(column)
+ renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn("Destination Node", renderer, text=1, editable=False)
+ treeview.append_column(column)
+ sw.add(treeview)
+ return frame
+
+ def __amp_mute_toggled(self, button, data):
+ caps, vals, idx = data
+ val = button.get_active()
+ vals.set_mute(idx, val)
+ button.set_active(vals.vals[idx] & 0x80)
+
+ def __amp_value_changed(self, adj, data):
+ caps, vals, idx = data
+ val = int(adj.get_value())
+ vals.set_value(idx, val)
+ adj.set_value(vals.vals[idx] & 0x7f)
+
+ def __build_amps(self, node):
+
+ def build_caps(title, caps, vals):
+ if caps and caps.ofs is None:
+ caps = caps.dir == HDA_INPUT and \
+ node.codec.amp_caps_in or node.codec.amp_caps_out
+ title += ' (Global)'
+ frame = gtk.Frame(title)
+ frame.set_border_width(4)
+ vbox = gtk.VBox(False, 0)
+ if caps:
+ str = 'Offset: %d\n' % caps.ofs
+ str += 'Number of steps: %d\n' % caps.nsteps
+ str += 'Step size: %d\n' % caps.stepsize
+ str += 'Mute: %s\n' % (caps.mute and "True" or "False")
+ vbox.pack_start(self.__new_text_view(text=str), True, True, 0)
+ idx = 0
+ frame1 = None
+ vbox1 = None
+ for val in vals.vals:
+ if vals.stereo and idx & 1 == 0:
+ frame1 = gtk.Frame()
+ vbox.pack_start(frame1, False, False)
+ vbox1 = gtk.VBox(False, 0)
+ frame1.add(vbox1)
+ hbox = gtk.HBox(False, 0)
+ label = gtk.Label('Val[%d]' % idx)
+ hbox.pack_start(label, False, False)
+ if caps.mute:
+ checkbutton = gtk.CheckButton('Mute')
+ checkbutton.set_active(val & 0x80 and True or False)
+ checkbutton.connect("toggled", self.__amp_mute_toggled, (caps, vals, idx))
+ hbox.pack_start(checkbutton, False, False)
+ if caps.stepsize > 0:
+ adj = gtk.Adjustment((val & 0x7f) % (caps.nsteps+1), 0.0, caps.nsteps+1, 1.0, 1.0, 1.0)
+ scale = gtk.HScale(adj)
+ scale.set_digits(0)
+ scale.set_value_pos(gtk.POS_RIGHT)
+ adj.connect("value_changed", self.__amp_value_changed, (caps, vals, idx))
+ hbox.pack_start(scale, True, True)
+ if vbox1:
+ vbox1.pack_start(hbox, False, False)
+ else:
+ vbox.pack_start(hbox, False, False)
+ idx += 1
+ frame.add(vbox)
+ return frame
+
+ hbox = gtk.HBox(False, 0)
+ c = build_caps('Input Amplifier',
+ node.in_amp and node.amp_caps_in or None,
+ node.in_amp and node.amp_vals_in or None)
+ hbox.pack_start(c)
+ c = build_caps('Output Amplifier',
+ node.out_amp and node.amp_caps_out or None,
+ node.out_amp and node.amp_vals_out or None)
+ hbox.pack_start(c)
+
+ return hbox
+
+ def __pincap_eapdbtl_toggled(self, button, data):
+ node, name = data
+ node.eapdbtl_set_value(name, button.get_active())
+ button.set_active(name in node.pincap_eapdbtl)
+
+ def __pinctls_toggled(self, button, data):
+ node, name = data
+ node.pin_widget_control_set_value(name, button.get_active())
+ button.set_active(name in node.pinctl)
+
+ def __pinctls_vref_change(self, combobox, node):
+ index = combobox.get_active()
+ idx1 = 0
+ for name in PIN_WIDGET_CONTROL_VREF:
+ if not name: continue
+ if idx1 == index:
+ node.pin_widget_control_set_value('vref', name)
+ break
+ idx1 += 1
+ idx = idx1 = 0
+ for name in PIN_WIDGET_CONTROL_VREF:
+ if name == node.pinctl_vref:
+ combobox.set_active(idx1)
+ break
+ if name != None:
+ idx1 += 1
+
+ def __build_pin(self, node):
+ hbox = gtk.HBox(False, 0)
+
+ if node.pincap or node.pincap_vref or node.pincap_eapdbtl:
+ vbox = gtk.VBox(False, 0)
+ if node.pincap or node.pincap_vref:
+ frame = gtk.Frame('PIN Caps')
+ frame.set_border_width(4)
+ str = ''
+ for i in node.pincap:
+ str += node.pincap_name(i) + '\n'
+ for i in node.pincap_vref:
+ str += 'VREF_%s\n' % i
+ frame.add(self.__new_text_view(text=str))
+ vbox.pack_start(frame)
+ if 'EAPD' in node.pincap:
+ frame = gtk.Frame('EAPD')
+ frame.set_border_width(4)
+ vbox1 = gtk.VBox(False, 0)
+ for name in EAPDBTL_BITS:
+ checkbutton = gtk.CheckButton(name)
+ checkbutton.set_active(node.pincap_eapdbtls & (1 << EAPDBTL_BITS[name]))
+ checkbutton.connect("toggled", self.__pincap_eapdbtl_toggled, (node, name))
+ vbox1.pack_start(checkbutton, False, False)
+ frame.add(vbox1)
+ vbox.pack_start(frame, False, False)
+ hbox.pack_start(vbox)
+
+ vbox = gtk.VBox(False, 0)
+
+ frame = gtk.Frame('Config Default')
+ frame.set_border_width(4)
+ str = 'Jack connection: %s\n' % node.jack_conn_name
+ str += 'Jack type: %s\n' % node.jack_type_name
+ str += 'Jack location: %s\n' % node.jack_location_name
+ str += 'Jack location2: %s\n' % node.jack_location2_name
+ str += 'Jack connector: %s\n' % node.jack_connector_name
+ str += 'Jack color: %s\n' % node.jack_color_name
+ if 'NO_PRESENCE' in node.defcfg_misc:
+ str += 'No presence\n'
+ frame.add(self.__new_text_view(text=str))
+ vbox.pack_start(frame)
+
+ frame = gtk.Frame('Widget Control')
+ frame.set_border_width(4)
+ vbox1 = gtk.VBox(False, 0)
+ for name in PIN_WIDGET_CONTROL_BITS:
+ checkbutton = gtk.CheckButton(name)
+ checkbutton.set_active(node.pinctls & (1 << PIN_WIDGET_CONTROL_BITS[name]))
+ checkbutton.connect("toggled", self.__pinctls_toggled, (node, name))
+ vbox1.pack_start(checkbutton, False, False)
+ if node.pincap_vref:
+ combobox = gtk.combo_box_new_text()
+ idx = idx1 = active = 0
+ for name in PIN_WIDGET_CONTROL_VREF:
+ if name == node.pinctl_vref: active = idx1
+ if name:
+ combobox.append_text(name)
+ idx1 += 1
+ idx += 1
+ combobox.set_active(active)
+ combobox.connect("changed", self.__pinctls_vref_change, node)
+ hbox1 = gtk.HBox(False, 0)
+ label = gtk.Label('VREF')
+ hbox1.pack_start(label, False, False)
+ hbox1.pack_start(combobox)
+ vbox1.pack_start(hbox1, False, False)
+ frame.add(vbox1)
+ vbox.pack_start(frame, False, False)
+
+ hbox.pack_start(vbox)
+ return hbox
+
+ def __build_mix(self, node):
+ hbox = gtk.HBox(False, 0)
+ return hbox
+
+ def __sdi_select_changed(self, adj, node):
+ val = int(adj.get_value())
+ node.sdi_select_set_value(val)
+ adj.set_value(node.sdi_select)
+
+ def __dig1_toggled(self, button, data):
+ node, name = data
+ val = button.get_active()
+ node.dig1_set_value(name, val)
+ button.set_active(name in node.dig1)
+
+ def __dig1_category_activate(self, entry, node):
+ val = entry.get_text()
+ if val.lower().startswith('0x'):
+ val = int(val[2:], 16)
+ else:
+ try:
+ val = int(val)
+ except:
+ print "Unknown category value '%s'" % val
+ return
+ node.dig1_set_value('category', val)
+ entry.set_text("0x%02x" % node.dig1_category)
+
+ def __build_aud(self, node):
+ vbox = gtk.VBox(False, 0)
+
+ frame = gtk.Frame('Converter')
+ frame.set_border_width(4)
+ str = 'Audio Stream:\t%s\n' % node.aud_stream
+ str += 'Audio Channel:\t%s\n' % node.aud_channel
+ if node.format_ovrd:
+ str += 'Rates:\t\t%s\n' % node.pcm_rates[:6]
+ if len(node.pcm_rates) > 6:
+ str += '\t\t\t\t%s\n' % node.pcm_rates[6:]
+ str += 'Bits:\t\t%s\n' % node.pcm_bits
+ str += 'Streams:\t%s\n' % node.pcm_streams
+ else:
+ str += 'Global Rates:\t%s\n' % node.codec.pcm_rates[:6]
+ if len(node.codec.pcm_rates) > 6:
+ str += '\t\t%s\n' % node.codec.pcm_rates[6:]
+ str += 'Global Bits:\t%s\n' % node.codec.pcm_bits
+ str += 'Global Streams:\t%s\n' % node.codec.pcm_streams
+ frame.add(self.__new_text_view(text=str))
+ vbox.pack_start(frame)
+
+ if not node.sdi_select is None:
+ hbox1 = gtk.HBox(False, 0)
+ frame = gtk.Frame('SDI Select')
+ adj = gtk.Adjustment(node.sdi_select, 0.0, 16.0, 1.0, 1.0, 1.0)
+ scale = gtk.HScale(adj)
+ scale.set_digits(0)
+ scale.set_value_pos(gtk.POS_LEFT)
+ scale.set_size_request(200, 16)
+ adj.connect("value_changed", self.__sdi_select_changed, node)
+ frame.add(scale)
+ hbox1.pack_start(frame, False, False)
+ vbox.pack_start(hbox1, False, False)
+
+ if node.digital:
+ hbox1 = gtk.HBox(False, 0)
+ frame = gtk.Frame('Digital Converter')
+ vbox1 = gtk.VBox(False, 0)
+ for name in DIG1_BITS:
+ checkbutton = gtk.CheckButton(name)
+ checkbutton.set_active(node.digi1 & (1 << DIG1_BITS[name]))
+ checkbutton.connect("toggled", self.__dig1_toggled, (node, name))
+ vbox1.pack_start(checkbutton, False, False)
+ frame.add(vbox1)
+ hbox1.pack_start(frame)
+ frame = gtk.Frame('Digital Converter Category')
+ entry = gtk.Entry()
+ entry.set_text("0x%x" % node.dig1_category)
+ entry.set_width_chars(4)
+ entry.connect("activate", self.__dig1_category_activate, node)
+ frame.add(entry)
+ hbox1.pack_start(frame)
+ vbox.pack_start(hbox1, False, False)
+
+ return vbox
+
+ def __build_device(self, device):
+ vbox = gtk.VBox(False, 0)
+ frame = gtk.Frame('Device')
+ frame.set_border_width(4)
+ hbox = gtk.HBox(False, 0)
+ s = 'name=' + str(device.name) + ', type=' + \
+ str(device.type) + ', device=' + str(device.device)
+ label = gtk.Label(s)
+ hbox.pack_start(label, False, False)
+ frame.add(hbox)
+ vbox.pack_start(frame)
+ return vbox
+
+ def __build_controls(self, ctrls):
+ vbox = gtk.VBox(False, 0)
+ frame = gtk.Frame('Controls')
+ frame.set_border_width(4)
+ vbox1 = gtk.VBox(False, 0)
+ for ctrl in ctrls:
+ hbox1 = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox1, False, False)
+ s = 'name=' + str(ctrl.name) + ', index=' + str(ctrl.index) + \
+ ', device=' + str(ctrl.device)
+ label = gtk.Label(s)
+ hbox1.pack_start(label, False, False)
+ if ctrl.amp_chs:
+ hbox1 = gtk.HBox(False, 0)
+ vbox1.pack_start(hbox1, False, False)
+ s = ' chs=' + str(ctrl.amp_chs) + ', dir=' + str(ctrl.amp_dir) + \
+ ', idx=' + str(ctrl.amp_idx) + ', ofs=' + str(ctrl.amp_ofs)
+ label = gtk.Label(s)
+ hbox1.pack_start(label, False, False)
+ frame.add(vbox1)
+ vbox.pack_start(frame)
+ return vbox
+
+ def __build_proc(self, node):
+ frame = gtk.Frame('Processing Caps')
+ frame.set_border_width(4)
+ str = 'benign=%i\nnumcoef=%i\n' % (node.proc_benign, node.proc_numcoef)
+ frame.add(self.__new_text_view(text=str))
+ return frame
+
+ def __build_node(self, node, doframe=False):
+ self.mytitle = node.name()
+ if doframe:
+ mframe = gtk.Frame(self.mytitle)
+ mframe.set_border_width(4)
+ else:
+ mframe = gtk.Table()
+
+ vbox = gtk.VBox(False, 0)
+ dev = node.get_device()
+ if not dev is None:
+ vbox.pack_start(self.__build_device(dev), False, False)
+ ctrls = node.get_controls()
+ if ctrls:
+ vbox.pack_start(self.__build_controls(ctrls), False, False)
+ hbox = gtk.HBox(False, 0)
+ hbox.pack_start(self.__build_node_caps(node))
+ hbox.pack_start(self.__build_connection_list(node))
+ vbox.pack_start(hbox, False, False)
+ if node.in_amp or node.out_amp:
+ vbox.pack_start(self.__build_amps(node), False, False)
+ if node.wtype_id == 'PIN':
+ vbox.pack_start(self.__build_pin(node), False, False)
+ elif node.wtype_id in ['AUD_IN', 'AUD_OUT']:
+ vbox.pack_start(self.__build_aud(node), False, False)
+ else:
+ if not node.wtype_id in ['AUD_MIX', 'BEEP', 'AUD_SEL']:
+ print 'Node type %s has no GUI support' % node.wtype_id
+ if node.proc_wid:
+ vbox.pack_start(self.__build_proc(node), False, False)
+
+ mframe.add(vbox)
+ self.add_with_viewport(mframe)
+
+ def __build_codec_info(self, codec):
+ vbox = gtk.VBox(False, 0)
+
+ frame = gtk.Frame('Codec Identification')
+ frame.set_border_width(4)
+ str = 'Audio Fcn Group: %s\n' % (codec.afg and "0x%02x" % codec.afg or "N/A")
+ str += 'Modem Fcn Group: %s\n' % (codec.mfg and "0x%02x" % codec.mfg or "N/A")
+ str += 'Vendor ID:\t 0x%08x\n' % codec.vendor_id
+ str += 'Subsystem ID:\t 0x%08x\n' % codec.subsystem_id
+ str += 'Revision ID:\t 0x%08x\n' % codec.revision_id
+ frame.add(self.__new_text_view(text=str))
+ vbox.pack_start(frame, False, False)
+
+ frame = gtk.Frame('PCM Global Capabilities')
+ frame.set_border_width(4)
+ str = 'Rates:\t\t %s\n' % codec.pcm_rates[:6]
+ if len(codec.pcm_rates) > 6:
+ str += '\t\t %s\n' % codec.pcm_rates[6:]
+ str += 'Bits:\t\t %s\n' % codec.pcm_bits
+ str += 'Streams:\t %s\n' % codec.pcm_streams
+ frame.add(self.__new_text_view(text=str))
+ vbox.pack_start(frame, False, False)
+
+ return vbox
+
+ def __build_codec_amps(self, codec):
+
+ def build_caps(title, caps):
+ frame = gtk.Frame(title)
+ frame.set_border_width(4)
+ if caps and caps.ofs != None:
+ str = 'Offset:\t\t %d\n' % caps.ofs
+ str += 'Number of steps: %d\n' % caps.nsteps
+ str += 'Step size:\t %d\n' % caps.stepsize
+ str += 'Mute:\t\t %s\n' % (caps.mute and "True" or "False")
+ frame.add(self.__new_text_view(text=str))
+ return frame
+
+ hbox = gtk.HBox(False, 0)
+ c = build_caps('Global Input Amplifier Caps', codec.amp_caps_in)
+ hbox.pack_start(c)
+ c = build_caps('Global Output Amplifier Caps', codec.amp_caps_out)
+ hbox.pack_start(c)
+
+ return hbox
+
+ def __gpio_toggled(self, button, (codec, id, idx)):
+ codec.gpio.set(id, idx, button.get_active())
+ button.set_active(codec.gpio.test(id, idx))
+
+ def __build_codec_gpio(self, codec):
+ frame = gtk.Frame('GPIO')
+ frame.set_border_width(4)
+ hbox = gtk.HBox(False, 0)
+ str = 'IO Count: %d\n' % codec.gpio_max
+ str += 'O Count: %d\n' % codec.gpio_o
+ str += 'I Count: %d\n' % codec.gpio_i
+ str += 'Unsolicited: %s\n' % (codec.gpio_unsol and "True" or "False")
+ str += 'Wake: %s\n' % (codec.gpio_wake and "True" or "False")
+ hbox.pack_start(self.__new_text_view(text=str), False, False)
+ frame.add(hbox)
+ for id in GPIO_IDS:
+ id1 = id == 'direction' and 'out-dir' or id
+ frame1 = gtk.Frame(id1)
+ frame1.set_border_width(4)
+ vbox1 = gtk.VBox(False, 0)
+ for i in range(codec.gpio_max):
+ checkbutton = gtk.CheckButton('[%d]' % i)
+ checkbutton.set_active(codec.gpio.test(id, i))
+ checkbutton.connect("toggled", self.__gpio_toggled, (codec, id, i))
+ vbox1.pack_start(checkbutton, False, False)
+ frame1.add(vbox1)
+ hbox.pack_start(frame1, False, False)
+ return frame
+
+ def __build_codec(self, codec, doframe=False):
+ self.mytitle = codec.name
+ if doframe:
+ mframe = gtk.Frame(self.mytitle)
+ mframe.set_border_width(4)
+ else:
+ mframe = gtk.Table()
+
+ vbox = gtk.VBox(False, 0)
+ vbox.pack_start(self.__build_codec_info(codec), False, False)
+ vbox.pack_start(self.__build_codec_amps(codec), False, False)
+ vbox.pack_start(self.__build_codec_gpio(codec), False, False)
+ mframe.add(vbox)
+ self.add_with_viewport(mframe)
+
+ def __build_card_info(self, card):
+ str = 'Card: %s\n' % card.card
+ str += 'Id: %s\n' % card.id
+ str += 'Driver: %s\n' % card.driver
+ str += 'Name: %s\n' % card.name
+ str += 'LongName: %s\n' % card.longname
+ return self.__new_text_view(text=str)
+
+ def __build_card(self, card, doframe=False):
+ self.mytitle = card.name
+ if doframe:
+ mframe = gtk.Frame(self.mytitle)
+ mframe.set_border_width(4)
+ else:
+ mframe = gtk.Table()
+
+ vbox = gtk.VBox(False, 0)
+ vbox.pack_start(self.__build_card_info(card), False, False)
+ mframe.add(vbox)
+ self.add_with_viewport(mframe)
#!/usr/bin/env python
URL="http://git.alsa-project.org/?p=alsa.git;a=blob_plain;f=hda-analyzer/"
-FILES=["hda_analyzer.py", "hda_codec.py", "hda_proc.py"]
+FILES=["hda_analyzer.py", "hda_guilib.py", "hda_codec.py", "hda_proc.py",
+ "hda_graph.py"]
try:
import gobject