| #! /usr/bin/env python |
| |
| """Program to control the Solaris audio device. |
| |
| When no arguments are given, this pops up a graphical window which lets you |
| choose which audio output device you want sound to go to. |
| |
| This program can be driven via the command line, and when done so, no window |
| pops up. Here are the options: |
| |
| --headphones[={0,1}] |
| -p[={0,1}] |
| Set the headphones output device. With no value, it toggles the |
| headphone device. With a value, 0 turns the headphones off and 1 |
| turns the headphones on. |
| |
| --speaker[={0,1}] |
| -s[={0,1}] |
| Set the speaker output device. Value semantics are the same as |
| above. |
| |
| --lineout[={0,1}] |
| -l[={0,1}] |
| Set the line out output device. Value semantics are the same as |
| above. |
| |
| --help |
| -h |
| Print this message and exit. |
| |
| """ |
| |
| import sys |
| from Tkinter import * |
| import sunaudiodev |
| from SUNAUDIODEV import * |
| |
| # Milliseconds between interrupt checks |
| KEEPALIVE_TIMER = 500 |
| |
| |
| |
| class MainWindow: |
| def __init__(self): |
| self.__tkroot = tkroot = Tk(className='Pynche') |
| tkroot.withdraw() |
| # create the menubar |
| menubar = Menu(tkroot) |
| # |
| # File menu |
| # |
| filemenu = Menu(menubar, tearoff=0) |
| filemenu.add_command(label='Quit', |
| command=self.__quit, |
| accelerator='Alt-Q', |
| underline=0) |
| # |
| # Tie them together |
| # |
| menubar.add_cascade(label='File', |
| menu=filemenu, |
| underline=0) |
| # now create the top level window |
| root = self.__root = Toplevel(tkroot, class_='Audiopy', menu=menubar) |
| root.protocol('WM_DELETE_WINDOW', self.__quit) |
| root.title('Audiopy') |
| root.iconname('Audiopy') |
| root.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) |
| root.bind('<Alt-q>', self.__quit) |
| root.bind('<Alt-Q>', self.__quit) |
| # |
| # Open up the audio control device and query for the current output |
| # device |
| self.__devctl = sunaudiodev.open('control') |
| info = self.__devctl.getinfo() |
| |
| # |
| # create the speaker/headphone radio button |
| label = Label(root, text='Output to:') |
| label.grid(row=0, column=0, sticky=E) |
| self.__spkvar = IntVar() |
| btn = Checkbutton(root, |
| text='Speaker', |
| variable=self.__spkvar, |
| onvalue=SPEAKER, |
| command=self.__outputto, |
| underline=0) |
| btn.grid(row=0, column=1, sticky=W) |
| root.bind('<Alt-s>', self.__speaker) |
| root.bind('<Alt-S>', self.__speaker) |
| self.__headvar = IntVar() |
| btn = Checkbutton(root, |
| text='Headphones', |
| variable=self.__headvar, |
| onvalue=HEADPHONE, |
| command=self.__outputto, |
| underline=0) |
| btn.grid(row=1, column=1, sticky=W) |
| root.bind('<Alt-h>', self.__headphones) |
| root.bind('<Alt-H>', self.__headphones) |
| self.__linevar = IntVar() |
| btn = Checkbutton(root, |
| variable=self.__linevar, |
| onvalue=LINE_OUT, |
| text='Line out', |
| command=self.__outputto, |
| underline=0) |
| btn.grid(row=2, column=1, sticky=W) |
| root.bind('<Alt-l>', self.__lineout) |
| root.bind('<Alt-L>', self.__lineout) |
| |
| def __quit(self, event=None): |
| self.__devctl.close() |
| self.__root.quit() |
| |
| def __keepalive(self): |
| # Exercise the Python interpreter regularly so keyboard interrupts get |
| # through. |
| self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) |
| # |
| # We have to poll because the device could have changed state and the |
| # underlying module does not support the SIGPOLL notification |
| # interface. |
| info = self.__devctl.getinfo() |
| self.__spkvar.set(info.o_port & SPEAKER) |
| self.__headvar.set(info.o_port & HEADPHONE) |
| self.__linevar.set(info.o_port & LINE_OUT) |
| |
| def __outputto(self, event=None): |
| info = self.__devctl.getinfo() |
| info.o_port = self.__spkvar.get() + \ |
| self.__headvar.get() + \ |
| self.__linevar.get() |
| self.__devctl.setinfo(info) |
| |
| def __getset(self, var, onvalue): |
| if var.get(): |
| var.set(0) |
| else: |
| var.set(onvalue) |
| self.__outputto() |
| |
| def __speaker(self, event=None): |
| self.__getset(self.__spkvar, SPEAKER) |
| |
| def __headphones(self, event=None): |
| self.__getset(self.__headvar, HEADPHONE) |
| |
| def __lineout(self, event=None): |
| self.__getset(self.__linevar, LINE_OUT) |
| |
| def start(self): |
| self.__keepalive() |
| self.__tkroot.mainloop() |
| |
| |
| |
| def usage(msg='', code=1): |
| print __doc__ |
| print msg |
| sys.exit(code) |
| |
| |
| def main(): |
| if len(sys.argv) == 1: |
| # GUI |
| w = MainWindow() |
| w.start() |
| return |
| |
| # command line |
| sval = None |
| hval = None |
| lval = None |
| for arg in sys.argv[1:]: |
| if arg in ('-h', '--help'): |
| usage(code=0) |
| # SPEAKER |
| elif arg in ('-s', '--speaker'): |
| sval = -1 |
| elif arg[:3] == '-s=': |
| try: |
| sval = int(arg[3:]) |
| except ValueError: |
| pass |
| if sval <> 0 and sval <> 1: |
| usage('Invalid option: ' + arg) |
| elif arg[:10] == '--speaker=': |
| try: |
| sval = int(arg[10:]) |
| except ValueError: |
| pass |
| if sval <> 0 and sval <> 1: |
| usage('Invalid option: ' + arg) |
| # HEADPHONES |
| elif arg in ('-p', '--headphones'): |
| hval = -1 |
| elif arg[:3] == '-p=': |
| try: |
| hval = int(arg[3:]) |
| except ValueError: |
| pass |
| if hval <> 0 and hval <> 1: |
| usage('Invalid option: ' + arg) |
| elif arg[:13] == '--headphones=': |
| try: |
| hval = int(arg[130:]) |
| except ValueError: |
| pass |
| if hval <> 0 and hval <> 1: |
| usage('Invalid option: ' + arg) |
| # LINEOUT |
| elif arg in ('-l', '--lineout'): |
| lval = -1 |
| elif arg[:3] == '-l=': |
| try: |
| lval = int(arg[3:]) |
| except ValueError: |
| pass |
| if lval <> 0 and lval <> 1: |
| usage('Invalid option: ' + arg) |
| elif arg[:10] == '--lineout=': |
| try: |
| lval = int(arg[10:]) |
| except ValueError: |
| pass |
| if lval <> 0 and lval <> 1: |
| usage('Invalid option: ' + arg) |
| else: |
| usage('Invalid option: ' + arg) |
| # now set the values |
| try: |
| devctl = sunaudiodev.open('control') |
| info = devctl.getinfo() |
| if sval is not None: |
| if sval == -1: |
| if info.o_port & SPEAKER: |
| sval = 0 |
| else: |
| sval = SPEAKER |
| else: |
| sval = sval * SPEAKER |
| else: |
| sval = info.o_port & SPEAKER |
| if hval is not None: |
| if hval == -1: |
| if info.o_port & HEADPHONE: |
| hval = 0 |
| else: |
| hval = HEADPHONE |
| else: |
| hval = hval * HEADPHONE |
| else: |
| hval = info.o_port & HEADPHONE |
| if lval is not None: |
| if lval == -1: |
| if info.o_port & LINE_OUT: |
| lval = 0 |
| else: |
| lval = LINE_OUT |
| else: |
| lval = lval * LINE_OUT |
| else: |
| lval = info.o_port & LINE_OUT |
| info.o_port = sval + hval + lval |
| devctl.setinfo(info) |
| finally: |
| devctl.close() |
| |
| |
| |
| if __name__ == '__main__': |
| main() |