SHARE
TWEET

Untitled

a guest Dec 2nd, 2014 172 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
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