#!/usr/bin/python import gtk import dbus import dbus.service import subprocess import time from dbus.mainloop.glib import DBusGMainLoop import pynotify class KeyhandlerDBUSService(dbus.service.Object): def __init__(self): bus_name = dbus.service.BusName('org.elektranox.keyhandler', bus=dbus.SessionBus()) dbus.service.Object.__init__(self, bus_name, '/org/elektranox/keyhandler') self.bnotice = pynotify.Notification("Backlight", "", "display-brightness-symbolic") self.vnotice = pynotify.Notification("Volume", "", "") self.wnotice = pynotify.Notification("WLAN", "", "") self.mnotice = pynotify.Notification("Mouse", "", "") def _lid_status_open(self): lidstatus = "state: unknown" with open('/proc/acpi/button/lid/LID/state', 'r') as lidstatefile: lidstatus = lidstatefile.read() lidstatus = lidstatus.strip().replace("state: ", "") return lidstatus == "open" def _dock_status_docked(self): popen = subprocess.Popen(['/usr/bin/lsusb', '-d', '17ef:1010']) popen.wait() return not popen.returncode def _bluetooth_set_status(self, state): bus = dbus.SystemBus() dev = bus.get_object("org.bluez", u'/org/bluez/hci0') iface = dbus.Interface(dev, 'org.freedesktop.DBus.Properties') iface.Set("org.bluez.Adapter1", "Powered", state) def _bluetooth_get_status(self, state): bus = dbus.SystemBus() dev = bus.get_object("org.bluez", u'/org/bluez/hci0') iface = dbus.Interface(dev, 'org.freedesktop.DBus.Properties') return iface.Get("org.bluez.Adapter1", "Powered") def _getBacklight(self): with open("/sys/class/backlight/intel_backlight/brightness", "r") as f: return int(f.readline().strip()) def _getMaxBacklight(self): with open("/sys/class/backlight/intel_backlight/max_brightness", "r") as f: return int(f.readline().strip()) def _setBacklight(self, value): with open("/sys/class/backlight/intel_backlight/brightness", "w") as f: f.write(str(value)) def _showBacklightState(self): state = self._getBacklight() * 100 / self._getMaxBacklight() self.bnotice.set_hint_int32("value", int(state)) self.bnotice.set_hint_string("synchronous", "brightness") self.bnotice.show() def _showVolumeState(self): popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'get', 'Master'], stdout = subprocess.PIPE) popen.wait() (stdout,stderr) = popen.communicate(None) lines = stdout.split("\n") state = int(lines[-2].split()[3][1:-2]) muted = lines[-2].split()[5][1:-1] == "off" if muted: self.vnotice.set_property("icon-name", "audio-volume-muted") elif state < 20: self.vnotice.set_property("icon-name", "audio-volume-low") elif state < 60: self.vnotice.set_property("icon-name", "audio-volume-medium") else: self.vnotice.set_property("icon-name", "audio-volume-high") self.vnotice.set_hint_int32("value", state) self.vnotice.set_hint_string("synchronous", "volume") self.vnotice.show() def _rfkill_get(self, rfid): popen = subprocess.Popen(['/usr/sbin/rfkill', 'list', rfid], stdout = subprocess.PIPE) popen.wait() (stdout,stderr) = popen.communicate() return stdout.split("\n")[1].split(" ")[2] == "no" def _showMicState(self): popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'get', 'Capture'], stdout = subprocess.PIPE) popen.wait() (stdout,stderr) = popen.communicate(None) lines = stdout.split("\n") state = int(lines[-2].split()[4][1:-2]) muted = lines[-2].split()[6][1:-1] == "off" if muted: self.vnotice.set_property("icon-name", "microphone-sensitivity-muted") elif state < 20: self.vnotice.set_property("icon-name", "microphone-sensitivity-low") elif state < 60: self.vnotice.set_property("icon-name", "microphone-sensitivity-medium") else: self.vnotice.set_property("icon-name", "microphone-sensitivity-high") self.vnotice.set_hint_int32("value", state) self.vnotice.set_hint_string("synchronous", "volume") self.vnotice.show() @dbus.service.method('org.elektranox.keyhandler') def volumeMute(self): #popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'set', 'Master', 'toggle']) popen = subprocess.Popen(['/usr/bin/pactl', 'set-sink-mute', 'alsa_output.pci-0000_00_1b.0.analog-stereo', 'toggle']) popen.wait() self._showVolumeState() @dbus.service.method('org.elektranox.keyhandler') def volumeDec(self): popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'set', 'Master', '2%-']) popen.wait() self._showVolumeState() @dbus.service.method('org.elektranox.keyhandler') def volumeInc(self): popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'set', 'Master', '2%+']) popen.wait() self._showVolumeState() @dbus.service.method('org.elektranox.keyhandler') def micMute(self): #popen = subprocess.Popen(['/usr/bin/amixer', '-c', 'PCH', 'set', 'Master', 'toggle']) popen = subprocess.Popen(['/usr/bin/amixer', 'set', 'Capture', 'toggle']) popen.wait() self._showMicState() @dbus.service.method('org.elektranox.keyhandler') def backlightDec(self): brightness = self._getBacklight() - 5 if brightness < 0: brightness = 0 self._setBacklight(brightness) self._showBacklightState() @dbus.service.method('org.elektranox.keyhandler') def backlightInc(self): brightness = self._getBacklight() + 5 if brightness > self._getMaxBacklight(): brightness = self._getMaxBacklight() self._setBacklight(brightness) self._showBacklightState() @dbus.service.method('org.elektranox.keyhandler') def XF86Display(self): lidopen = self._lid_status_open() docked = self._dock_status_docked() if not docked: popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'eDP1', '--auto']) popen.wait() popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'DP2-1', '--off']) popen.wait() popen = subprocess.Popen(['/usr/bin/notify-send','Not docked']) popen.wait() elif lidopen: popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'eDP1', '--auto']) popen.wait() popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'DP2-1', '--right-of', 'eDP1', '--auto']) popen.wait() popen = subprocess.Popen(['/usr/bin/notify-send','Docked with open lid']) popen.wait() else: popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'DP2-1', '--right-of', 'eDP1', '--auto']) popen.wait() popen = subprocess.Popen(['/usr/bin/xrandr','--output', 'eDP1', '--off']) popen.wait() popen = subprocess.Popen(['/usr/bin/notify-send','Docked with closed lid']) popen.wait() @dbus.service.method('org.elektranox.keyhandler') def WLAN(self): # button itself is handled by systemd state = self._rfkill_get("wlan") if state: self.wnotice.set_property("icon-name", "network-wireless-symbolic") self.wnotice.set_property("summary", "enabled") else: self.wnotice.set_property("icon-name", "network-wireless-offline-symbolic") self.wnotice.set_property("summary", "disabled") self.wnotice.show() @dbus.service.method('org.elektranox.keyhandler') def XF86Tools(self): popen = subprocess.Popen(['/usr/local/bin/toggle-mouse-wheel-emulation'], stdout = subprocess.PIPE) popen.wait() (stdout,stderr) = popen.communicate(None) enabled = (stdout.find("enabled") != -1) self.mnotice.set_property("icon-name", "/usr/share/icons/mate/48x48/devices/input-mouse.png") if enabled: self.mnotice.set_property("summary", "Mouse Wheel Emulation enabled") else: self.mnotice.set_property("summary", "Mouse Wheel Emulation disabled") self.mnotice.show() @dbus.service.method('org.elektranox.keyhandler') def XF86Search(self): popen = subprocess.Popen(['/usr/bin/notify-send','XF86Search']) popen.wait() # TODO: add some fancy binding pass @dbus.service.method('org.elektranox.keyhandler') def XF86LaunchA(self): popen = subprocess.Popen(['/usr/bin/notify-send','XF86LaunchA']) popen.wait() # TODO: add some fancy binding pass @dbus.service.method('org.elektranox.keyhandler') def XF86Explorer(self): state = self._rfkill_get("bluetooth") if state: subprocess.call(['/usr/sbin/rfkill','block', 'bluetooth']) self.wnotice.set_property("icon-name", "/usr/share/icons/gnome/scalable/status/bluetooth-disabled-symbolic.svg") self.wnotice.set_property("summary", "RF blocked") else: subprocess.call(['/usr/sbin/rfkill','unblock', 'bluetooth']) self.wnotice.set_property("icon-name", "/usr/share/icons/gnome/scalable/status/bluetooth-active-symbolic.svg") self.wnotice.set_property("summary", "RF unblocked") self.wnotice.show() if not state: time.sleep(1) self._bluetooth_set_status(True) DBusGMainLoop(set_as_default=True) service = KeyhandlerDBUSService() pynotify.init("TP Keyhandler") gtk.main()