summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-03-06 14:16:47 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-03-06 14:16:47 +0100
commit4659883ba00bd499f41f4cc1a5f96e4bdd5ac9de (patch)
tree74211870b90bb20c0041c8a76d677579a88206a9
parente342d5c7241cd04352948fb6937e05a98000b70c (diff)
downloadpylock-4659883ba00bd499f41f4cc1a5f96e4bdd5ac9de.tar
pylock-4659883ba00bd499f41f4cc1a5f96e4bdd5ac9de.zip
Rework pylock to behave like xlock
-rw-r--r--Idle.py71
-rw-r--r--Locker.py25
-rw-r--r--Selection.py (renamed from Message.py)22
-rw-r--r--pylock.py77
4 files changed, 42 insertions, 153 deletions
diff --git a/Idle.py b/Idle.py
deleted file mode 100644
index d9ea53a..0000000
--- a/Idle.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-import ctypes
-import ctypes.util
-
-from gi.repository import GdkX11
-
-
-class XScreenSaverInfo(ctypes.Structure):
- _fields_ = [
- ('window', ctypes.c_ulong),
- ('state', ctypes.c_int),
- ('kind', ctypes.c_int),
- ('til_or_since', ctypes.c_ulong),
- ('idle', ctypes.c_ulong),
- ('eventMask', ctypes.c_ulong)
- ]
-XScreenSaverInfo_p = ctypes.POINTER(XScreenSaverInfo)
-
-display_p = ctypes.c_void_p
-xid = ctypes.c_ulong
-c_int_p = ctypes.POINTER(ctypes.c_int)
-
-libXsspath = ctypes.util.find_library('Xss')
-if libXsspath == None:
- raise OSError('libXss could not be found.')
-libXss = ctypes.cdll.LoadLibrary(libXsspath)
-libXss.XScreenSaverQueryExtension.argtypes = display_p, c_int_p, c_int_p
-libXss.XScreenSaverAllocInfo.restype = XScreenSaverInfo_p
-libXss.XScreenSaverQueryInfo.argtypes = (display_p, xid, XScreenSaverInfo_p)
-
-dpy_p = hash(GdkX11.x11_get_default_xdisplay())
-rootwindow = GdkX11.x11_get_default_root_xwindow()
-
-_event_basep = ctypes.c_int()
-_error_basep = ctypes.c_int()
-if libXss.XScreenSaverQueryExtension(ctypes.c_void_p(dpy_p), ctypes.byref(_event_basep),
- ctypes.byref(_error_basep)) == 0:
- raise OSError('XScreenSaver Extension not available on display.')
-
-xss_info_p = libXss.XScreenSaverAllocInfo()
-if xss_info_p == None:
- raise OSError('XScreenSaverAllocInfo: Out of Memory.')
-
-def getIdleSec():
- if libXss.XScreenSaverQueryInfo(dpy_p, rootwindow, xss_info_p) == 0:
- return 0
- else:
- return int(xss_info_p.contents.idle) / 1000
diff --git a/Locker.py b/Locker.py
index 0f10fe0..5243609 100644
--- a/Locker.py
+++ b/Locker.py
@@ -24,35 +24,16 @@
from gi.repository import Gtk, GLib
-import Idle
-
class Locker(object):
- def __init__(self, lockTimeout, doLock, doUnlock, logoutTimeout = None, doLogout = None, updateLogoutTimeout = None):
+ def __init__(self, doLock, doUnlock, logoutTimeout = None, doLogout = None, updateLogoutTimeout = None):
self.locked = False
- self.lockTimeout = lockTimeout
self.logoutTimeout = logoutTimeout
self.doLock = doLock
self.doUnlock = doUnlock
self.doLogout = doLogout
self.updateLogoutTimeout = updateLogoutTimeout
- if self.lockTimeout > 0:
- GLib.timeout_add_seconds(1, self._checkLock)
- else:
- GLib.idle_add(self.lock)
-
- def _checkLock(self):
- if self.locked:
- return False
-
- idle = Idle.getIdleSec()
- if (idle >= self.lockTimeout):
- GLib.idle_add(self.lock)
- return False
- else:
- return True
-
def _checkLogout(self):
if not self.locked:
return False
@@ -68,7 +49,7 @@ class Locker(object):
self.locked = True
if not self.doLock(self.logoutTimeout):
self.locked = False
- GLib.timeout_add_seconds(1, self._checkLock)
+ GLib.timeout_add_seconds(1, self.lock)
return False
if self.doLogout is not None:
@@ -84,8 +65,6 @@ class Locker(object):
self.doUnlock()
self.locked = False
- GLib.timeout_add_seconds(1, self._checkLock)
-
def _canLogout(self):
return (self.locked and self.doLogout is not None and self.currentLogoutTimeout <= 0)
diff --git a/Message.py b/Selection.py
index b78a0f3..11a7285 100644
--- a/Message.py
+++ b/Selection.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
+# Copyright (c) 2012-2013, Matthias Schiffer <mschiffer@universe-factory.net>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,6 @@ if libX11 == None:
raise OSError('libX11 could not be found.')
libX11 = ctypes.cdll.LoadLibrary(libX11)
-libX11.XSendEvent.argtypes = display_p, xid, x11_bool, ctypes.c_long, XEvent_p
-libX11.XSendEvent.restype = status
libX11.XSetSelectionOwner.argtypes = display_p, xid, xid, x11_time
libX11.XSetSelectionOwner.restype = ctypes.c_int
libX11.XGetSelectionOwner.argtypes = display_p, xid
@@ -52,27 +50,17 @@ libX11.XGetSelectionOwner.restype = xid
display = Gdk.Display.get_default()
dpy_p = display_p(hash(GdkX11.X11Display.get_xdisplay(display)))
atomPylockWindow = GdkX11.x11_get_xatom_by_name("PYLOCK_WINDOW")
-atomPylockActionLock = GdkX11.x11_get_xatom_by_name("PYLOCK_ACTION_LOCK")
-def getSelection():
+def get():
return libX11.XGetSelectionOwner(dpy_p, atomPylockWindow)
-def sendLockMessage():
- window = getSelection()
- if window == 0:
- return
-
- gdkWindow = GdkX11.X11Window.foreign_new_for_display(display, window)
- gdkWindow.show()
- display.sync()
-
-def acquireSelection(window):
- if getSelection() != 0:
+def acquire(window):
+ if get() != 0:
return False
window.realize()
xid = GdkX11.X11Window.get_xid(window.get_window())
libX11.XSetSelectionOwner(dpy_p, atomPylockWindow, xid, 0)
- return (getSelection() == xid)
+ return (get() == xid)
diff --git a/pylock.py b/pylock.py
index be8e901..32e9149 100644
--- a/pylock.py
+++ b/pylock.py
@@ -30,33 +30,27 @@ import sys
import os
import pwd
import locale
-import argparse
+import configparser
-from gi.repository import Gtk, Gdk, Gio
+from gi.repository import Gtk, GLib
from Locker import Locker
from LockWindow import LockWindow
-import Message
+import Selection
import pam
-_ = locale.gettext
-
+CONFIG_FILE = '/etc/pylock.conf'
-def get_username():
- return pwd.getpwuid(os.getuid())[0]
-
-theme = 'UzL-login'
+_ = locale.gettext
-parser = argparse.ArgumentParser(prog='pylock', description=_('GTK-based screen locker.'))
-parser.add_argument('-t', '--timeout', type=int, default=0, help=_('Start in daemon mode that will automatically activate after a given time of inactivity.'))
-parser.add_argument('-l', '--logout', type=int, default=0, help=_('Allow to logout the current user after a given time.'))
-parser.add_argument('-c', '--logout-command', help=_('Specifies the command to be called to log out a user.'))
-parser.add_argument('-u', '--username', default=get_username(), help=_('Set the name of the user that is able to unlock the screen.'))
+configParser = configparser.ConfigParser()
+configParser.read_file(open(CONFIG_FILE))
-args = parser.parse_args()
+config = configParser['pylock']
+username = pwd.getpwuid(os.getuid())[0]
def handler(signum, frame):
@@ -71,66 +65,65 @@ signal.signal(signal.SIGQUIT, handler)
locale.setlocale(locale.LC_ALL, '')
locale.textdomain('pylock')
-Gtk.Settings.get_default().set_property('gtk-theme-name', theme)
+Gtk.Settings.get_default().set_property('gtk-theme-name', config['theme'])
-if Message.getSelection() != 0:
- if args.timeout == 0:
- Message.sendLockMessage()
- exit(0)
- else:
- print('There seems to be a Pylock instance already running.', file=sys.stderr)
- exit(1)
+def waitForSelection():
+ if Selection.get() != 0:
+ return True
+
+ Gtk.main_quit()
+ return False
+
+if Selection.get() != 0:
+ GLib.timeout_add_seconds(1, waitForSelection)
+ Gtk.main()
+ exit(0)
window = LockWindow()
-if not Message.acquireSelection(window):
- print('Unable to register for lock messages', file=sys.stderr)
+if not Selection.acquire(window):
+ print('Unable to register pylock at X server', file=sys.stderr)
+ exit(1)
def lock(timeLeft):
- window.updateLockMessage(args.username, timeLeft)
+ window.updateLockMessage(username, timeLeft)
return window.lock()
def logout():
try:
- os.system(args.logout_command)
+ os.system(config['logout_command'])
except:
pass
window.reset(False)
def updateTimeout(timeLeft):
- window.updateLockMessage(args.username, timeLeft)
+ window.updateLockMessage(username, timeLeft)
-if args.logout_command is None:
- locker = Locker(args.timeout, lock, window.unlock)
+if not ('logout_timeout' in config and 'logout_command' in config):
+ locker = Locker(lock, window.unlock)
else:
- locker = Locker(args.timeout, lock, window.unlock, args.logout, logout, updateTimeout)
-
-
-def _triggerLock(w, e):
- locker.lock()
-
-window.connect('map-event', _triggerLock)
-
+ locker = Locker(lock, window.unlock, int(config['logout_timeout']), logout, updateTimeout)
pamAuth = pam.pam()
def tryUnlock(w, password):
- if pamAuth.authenticate(args.username, password):
+ if pamAuth.authenticate(username, password):
locker.unlock()
-
- if args.timeout == 0:
- Gtk.main_quit()
+ Gtk.main_quit()
else:
window.reset()
window.setAuthMessage(pamAuth.reason)
return True
+
window.connect('logout', lambda w: locker.logout())
window.connect('tryUnlock', tryUnlock)
+GLib.idle_add(lambda: locker.lock())
+
Gtk.main()