ioctl work ; reading keys works.

This commit is contained in:
Merlijn Wajer 2013-04-18 18:13:57 +02:00
parent 9c5c57a7eb
commit 4eb6a0f1d4
3 changed files with 142 additions and 2 deletions

37
py/ioctlhelp.py Normal file
View File

@ -0,0 +1,37 @@
# See linux/include/uapi/asm-generic/ioctl.h
import struct
_IOC_NRBITS = 8
_IOC_TYPEBITS = 8
# According to linux these *may* be architecture specific
_IOC_SIZEBITS = 14
_IOC_DIRBITS = 2
_IOC_NRMASK = (1 << _IOC_NRBITS) - 1
_IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1
_IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1
_IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1
_IOC_NRSHIFT = 0
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS
_IOC_NONE = 0
_IOC_WRITE = 1
_IOC_READ = 2
def IOC(_dir, _type, nr, size):
if type(size) in (str, unicode):
size = struct.calcsize(size)
return _dir << _IOC_DIRSHIFT | _type << _IOC_TYPESHIFT | \
nr << _IOC_NRSHIFT | size << _IOC_SIZESHIFT
IO = lambda _type, nr: IOC(_IOC_NONE, _type, nr, 0)
IOR = lambda _type, nr, size: IOC(_IOC_READ, _type, nr, size)
IOW = lambda _type, nr, size: IOC(_IOC_WRITE, _type, nr, size)
IORW = lambda _type, nr, size: IOC(_IOC_READ | _IOC_WRITE, _type, nr, size)

View File

@ -20,3 +20,78 @@ class input_event(ctypes.Structure):
("value", ctypes.c_int32)
]
from ioctlhelp import IOR, IOW, IOC, IO, _IOC_READ
# Get driver version
EVIOCGVERSION = IOR(ord('E'), 0x01, '@i')
# Get device ID
#EVIOCGID = IOR(ord('E'), 0x02, struct input_id)
# Get repeat settings
EVIOCGREP = IOR(ord('E'), 0x03, '@ii')
# Set repeat settings
EVIOCSREP = IOW(ord('E'), 0x03, '@ii')
# Get keycode
EVIOCGKEYCODE = IOR(ord('E'), 0x04, '@ii')
# EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
# Set keycode
EVIOCSKEYCODE = IOW(ord('E'), 0x04, '@ii')
#EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
# Get device name
EVIOCGNAME = lambda _len: IOC(_IOC_READ, ord('E'), 0x06,
struct.calcsize('%ds' % _len))
# Get physical location
EVIOCGPHYS= lambda _len: IOC(_IOC_READ, ord('E'), 0x07,
struct.calcsize('%ds' % _len))
# Get unique identifier
EVIOCGUNIQ = lambda _len: IOC(_IOC_READ, ord('E'), 0x08,
struct.calcsize('%ds' % _len))
# Get device properties
EVIOCGPROP = lambda _len: IOC(_IOC_READ, ord('E'), 0x09,
struct.calcsize('%ds' % _len))
#EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
#
#EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
#EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
#EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
#EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
# Get event bits
EVIOCGBIT = lambda ev, _len: IOC(_IOC_READ, ord('E'), 0x20 + ev, _len)
#EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
#
#EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
#EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#
#EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
#
#EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
import array, struct, fcntl
def get_input_version(f):
buf = array.array('i', [0])
r = fcntl.ioctl(f, EVIOCGVERSION, buf)
v = struct.unpack('@i', buf)[0]
del r
return "%d.%d.%d" % ( v >> 16, (v >> 8) & 0xff, v & 0xff)
def get_input_name(f, l=256):
buf = array.array('c', ' ' * l)
r = fcntl.ioctl(f, EVIOCGNAME(l), buf)
v = struct.unpack('%ds' % l, buf)
del r
return v

View File

@ -3,7 +3,35 @@ import ctypes
import sys
f = open(sys.argv[1] if len(sys.argv) == 2 else "/dev/input/event8")
f = open(sys.argv[1] if len(sys.argv) == 2 else "/dev/input/event3")
print 'Version:', cinput.get_input_version(f)
print cinput.get_input_name(f)
print cinput.EVIOCGBIT(0, cinput.EV_MAX)
import struct, array, fcntl
bpl = struct.calcsize('@L') * 8
nbits = lambda x: ((x-1) / bpl) + 1
ll = nbits(cinput.KEY_MAX)
test_bit = lambda j, v: (v[j / bpl] >> (j % bpl)) & 1
#for b in xrange(cinput.EV_MAX):
for b in xrange(1, 2):
buf = array.array('L', [0L] * ll)
print 'ioctl return:', fcntl.ioctl(f, cinput.EVIOCGBIT(b, cinput.KEY_MAX), buf)
v = struct.unpack('@%dL' % ll, buf)
print v
for j in range(0, cinput.KEY_MAX):
if test_bit(j, v):
print cinput.rev_keys[j]
del buf
while True:
estr = f.read(ctypes.sizeof(cinput.input_event))
@ -15,4 +43,4 @@ while True:
try:
print 'Code:', cinput.event_keys[ev.type][ev.code]
except KeyError:
pass
pass