Autocommit of file /home/julien/scripts/idlemail.py changed on host nix
[dotfiles/scripts.git] / SessionManager.py
1 #!/usr/bin/python
2 """
3 SessionManager
4 Copyright (c) 2010--2011, Olivier Mehani <shtrom@ssji.net>
5 All rights reserved.
6
7 Original source: https://scm.narf.ssji.net/svn/shtrom/browser/default-env/bin/SessionManager.py
8 Code documented at http://www.narf.ssji.net/~shtrom/wiki/projets/gnomescreensavernosession
9
10 Local changes by Julien Valroff <julien@kirya.net>
11   2011-05:
12     * Use standard python path
13     * Drop GPG-related code
14     * Make the script usable with Debian
15
16 $Id$
17 A drop-in replacement for org.gnome.SessionManager, doing almost nothing.
18 Loosely based on basic instructions at [0,1,2,3,5,6].
19
20 [0] http://people.gnome.org/~mccann/gnome-session/docs/gnome-session.html
21 [1] http://www.amk.ca/diary/2007/04/rough_notes_python_and_dbus.html
22 [2] http://paste.lisp.org/display/45824
23 [3] http://www.lamalex.net/2010/03/help-does-anyone-know-how-to-export-properties-with-python-dbus/
24 [4] http://thp.io/2007/09/x11-idle-time-and-focused-window-in.html
25 [5] http://www.eurion.net/python-snippets/snippet/GConf%3A%20get_set%20values.html
26 [6] http://lists.gnupg.org/pipermail/gnupg-users/2006-March/028189.html
27
28 Redistribution and use in source and binary forms, with or without
29 modification, are permitted provided that the following conditions
30 are met:
31 1. Redistributions of source code must retain the above copyright notice, this
32 list of conditions and the following disclaimer.
33 2. Redistributions in binary form must reproduce the above copyright notice,
34 this list of conditions and the following disclaimer in the documentation
35 and/or other materials provided with the distribution.
36 3. Neither the name of Olivier Mehani nor the names of its contributors
37 may be used to endorse or promote products derived from this software
38 without specific prior written permission.
39
40 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50 POSSIBILITY OF SUCH DAMAGE.
51
52 """
53
54 __version__ = "$Revision$"
55
56
57 import dbus
58 import dbus.service
59 import dbus.glib
60 import gobject
61
62 import gtk
63
64 import ctypes
65 import os
66
67 import gconf
68
69 import signal
70
71
72 ogSM    = 'org.gnome.SessionManager'
73 ogSMp   = '/org/gnome/SessionManager'
74 ogSMP   = 'org.gnome.SessionManager.Presence'
75 ogSMPp  = '/org/gnome/SessionManager/Presence'
76
77 class SessionManager(dbus.service.Object):
78     def __init__(self):
79         bus_name = dbus.service.BusName(ogSM,
80             bus=dbus.SessionBus())
81         dbus.service.Object.__init__(self, bus_name,
82             ogSMp)
83         self.presence = SessionManagerPresence()
84         #print "%s emulation ready" % ogSM
85
86     def get_smp(self):
87         return self.presence
88
89
90 class SessionManagerPresence(dbus.service.Object):
91     PRESENCE_AVAILABLE  = 0
92     PRESENCE_INVISIBLE  = 1
93     PRESENCE_BUSY               = 2
94     PRESENCE_IDLE               = 3
95     
96     status                      = PRESENCE_AVAILABLE
97     status_text         = ""
98
99     def __init__(self):
100         bus_name = dbus.service.BusName(ogSMP,
101             bus=dbus.SessionBus())
102         dbus.service.Object.__init__(self, bus_name,
103             ogSMPp)
104         #print "%s emulation ready" % ogSMP
105
106     @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
107         in_signature='s', out_signature='a{sv}')
108     def GetAll(self, interface_name):
109         #print "%s.GetAll(%s)" % (ogSMP, interface_name)
110         return {'status':               dbus.UInt32(self.status),
111             'status-text':  self.status_text,
112             }
113     @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
114         in_signature='ss', out_signature='v')
115     def Get(self, interface_name, property_name):
116         #print "%s.Get(%s, %s)" % (ogSMP, interface_name, property_name)
117         #print " -> %s" % str(self.GetAll(interface_name)[property_name])
118         return self.GetAll(interface_name)[property_name]
119     @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
120         in_signature='ssv')
121     def Set(self, interface_name, property_name, value):
122         #print "%s.Set(%s, %s, %s)" % \
123         #       (ogSMP, interface_name, property_name, value)
124         pass
125
126     @dbus.service.method(dbus_interface=ogSMP, in_signature='u')
127     def SetStatus(self, status):
128         self.status = status
129
130     @dbus.service.method(dbus_interface=ogSMP, in_signature='u')
131     def SetStatusText(self, status_text):
132         self.status_text = status_text
133
134     @dbus.service.signal(dbus_interface=ogSMP, signature='u')
135     def StatusChanged(self, status):
136         self.SetStatus(status)
137
138     @dbus.service.signal(dbus_interface=ogSMP, signature='s')
139     def StatusTextChanged(self, status_text):
140         self.SetStatusText(status_text)
141
142
143 class XScreenSaverIdleChecker():
144     class XScreenSaverInfo(ctypes.Structure):
145         """ typedef struct { ... } XScreenSaverInfo; """
146         _fields_ = [('window',    ctypes.c_ulong), # screen saver window
147             ('state',      ctypes.c_int),   # off,on,disabled
148             ('kind',            ctypes.c_int),   # blanked,internal,external
149             ('since',      ctypes.c_ulong), # milliseconds
150             ('idle',            ctypes.c_ulong), # milliseconds
151             ('event_mask',  ctypes.c_ulong)] # events
152         
153     def __init__(self, idle_timeout):
154         self.idle_timeout = idle_timeout
155         self.idle       = False
156         self.xlib       = ctypes.cdll.LoadLibrary('libX11.so.6')
157         self.dpy        = self.xlib.XOpenDisplay(os.environ['DISPLAY'])
158         self.root       = self.xlib.XDefaultRootWindow(self.dpy)
159         self.xss        = ctypes.cdll.LoadLibrary('libXss.so.1')
160         self.xss.XScreenSaverAllocInfo.restype \
161                 = ctypes.POINTER(self.XScreenSaverInfo)
162         print ("XScreenSaverIdleChecker ready with timeout %d" % idle_timeout)
163     
164     def check_idle(self, smp):
165         #print "Checking idleness..."
166         xss_info = self.xss.XScreenSaverAllocInfo()
167         self.xss.XScreenSaverQueryInfo(self.dpy, self.root, xss_info)
168         idle = xss_info.contents.idle/1000
169         
170         if idle >= self.idle_timeout:
171             if not self.idle:
172                 print "Becoming idle"
173                 self.idle = True
174                 smp.StatusChanged(smp.PRESENCE_IDLE)
175         else:
176             if self.idle:
177                 print "Not idle anymore"
178                 self.idle = False
179                 smp.StatusChanged(smp.PRESENCE_AVAILABLE)
180         
181         gobject.timeout_add(10000, self.check_idle, smp)
182     
183
184 gclient = gconf.client_get_default()
185 gvalue = gclient.get('/apps/gnome-screensaver/idle_delay')
186 if gvalue is not None:
187     idle_delay = gvalue.get_int() * 60
188 else:
189     # 5 minutes
190     idle_delay = 300
191
192 sessmgr = SessionManager()
193
194 xssic = XScreenSaverIdleChecker(idle_delay)
195 xssic.check_idle(sessmgr.get_smp())
196
197 gtk.main()