Guest User

Untitled

a guest
Dec 2nd, 2014
177
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python2
  2. # -*- coding: utf-8 -*-
  3.  
  4. import gtk
  5. import glib
  6. import os
  7. import sys
  8. import ConfigParser
  9. import ctypes
  10. try:
  11.     import pynotify
  12.     if not pynotify.init("LockKeys"):
  13.         print("Il y a eu une erreur pendant l'initialisation du système de notification. Les notifications ne fonctionnerons pas.")
  14.         pynotify = None
  15. except:
  16.     print("Il semble que python-notify ne soit pas installé. Les notifications ne fonctionnerons pas.")
  17.     pynotify = None
  18. NotifyAvailable = pynotify
  19.  
  20. class XKeyboardState(ctypes.Structure):
  21.     _fields_ = [("key_click_percent", ctypes.c_int),
  22.                 ("bell_percent", ctypes.c_int),
  23.                 ("bell_pitch", ctypes.c_uint),
  24.                 ("bell_duration", ctypes.c_uint),
  25.                 ("led_mask", ctypes.c_ulong),
  26.                 ("global_auto_repeat", ctypes.c_int),
  27.                 ("auto_repeats", ctypes.c_char * 32)]
  28.  
  29. def initXGetKeyboardControl():
  30.     global dpy, keyboardState, XGetKeyboardControl
  31.    
  32.     libX11 = ctypes.CDLL("libX11.so.6")
  33.     XOpenDisplay = libX11.XOpenDisplay
  34.     XOpenDisplay.restype = ctypes.c_void_p
  35.     XOpenDisplay.argtypes = [ctypes.c_char_p]
  36.     XGetKeyboardControl = libX11.XGetKeyboardControl
  37.     XGetKeyboardControl.restype = ctypes.c_int
  38.     XGetKeyboardControl.argtypes = [ctypes.c_void_p, ctypes.POINTER(XKeyboardState)]
  39.    
  40.     dpy = XOpenDisplay(None)
  41.     keyboardState = XKeyboardState()
  42.  
  43. def runXGetKeyboardControl():
  44.     global dpy, keyboardState, XGetKeyboardControl
  45.     XGetKeyboardControl(dpy, ctypes.byref(keyboardState))
  46.     return keyboardState.led_mask
  47.  
  48. #écrit dans le fichier de config    
  49. def WriteConfig (Section, Key, Value):
  50.     Config.set(Section,Key,Value)
  51.     with open(ConfigFile, 'w') as myfile:
  52.         Config.write(myfile)
  53.  
  54. #Notification (état du clavier) si pynotify != None
  55. def notify(message,duration):
  56.     if pynotify:
  57.         n = pynotify.Notification('LockKeys', message)
  58.         n.set_timeout(duration)
  59.         n.set_icon_from_pixbuf(gtk.Label().render_icon(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_LARGE_TOOLBAR))
  60.         n.show()
  61.  
  62.  
  63. class Systray():
  64.     def __init__(self):
  65.         self.tray_object= gtk.StatusIcon()
  66.         self.tray_object.connect("popup_menu", self.rightclick_menu)
  67.         self.show_trayicon(1) ## fixed to one for now
  68.         self._oldMask = -1
  69.  
  70.     def show_trayicon(self,value):
  71.        self.tray_object.set_visible(True)
  72.        return
  73.  
  74.     def property_modified(self):
  75.         # utilse xset pour connaître l'état des touches capslock et numlock
  76.         # 0 -> aucun, 1 -> capslock, 2-> numlock, 3 -> les 2
  77.         mask=int(runXGetKeyboardControl()) & 3
  78.         if mask != self._oldMask:
  79.             self._oldMask = mask
  80.             if sound_status == True:
  81.                 os.system(Sound)
  82.             notify(msg[mask],2000)
  83.            
  84.             # Todo : essayer d'abord usr/share/lockkeys/ voire ~/.local/lockkeys
  85.             icon_path = './' + str(mask) + '.png'
  86.             self.tray_object.set_from_file(icon_path)
  87.  
  88.     # défini le menu clic droit sur l'icône
  89.     def rightclick_menu(self, button, widget, event):
  90.         menu = gtk.Menu()
  91.         about_menu = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
  92.         about_menu.connect('activate', self.about)
  93.         exit_menu = gtk.ImageMenuItem(gtk.STOCK_CLOSE)
  94.         exit_menu.connect('activate', self.close)
  95.         menu.append(about_menu)
  96.         menu.append(exit_menu)
  97.         sep = gtk.SeparatorMenuItem()
  98.         menu.append(sep)
  99.         sound_menu = gtk.CheckMenuItem("Activer le son")
  100.         sound_menu.set_active(sound_status)
  101.         sound_menu.connect("activate", self.sound_toggle)
  102.         menu.append(sound_menu)
  103.         notify_menu = gtk.CheckMenuItem("Activer les notifications")
  104.         notify_menu.set_active(notify_status)
  105.         notify_menu.connect("activate", self.notify_toggle)
  106.         menu.append(notify_menu)
  107.         menu.show_all()
  108.         menu.popup(None, None, None, 2, event)
  109.        
  110.     # activation / désactivation du son et enregistrement dans le fichier config
  111.     def sound_toggle(self, widget):
  112.         global sound_status
  113.         if widget.active:
  114.             sound_status=True
  115.         else:
  116.             sound_status=False
  117.         WriteConfig ('helpers','sound',sound_status)
  118.  
  119.     # activation / désactivation des notifications et enregistrement dans le fichier config
  120.     def notify_toggle(self, widget):
  121.         global notify_status
  122.         global pynotify
  123.         if widget.active:
  124.             notify_status=True
  125.             pynotify=NotifyAvailable
  126.         else:
  127.             notify_status=False
  128.             pynotify=None
  129.         WriteConfig ('helpers','notification',notify_status)
  130.  
  131.     def close(self,button):
  132.         sys.exit(0)
  133.  
  134.     def about(self, button):
  135.         about_dg = gtk.AboutDialog()
  136.         about_dg.set_name('Lockkeys')
  137.         about_dg.set_version('0.2')
  138.         about_dg.set_copyright('(C) 2014 Vincent Gay <vgay@vintherine.org>')
  139.         about_dg.set_comments(("Simple icône dans la zone de notification pour indiquer l'état de CapsLock et NumLock"))
  140.         about_dg.set_license('Ce script est distribuable sous licence gpl version 3 ou supérieure\nhttp://www.gnu.org/licenses/gpl-3.0.fr.html')
  141.         about_dg.set_website('http://blog.vintherine.org')
  142.         about_dg.run()
  143.         about_dg.destroy()
  144.  
  145. class Manager:
  146.     def __init__(self):
  147.         self.listener = Systray()
  148.        
  149.     def __property_modified_handler(self):
  150.         self.listener.property_modified()
  151.  
  152.     def update(self):
  153.         self.__property_modified_handler()
  154.         return True
  155.  
  156. def main():
  157.     initXGetKeyboardControl()
  158.     m = Manager()
  159.     glib.timeout_add(300, m.update)
  160.     gtk.main()
  161.  
  162. ConfigFile=os.path.expanduser('~/.config/lockkeys.cfg')
  163. # aplay appartient au paquet alsa, est-ce la peine de vérifier ?
  164. Sound = 'aplay ./ding.wav > /dev/null 2>1&'
  165. sound_status=True
  166. pynotify = None
  167. Config = ConfigParser.ConfigParser()
  168. msg=[]
  169. msg.append('Capslock = off, Numlock = off')
  170. msg.append('Capslock = on, Numlock = off')
  171. msg.append('Capslock = off, Numlock = on')
  172. msg.append('Capslock = on, Numlock = on')
  173.  
  174. #créer le fichier de config s'il n'existe pas
  175. if os.path.isfile(ConfigFile) == False:
  176.     ini = open(ConfigFile,'w')
  177.     Config.add_section('helpers')
  178.     Config.set('helpers','sound',True)
  179.     Config.set('helpers','notification',False)
  180.     Config.write(ini)
  181.     ini.close()
  182.  
  183. # lire le fichier de configuration    
  184. Config.read(ConfigFile)
  185. try:
  186.     sound_status = Config.getboolean("helpers", "sound")
  187. except:
  188.     WriteConfig ('helpers','sound',True)
  189. try:
  190.     notify_status = Config.getboolean("helpers", "notification")
  191. except:
  192.     WriteConfig ('helpers','notification',False)
  193.     notify_status=False
  194. if notify_status:
  195.     pynotify=NotifyAvailable
  196.    
  197. main()
RAW Paste Data