Pasted by JockeTF at 2009-08-22, 03:48:03.
  1. #!/usr/bin/env python
  2. "A simple volume control applet."
  3.  
  4. import gtk
  5. import subprocess
  6.  
  7. __author__  = "Joakim \"JockeTF\" Soderlund"
  8. __date__    = "2008-08-22"
  9. __license__ = "Public domain."
  10.  
  11. # Binaries to execute.
  12. OSSMIX  = "ossmix"
  13. OSSXMIX = "ossxmix"
  14.  
  15. # The device to control.
  16. DEVICE = "vmix0-outvol"
  17.  
  18. # The maximum outvol volume in decibels.
  19. MAX_DB = 25.0
  20.  
  21. # Sets an icon for different volume levels.
  22. LEVELS = (
  23.     (22, "audio-volume-high"),
  24.     (18, "audio-volume-medium"),
  25.     (0,  "audio-volume-low"),
  26.     (-1, "audio-volume-muted"),
  27. )
  28.  
  29. class StatusIcon():
  30.     "The status icon."
  31.     def __init__(self):
  32.         self.icon = gtk.StatusIcon()
  33.        
  34.         self.icon.connect("scroll-event", self.scrollEvent)
  35.         self.icon.connect("activate", self.clickEvent)
  36.        
  37.         self.set_visible = self.icon.set_visible
  38.        
  39.         self.update()
  40.  
  41.  
  42.     def scrollEvent(self, widget, event, *args):
  43.         "Changes the volume when the user scrolls on the volume applet."
  44.         if event.direction == gtk.gdk.SCROLL_UP:
  45.             subprocess.call([OSSMIX, DEVICE, "--", "+%.1f" % self.getStep()])
  46.            
  47.         elif event.direction == gtk.gdk.SCROLL_DOWN:
  48.             subprocess.call([OSSMIX, DEVICE, "--", "-%.1f" % self.getStep()])
  49.  
  50.         self.update()
  51.  
  52.  
  53.     def clickEvent(self, widget, *args):
  54.         "Starts or closes ossxmix when the volume applet is clicked."
  55.         if not hasattr(self, "ossxmix"):
  56.             self.ossxmix = subprocess.Popen([OSSXMIX, "-S"])
  57.         else:
  58.             if self.ossxmix.poll() == None:
  59.                 self.ossxmix.terminate()
  60.             else:
  61.                 self.ossxmix = subprocess.Popen([OSSXMIX, "-S"])
  62.  
  63.         self.update()
  64.  
  65.        
  66.     def getVolume(self):
  67.         "Returns the current volume in decibels as a float."
  68.         process = subprocess.Popen([OSSMIX, DEVICE], stdout=subprocess.PIPE)
  69.         volume = float(process.communicate()[0].split()[-2])
  70.         process.wait()
  71.        
  72.         return volume
  73.  
  74.    
  75.     def getStep(self):
  76.         "Returns the next volume step to make in decibels as a float."
  77.         return (MAX_DB - self.getVolume() + 1) * 0.1
  78.  
  79.  
  80.     def getIconName(self):
  81.         "Returns the icon name for the current volume level."
  82.         volume = self.getVolume()
  83.        
  84.         for level in LEVELS:
  85.             if level[0] < volume:
  86.                 return level[1]
  87.  
  88.  
  89.     def update(self, *args):
  90.         "Updates the volume applet's tooltip and icon."
  91.         self.icon.set_tooltip("Volume: %.1f dB" % self.getVolume())
  92.         self.icon.set_from_icon_name(self.getIconName())
  93.  
  94.  
  95. if __name__ == "__main__":
  96.     icon = StatusIcon()
  97.     icon.set_visible(True)
  98.    
  99.     try:
  100.         gtk.main()
  101.     except KeyboardInterrupt:
  102.         print("")
  103.