SHARE
TWEET

LockKeys 0.2

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