From: Neil Brown Date: Wed, 28 Jan 2009 02:44:14 +0000 (+1100) Subject: Initial commit for "lock" - screen lock for neo Freerunner X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=f1b36c342baa6dbf0f5110abf35121ddcb3d9657;p=freerunner.git Initial commit for "lock" - screen lock for neo Freerunner --- f1b36c342baa6dbf0f5110abf35121ddcb3d9657 diff --git a/lock/lock-no.png b/lock/lock-no.png new file mode 100644 index 0000000..fe367d3 Binary files /dev/null and b/lock/lock-no.png differ diff --git a/lock/lock-nosusp.png b/lock/lock-nosusp.png new file mode 100644 index 0000000..3174bb5 Binary files /dev/null and b/lock/lock-nosusp.png differ diff --git a/lock/lock-un-nosusp.png b/lock/lock-un-nosusp.png new file mode 100644 index 0000000..965b4e7 Binary files /dev/null and b/lock/lock-un-nosusp.png differ diff --git a/lock/lock-un.png b/lock/lock-un.png new file mode 100644 index 0000000..990d127 Binary files /dev/null and b/lock/lock-un.png differ diff --git a/lock/lock.png b/lock/lock.png new file mode 100644 index 0000000..bb7b064 Binary files /dev/null and b/lock/lock.png differ diff --git a/lock/lock.py b/lock/lock.py new file mode 100644 index 0000000..27294af --- /dev/null +++ b/lock/lock.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python + +# This software is copyright Neil Brown 2009. +# It is licensed to you under the terms of the +# GNU General Public License version 2. +# +# +# blank and lock the screen when there is no activity. +# +# We detect activity by watching touch screen, power button, +# aux button +# After a period with no activity, we drop brightness to 20% +# and Grab all devices. +# Any activity at this stage returns us to 100% and no grab +# Continued inactivity turns display off. After that, require +# a button (AUX or Power) to reactivate. +# +# If the device seems really idle, we suspend with "apm -s" +# Other applications can disable this by getting a LOCK_SH +# lock on /var/run/suspend_disabled +# + +import gobject +import gtk +import fcntl +import os +import sys +import struct +import time +from subprocess import Popen, PIPE + +class EvDev: + def __init__(self, path, on_event): + self.f = os.open(path, os.O_RDWR|os.O_NONBLOCK); + self.ev = gobject.io_add_watch(self.f, gobject.IO_IN, self.read) + self.on_event = on_event + self.grabbed = False + self.downlist = [] + def read(self, x, y): + try: + str = os.read(self.f, 16) + except: + return True + + if len(str) != 16: + return True + (sec,usec,typ,code,value) = struct.unpack_from("IIHHI", str) + if typ == 0x01: + # KEY event + if value == 0: + # 'up' - remove from downlist + if code in self.downlist: + del self.downlist[self.downlist.index(code)] + else: + # 'down' - add to downlist + if code not in self.downlist: + self.downlist.append(code) + self.on_event(self.down_count(), typ, code, value) + return True + def down_count(self): + return len(self.downlist) + + def grab(self): + if self.grabbed: + return + #print "grab" + fcntl.ioctl(self.f, EVIOC_GRAB, 1) + self.grabbed = True + def ungrab(self): + if not self.grabbed: + return + #print "release" + fcntl.ioctl(self.f, EVIOC_GRAB, 0) + self.grabbed = False + +FBIOBLANK = 0x4611 +FB_BLANK_UNBLANK = 0 +FB_BLANK_POWERDOWN = 4 + +EVIOC_GRAB = 0x40044590 + +class Screen: + def __init__(self): + self.state = "unknown" + f = open("/sys/class/backlight/gta02-bl/max_brightness") + self.max = int(f.read()) + f.close() + def bright(self, pcent): + b = int(pcent * self.max / 100) + f = open("/sys/class/backlight/gta02-bl/brightness","w") + f.write("%d\n" % b) + f.close() + def power(self, ioc): + f = open("/dev/fb0", "r+") + fcntl.ioctl(f, FBIOBLANK, ioc) + f.close() + def on(self): + if self.state != "on": + self.power(FB_BLANK_UNBLANK) + self.state = "on" + self.bright(100) + def dim(self): + if self.state != "on": + self.power(FB_BLANK_UNBLANK) + self.state = "on" + self.bright(20) + def off(self): + self.bright(0) + if self.state != "off": + self.power(FB_BLANK_POWERDOWN) + self.state = "off" + +def grab_all(): + global screen, power, aux + screen.grab() + power.grab() + aux.grab() + +def release_all(): + global screen, power, aux + screen.ungrab() + power.ungrab() + aux.ungrab() + +timeout = None +state = "full" +dimtime = 15 +enable_suspend = True +def set_timeout(): + global timeout + global state, enable_suspend + global dimtime + #print "set timeout for", state + if timeout != None: + gobject.source_remove(timeout) + if state == "full": + timeout = gobject.timeout_add(dimtime*1000, set_dim) + elif state == "dim": + timeout = gobject.timeout_add(10*1000, set_off) + elif state == "insta-lock": + timeout = gobject.timeout_add(1000, set_off) + elif state == "off" and enable_suspend: + timeout = gobject.timeout_add(30*1000, set_suspend) + + set_ico_file() + +def set_dim(): + global state + global aux, power, screen + if aux.down_count() + power.down_count() + screen.down_count() > 0: + # button still down + set_timeout() + return + display.dim() + grab_all() + state = "dim" + set_timeout() + +def set_off(): + global state, dimtime + display.off() + state = "off" + set_timeout() + dimtime = 15 + +def read_num(filename, default = 0, sep = None): + try: + f = open(filename) + except: + f = [ "%d" % default ] + num = default + for l in f: + l = l.split(sep)[0].strip() + try: + num = float(l) + break + except: + num = default + return num + +#Active Internet connections (w/o servers) +#Proto Recv-Q Send-Q Local Address Foreign Address State +#tcp 0 48 192.168.2.202:22 192.168.2.200:34244 ESTABLISHED +#tcp 0 0 192.168.2.202:22 192.168.2.200:41473 ESTABLISHED +def external_tcp(): + # check for TCP connections to external computers. + netstat = Popen(['netstat','-nt'], stdout = PIPE, close_fds = True) + for l in netstat.stdout: + l = l.strip() + f = l.split() + if f[0] != "tcp" or f[5] != 'ESTABLISHED': + continue + a = f[4].split(':') + if a[0] != "127.0.0.1": + return True + return False + +def set_suspend(): + global state, display + # Check for lock file + try: + f = open("/var/run/suspend_disabled", "r+") + except: + f = None + if f: + try: + fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) + except: + set_timeout() + return + + # Check for loadavg > 0.5 + load = read_num("/proc/loadavg") + if load > 0.5: + set_timeout() + return + + # Check for USB power, at least 500mA + current = read_num("/sys/class/i2c-adapter/i2c-0/0-0073/pcf50633-mbc/usb_curlim") + if current >= 500: + set_timeout() + return + + #if external_tcp(): + # set_timeout() + # return + + os.system("apm -s") + if f: + f.close() + state = "full" + set_timeout() + display.on() + +def wake_all(down_cnt, *rest): + global state, dimtime + #print "wake all" + display.on() + if down_cnt == 0: + release_all() + if state == "dim" and dimtime < 120: + dimtime += 15 + if state != "disable": + state = "full" + set_timeout() + +def wake_dim(down_cnt, *rest): + global state + #print "wake_dim" + if state == "dim" or state == "full": + wake_all(down_cnt) + + +ico_file = None +def set_ico_file(): + global state, ico_file, ico + if state == "disable": + file = "lock-no.png" + elif state == "full": + if enable_suspend: + file = "lock-un.png" + else: + file = "lock-un-nosusp.png" + else: + if enable_suspend: + file = "lock.png" + else: + file = "lock-nosusp.png" + if file != ico_file: + ico.set_from_file("/usr/local/pixmaps/" + file) + ico_file = file + +last_ping = 0 +prev_ping = 0 +def ping(icon): + global state, enable_suspend, last_ping, prev_ping + if time.time() - prev_ping < 0.8: + grab_all() + state = "insta-lock" + elif state == "disable": + enable_suspend = False + state = "full" + elif not enable_suspend: + enable_suspend = True + state = "full" + else: + state = "disable" + prev_ping = last_ping + last_ping = time.time() + set_timeout() + +def main(): + global display, ico + global screen, power, aux + aux = EvDev("/dev/input/event4", wake_all) + power = EvDev("/dev/input/event0", wake_all) + screen = EvDev("/dev/input/event1", wake_dim) + state = "full" + display = Screen() + display.on() + ico = gtk.StatusIcon() + set_timeout() + ico.connect("activate", ping) + + gtk.main() + +main() diff --git a/lock/lock.xcf b/lock/lock.xcf new file mode 100644 index 0000000..92462fc Binary files /dev/null and b/lock/lock.xcf differ