From: NeilBrown Date: Sat, 21 Apr 2012 11:42:50 +0000 (+1000) Subject: Add evdev.py X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=b1f49cd7d7c1a5f07dcde9be0bd94fb5b07cc5ea;p=plato.git Add evdev.py evdev monitors /dev/input/event* (event devices) and calls a callback on each event. It allows 'grabbing' of devices too Signed-off-by: NeilBrown --- diff --git a/lib/evdev.py b/lib/evdev.py new file mode 100644 index 0000000..fa7e302 --- /dev/null +++ b/lib/evdev.py @@ -0,0 +1,87 @@ +# Copyright (C) 2011-2012 Neil Brown +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import gobject, os, struct, fcntl + + +EVIOCGRAB = 0x40044590 +def EVIOCGKEY(len): + return 0x80004518 + len * 65536 + +class EvDev: + def __init__(self, path, on_event, arg=None): + 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.arg = arg + 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: + self.downlist.remove(code) + else: + # 'down' - add to downlist + if code not in self.downlist: + # ignore the 'play' butten (headphone insert) + if code != 207: + self.downlist.append(code) + moment = sec + float(usec)/1000000 + self.on_event(self.down_count(), moment, typ, code, value) + return True + def down_count(self): + if len(self.downlist) == 0: + return 0 + # double check, we might have missed an 'up' event somehow. + try: + rv = fcntl.ioctl(self.f, EVIOCGKEY(768/8), (768/8) * " " ) + l = len(rv)/4 + ra = struct.unpack('%dI' % l, rv) + isup = [] + for k in self.downlist: + by = int(k/8) + bt = k % 8 + if by < l and ((ra[by] >> bt) & 1) == 0: + isup.append[k] + for k in isup: + self.downlist.remove(k) + except: + pass + return len(self.downlist) + + def grab(self): + if self.grabbed: + return + #print "grab" + fcntl.ioctl(self.f, EVIOCGRAB, 1) + self.grabbed = True + def ungrab(self): + if not self.grabbed: + return + #print "release" + fcntl.ioctl(self.f, EVIOCGRAB, 0) + self.grabbed = False