hwmixvolume: use four spaces instead of one tab for indent

This is the recommended coding style for all Python programs, as
specified in PEP-0008[1].

[1] https://www.python.org/dev/peps/pep-0008/

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Emmanuel Gil Peyrot 2018-09-18 15:42:31 +02:00 committed by Takashi Iwai
parent 235d9c5e83
commit 50e9ac4e81

View file

@ -26,285 +26,285 @@ EVENT_INFO = alsahcontrol.event_mask['INFO']
EVENT_REMOVE = alsahcontrol.event_mask_remove EVENT_REMOVE = alsahcontrol.event_mask_remove
class Stream: class Stream:
def __init__(self, element, parent): def __init__(self, element, parent):
self.element = element self.element = element
self.element.set_callback(self) self.element.set_callback(self)
self.parent = parent self.parent = parent
self.label = None self.label = None
self.scales = [] self.scales = []
self.adjustments = [] self.adjustments = []
self.callback(self.element, EVENT_INFO) self.callback(self.element, EVENT_INFO)
def destroy(self): def destroy(self):
self.deactivate() self.deactivate()
def callback(self, e, mask): def callback(self, e, mask):
if mask == EVENT_REMOVE: if mask == EVENT_REMOVE:
self.deactivate() self.deactivate()
elif (mask & EVENT_INFO) != 0: elif (mask & EVENT_INFO) != 0:
info = alsahcontrol.Info(self.element) info = alsahcontrol.Info(self.element)
if info.is_inactive: if info.is_inactive:
self.deactivate() self.deactivate()
else: else:
self.activate() self.activate()
elif (mask & EVENT_VALUE) != 0: elif (mask & EVENT_VALUE) != 0:
self.update_scales_from_ctl() self.update_scales_from_ctl()
def activate(self): def activate(self):
if self.label: if self.label:
return return
info = alsahcontrol.Info(self.element) info = alsahcontrol.Info(self.element)
value = alsahcontrol.Value(self.element) value = alsahcontrol.Value(self.element)
value.read() value.read()
values = value.get_tuple(TYPE_INTEGER, info.count) values = value.get_tuple(TYPE_INTEGER, info.count)
self.label = gtk.Label(self.get_label(info)) self.label = gtk.Label(self.get_label(info))
self.label.set_single_line_mode(True) self.label.set_single_line_mode(True)
self.parent.scales_vbox.pack_start(self.label, expand=False) self.parent.scales_vbox.pack_start(self.label, expand=False)
for i in range(info.count): for i in range(info.count):
adj = gtk.Adjustment(value=values[i], adj = gtk.Adjustment(value=values[i],
lower=info.min, upper=info.max, lower=info.min, upper=info.max,
step_incr=1, step_incr=1,
page_incr=(info.max-info.min+1)/8) page_incr=(info.max-info.min+1)/8)
adj.connect('value-changed', self.update_ctl_from_scale, i) adj.connect('value-changed', self.update_ctl_from_scale, i)
scale = gtk.HScale(adj) scale = gtk.HScale(adj)
scale.set_draw_value(False) scale.set_draw_value(False)
self.parent.scales_vbox.pack_start(scale, expand=False) self.parent.scales_vbox.pack_start(scale, expand=False)
self.scales.append(scale) self.scales.append(scale)
self.adjustments.append(adj) self.adjustments.append(adj)
self.parent.scales_vbox.show_all() self.parent.scales_vbox.show_all()
self.parent.update_msg_label() self.parent.update_msg_label()
def deactivate(self): def deactivate(self):
if not self.label: if not self.label:
return return
self.label.destroy() self.label.destroy()
for s in self.scales: for s in self.scales:
s.destroy() s.destroy()
self.label = None self.label = None
self.scales = [] self.scales = []
self.adjustments = [] self.adjustments = []
self.parent.update_msg_label() self.parent.update_msg_label()
def update_scales_from_ctl(self): def update_scales_from_ctl(self):
if not self.label: if not self.label:
return return
count = len(self.adjustments) count = len(self.adjustments)
value = alsahcontrol.Value(self.element) value = alsahcontrol.Value(self.element)
value.read() value.read()
values = value.get_tuple(TYPE_INTEGER, count) values = value.get_tuple(TYPE_INTEGER, count)
for i in range(count): for i in range(count):
self.adjustments[i].set_value(values[i]) self.adjustments[i].set_value(values[i])
def update_ctl_from_scale(self, adj, index): def update_ctl_from_scale(self, adj, index):
scale_value = adj.get_value() scale_value = adj.get_value()
value_to_set = int(round(adj.get_value())) value_to_set = int(round(adj.get_value()))
count = len(self.adjustments) count = len(self.adjustments)
value = alsahcontrol.Value(self.element) value = alsahcontrol.Value(self.element)
if self.parent.lock_check.get_active(): if self.parent.lock_check.get_active():
values = [value_to_set for i in range(count)] values = [value_to_set for i in range(count)]
else: else:
value.read() value.read()
values = value.get_array(TYPE_INTEGER, count) values = value.get_array(TYPE_INTEGER, count)
values[index] = value_to_set values[index] = value_to_set
value.set_array(TYPE_INTEGER, values) value.set_array(TYPE_INTEGER, values)
value.write() value.write()
if value_to_set != scale_value: if value_to_set != scale_value:
adj.set_value(value_to_set) adj.set_value(value_to_set)
def get_label(self, info): def get_label(self, info):
pid = self.get_pid(info) pid = self.get_pid(info)
if pid: if pid:
cmdline = self.get_pid_cmdline(pid) cmdline = self.get_pid_cmdline(pid)
if cmdline: if cmdline:
return cmdline return cmdline
else: else:
return "PID %d" % pid return "PID %d" % pid
else: else:
name = info.name name = info.name
if name[-7:] == " Volume": if name[-7:] == " Volume":
name = name[:-7] name = name[:-7]
if name[-9:] == " Playback": if name[-9:] == " Playback":
name = name[:-9] name = name[:-9]
return name return name
def get_pid(self, info): def get_pid(self, info):
card = self.parent.current_card card = self.parent.current_card
device = info.device device = info.device
subdevice = info.subdevice subdevice = info.subdevice
if subdevice == 0: if subdevice == 0:
subdevice = info.index subdevice = info.index
filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice) filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice)
try: try:
f = open(filename, "r") f = open(filename, "r")
except IOError: except IOError:
return None return None
try: try:
for line in f.readlines(): for line in f.readlines():
if line[:9] == "owner_pid": if line[:9] == "owner_pid":
return int(line.split(':')[1].strip()) return int(line.split(':')[1].strip())
finally: finally:
f.close() f.close()
return None return None
def get_pid_cmdline(self, pid): def get_pid_cmdline(self, pid):
try: try:
f = open("/proc/%d/cmdline" % pid, "r") f = open("/proc/%d/cmdline" % pid, "r")
except IOError: except IOError:
return None return None
try: try:
cmdline = f.read() cmdline = f.read()
finally: finally:
f.close() f.close()
return cmdline.replace('\x00', ' ').strip() return cmdline.replace('\x00', ' ').strip()
class MixerWindow(gtk.Window): class MixerWindow(gtk.Window):
card_numbers = alsacard.card_list() card_numbers = alsacard.card_list()
current_card = -1 current_card = -1
hcontrol = None hcontrol = None
scales_vbox = None scales_vbox = None
msg_label = None msg_label = None
streams = [] streams = []
hctl_sources = [] hctl_sources = []
def __init__(self): def __init__(self):
gtk.Window.__init__(self) gtk.Window.__init__(self)
self.connect('destroy', lambda w: gtk.main_quit()) self.connect('destroy', lambda w: gtk.main_quit())
self.set_title("Hardware Mixer Volumes") self.set_title("Hardware Mixer Volumes")
vbox = gtk.VBox() vbox = gtk.VBox()
self.add(vbox) self.add(vbox)
hbox = gtk.HBox() hbox = gtk.HBox()
vbox.pack_start(hbox, expand=False) vbox.pack_start(hbox, expand=False)
label = gtk.Label("_Sound Card: ") label = gtk.Label("_Sound Card: ")
label.set_use_underline(True) label.set_use_underline(True)
hbox.pack_start(label, expand=False) hbox.pack_start(label, expand=False)
combo = gtk.combo_box_new_text() combo = gtk.combo_box_new_text()
for i in self.card_numbers: for i in self.card_numbers:
str = "%d: %s" % (i, alsacard.card_get_name(i)) str = "%d: %s" % (i, alsacard.card_get_name(i))
combo.append_text(str) combo.append_text(str)
if len(self.card_numbers) > 0: if len(self.card_numbers) > 0:
combo.set_active(0) combo.set_active(0)
combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()])) combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()]))
hbox.pack_start(combo) hbox.pack_start(combo)
label.set_mnemonic_widget(combo) label.set_mnemonic_widget(combo)
self.lock_check = gtk.CheckButton(label="_Lock Channels") self.lock_check = gtk.CheckButton(label="_Lock Channels")
self.lock_check.set_active(True) self.lock_check.set_active(True)
vbox.pack_start(self.lock_check, expand=False) vbox.pack_start(self.lock_check, expand=False)
scrollwin = gtk.ScrolledWindow() scrollwin = gtk.ScrolledWindow()
scrollwin.set_policy(hscrollbar_policy=gtk.POLICY_NEVER, vscrollbar_policy=gtk.POLICY_AUTOMATIC) scrollwin.set_policy(hscrollbar_policy=gtk.POLICY_NEVER, vscrollbar_policy=gtk.POLICY_AUTOMATIC)
scrollwin.set_shadow_type(gtk.SHADOW_NONE) scrollwin.set_shadow_type(gtk.SHADOW_NONE)
vbox.pack_start(scrollwin) vbox.pack_start(scrollwin)
self.scales_vbox = gtk.VBox() self.scales_vbox = gtk.VBox()
scrollwin.add_with_viewport(self.scales_vbox) scrollwin.add_with_viewport(self.scales_vbox)
label = gtk.Label() label = gtk.Label()
label.set_single_line_mode(True) label.set_single_line_mode(True)
line_height = label.size_request()[1] line_height = label.size_request()[1]
label.destroy() label.destroy()
scale = gtk.HScale() scale = gtk.HScale()
scale.set_draw_value(False) scale.set_draw_value(False)
line_height += scale.size_request()[1] line_height += scale.size_request()[1]
scale.destroy() scale.destroy()
# always have space for at least four sliders # always have space for at least four sliders
scrollwin.set_size_request(width=-1, height=line_height*4+4) scrollwin.set_size_request(width=-1, height=line_height*4+4)
# TODO: select the default card or the first card with stream controls # TODO: select the default card or the first card with stream controls
if len(self.card_numbers) > 0: if len(self.card_numbers) > 0:
self.change_card(self.card_numbers[0]) self.change_card(self.card_numbers[0])
self.update_msg_label() self.update_msg_label()
self.show_all() self.show_all()
def change_card(self, cardnum): def change_card(self, cardnum):
for s in self.hctl_sources: for s in self.hctl_sources:
gobject.source_remove(s) gobject.source_remove(s)
self.hctl_sources = [] self.hctl_sources = []
self.hcontrol = self.open_hcontrol_for_card(cardnum) self.hcontrol = self.open_hcontrol_for_card(cardnum)
for s in self.streams: for s in self.streams:
s.destroy() s.destroy()
self.streams = [] self.streams = []
self.current_card = cardnum self.current_card = cardnum
if not self.hcontrol: if not self.hcontrol:
self.update_msg_label() self.update_msg_label()
return return
for id in self.hcontrol.list(): for id in self.hcontrol.list():
if not self.is_stream_elem(id): if not self.is_stream_elem(id):
continue continue
elem = alsahcontrol.Element(self.hcontrol, id[0]) elem = alsahcontrol.Element(self.hcontrol, id[0])
info = alsahcontrol.Info(elem) info = alsahcontrol.Info(elem)
if not self.is_stream_info(info): if not self.is_stream_info(info):
continue continue
stream = Stream(elem, self) stream = Stream(elem, self)
self.streams.append(stream) self.streams.append(stream)
for fd,condition in self.hcontrol.poll_fds: for fd,condition in self.hcontrol.poll_fds:
self.hctl_sources.append(gobject.io_add_watch(fd, condition, self.hctl_io_callback)) self.hctl_sources.append(gobject.io_add_watch(fd, condition, self.hctl_io_callback))
self.update_msg_label() self.update_msg_label()
self.scales_vbox.show_all() self.scales_vbox.show_all()
def update_msg_label(self): def update_msg_label(self):
needs_msg = len(self.scales_vbox.get_children()) < 2 needs_msg = len(self.scales_vbox.get_children()) < 2
has_msg = self.msg_label has_msg = self.msg_label
if has_msg and not needs_msg: if has_msg and not needs_msg:
self.msg_label.destroy() self.msg_label.destroy()
self.msg_label = None self.msg_label = None
elif needs_msg: elif needs_msg:
if len(self.streams) > 0: if len(self.streams) > 0:
msg = "There are no open streams." msg = "There are no open streams."
else: else:
msg = "This card does not have stream controls." msg = "This card does not have stream controls."
if not has_msg: if not has_msg:
self.msg_label = gtk.Label(msg) self.msg_label = gtk.Label(msg)
self.scales_vbox.pack_start(self.msg_label) self.scales_vbox.pack_start(self.msg_label)
self.scales_vbox.show_all() self.scales_vbox.show_all()
elif self.msg_label.get_text() != msg: elif self.msg_label.get_text() != msg:
self.msg_label.set_text(msg) self.msg_label.set_text(msg)
def open_hcontrol_for_card(self, cardnum): def open_hcontrol_for_card(self, cardnum):
devname = "hw:CARD=" + str(cardnum) devname = "hw:CARD=" + str(cardnum)
try: try:
hc = alsahcontrol.HControl(name=devname, hc = alsahcontrol.HControl(name=devname,
mode=alsahcontrol.open_mode['NONBLOCK']) mode=alsahcontrol.open_mode['NONBLOCK'])
except: except:
# TODO: alsa error msg # TODO: alsa error msg
dlg = gtk.MessageDialog(self, dlg = gtk.MessageDialog(self,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
"Cannot open sound card control device.") "Cannot open sound card control device.")
dlg.run() dlg.run()
dlg.destroy() dlg.destroy()
return None return None
return hc return hc
def is_stream_elem(self, id): def is_stream_elem(self, id):
return ((id[1] == INTF_PCM and return ((id[1] == INTF_PCM and
id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or
(id[1] == INTF_MIXER and (id[1] == INTF_MIXER and
id[4] == "VIA DXS Playback Volume")) id[4] == "VIA DXS Playback Volume"))
def is_stream_info(self, info): def is_stream_info(self, info):
return info.is_readable and info.is_writable and info.type == TYPE_INTEGER return info.is_readable and info.is_writable and info.type == TYPE_INTEGER
def hctl_io_callback(self, source, condition): def hctl_io_callback(self, source, condition):
self.hcontrol.handle_events() self.hcontrol.handle_events()
return True return True
def main(): def main():
MixerWindow() MixerWindow()
gtk.main() gtk.main()
main() main()