45 import os, struct, time, fcntl
47 from collections
import deque
56 SIZEOF_INT2 = struct.calcsize(INT2)
59 from ioctl
import _IOC, _IO, _IOW, _IOR, _IOC_READ
62 EVIOCGVERSION = _IOR(69, 0x01, INT)
63 EVIOCGID = _IOR(69, 0x02, SHORT4)
64 EVIOCGREP = _IOR(69, 0x03, INT2)
65 EVIOCSREP = _IOW(69, 0x03, INT2)
66 EVIOCGKEYCODE = _IOR(69, 0x04, INT2)
67 EVIOCSKEYCODE = _IOW(69, 0x04, INT2)
68 EVIOCGKEY = _IOR(69, 0x05, INT2)
69 EVIOCGNAME = _IOC(_IOC_READ, 69, 0x06, 255)
70 EVIOCGPHYS = _IOC(_IOC_READ, 69, 0x07, 255)
71 EVIOCGUNIQ = _IOC(_IOC_READ, 69, 0x08, 255)
72 EVIOCRMFF = _IOW(69, 0x81, INT)
73 EVIOCSGAIN = _IOW(69, 0x82, USHORT)
74 EVIOCSAUTOCENTER= _IOW(69, 0x83, USHORT)
75 EVIOCGEFFECTS = _IOR(69, 0x84, INT)
76 EVIOCGRAB = _IOW(69, 0x90, INT)
86 return _IOC(_IOC_READ, 69, 0x20 + evtype, len)
90 return _IOR(69, 0x40 + abs, INT5)
94 return _IOC(_IOC_READ, 69, 0x1b, len)
98 return _IOC(_IOC_READ, 69, 0x19, len)
108 EVsize = struct.calcsize(EVFMT)
132 EV_KEY:
"Keys or Buttons",
133 EV_REL:
"Relative Axes",
134 EV_ABS:
"Absolute Axes",
135 EV_MSC:
"Miscellaneous",
140 EV_FF:
"Force Feedback",
141 EV_PWR:
"Power Management",
142 EV_FF_STATUS:
"Force Feedback Status",
149 return (self.
_bits >> EV_KEY) & 1
152 return (self.
_bits >> EV_LED) & 1
155 return (self.
_bits >> EV_SND) & 1
158 return (self.
_bits >> EV_REL) & 1
161 return (self.
_bits >> EV_ABS) & 1
164 return (self.
_bits >> EV_MSC) & 1
167 return (self.
_bits >> EV_SW) & 1
170 return (self.
_bits >> EV_REP) & 1
173 return (self.
_bits >> EV_FF) & 1
176 return (self.
_bits >> EV_FF_STATUS) & 1
179 return (self.
_bits >> EV_PWR) & 1
184 for bit
in (EV_KEY, EV_REL, EV_ABS, EV_MSC, EV_SW, EV_LED, EV_SND, EV_REP, EV_FF, EV_PWR, EV_FF_STATUS):
185 if (bits >> bit) & 1:
195 for bit, name
in self.NAMES.items():
196 if (bits >> bit) & 1:
207 def __init__(self, time=0.0, evtype=0, code=0, value=0):
214 return "Event:\n time: %f\n evtype: 0x%x\n code: 0x%x\n value: 0x%x\n" % \
218 tv_sec, tv_usec = divmod(self.
time, 1.0)
219 return struct.pack(EVFMT, long(tv_sec), long(tv_usec * 1000000.0), self.
evtype, self.
code, self.
value)
222 tv_sec, tv_usec, self.
evtype, self.
code, self.
value = struct.unpack(EVFMT, ev)
223 self.
time = float(tv_sec) + float(tv_usec) / 1000000.0
225 def set(self, evtype, code, value):
226 self.
time = time.time()
228 self.
code = int(code)
229 self.
value = int(value)
236 self.
_fo = open(fname, mode)
245 return self._eventq.pop()
254 raw = self._fo.read(EVsize * 32)
256 for i
in xrange(len(raw) / EVsize):
258 ev.decode(raw[i * EVsize:(i + 1) * EVsize])
259 self._eventq.push(ev)
279 if self.
idbus is None:
281 return "%s: bus=0x%x, vendor=0x%x, product=0x%x, version=0x%x\n %s" % \
287 raw = os.read(self.
_fd, EVsize * 32)
292 for i
in range(len(raw) / EVsize):
294 ev.decode(raw[i * EVsize:(i + 1) * EVsize])
295 self._eventq.push(ev)
297 def find(self, start=0, name=None):
299 assert name
is not None,
"EventDevice: no name to find"
300 for d
in range(start, 16):
301 filename =
"/dev/input/event%d" % (d,)
302 if os.path.exists(filename):
305 except (OSError, IOError):
308 if name
in self.
name:
311 raise IOError(
"Input device %r not found." % (name,))
314 self.
_fd = os.open(filename, os.O_RDWR)
315 name = fcntl.ioctl(self.
_fd, EVIOCGNAME, chr(0) * 256)
316 self.
name = name.replace(chr(0),
'')
322 if self.
_fd is not None:
330 return self._eventq.pop()
338 def write(self, evtype, code, value):
339 ev =
Event(0.0, evtype, code, value)
340 return os.write(self.
_fd, ev.encode())
343 ver = fcntl.ioctl(self.
_fd, EVIOCGVERSION,
'\x00\x00\x00\x00')
344 return struct.unpack(INT, ver)[0]
347 ver = fcntl.ioctl(self.
_fd, EVIOCGID,
'\x00\x00\x00\x00\x00\x00\x00\x00')
352 caps = fcntl.ioctl(self.
_fd,
EVIOCGBIT(0),
'\x00\x00\x00\x00')
353 caps = struct.unpack(INT, caps)[0]
357 return bool(self.
_fd)
386 for d
in range(start, 16):
387 filename =
"/dev/input/event%d" % (d,)
388 if os.path.exists(filename):
390 fd = os.open(filename, os.O_RDWR)
392 name = fcntl.ioctl(fd, EVIOCGNAME, chr(0) * 256)
395 name = name.replace(chr(0),
'')
396 except (OSError, IOError):
399 names.append((d, name))
405 for d
in range(start, 16):
406 filename =
"/dev/input/event%d" % (d,)
407 if os.path.exists(filename):