Basic cloning & config.

Also fixed a few bugs and added a few features.
This commit is contained in:
Merlijn Wajer 2013-04-21 01:46:44 +02:00
parent c8e7b07805
commit 98fdbecccf
4 changed files with 122 additions and 46 deletions

View File

@ -68,7 +68,10 @@ class InputDevice(object):
def get_name(self):
return get_input_name(self._f)
# TODO: Maybe do not export keys?
def get_exposed_events(self):
"""
"""
d = dict()
for k, v in events.iteritems():
l = get_keys(self._f, v)
@ -76,7 +79,7 @@ class InputDevice(object):
d[k] = []
for ev in l:
try:
d[k].append(event_keys[v][ev])
d[k].append(rev_event_keys[v][ev])
except KeyError:
pass
@ -91,7 +94,8 @@ class InputDevice(object):
def __del__(self):
os.close(self._f)
if hasattr(self, '_f'):
os.close(self._f)
def open_uinput():
@ -105,15 +109,10 @@ def open_uinput():
return None
return f
def write_uinput_device_info(name):
def write_uinput_device_info(f, name):
"""
Create uinput device
"""
f = open_uinput()
if not f:
print 'Failed to open uinput'
return None
# Add keys, etc
#handle_specs(f, specs)
@ -142,22 +141,28 @@ def free_uinput_device(f):
class UInputDevice(object):
def __init__(self, name, specs):
# TODO: Other methods for specs etc
# TODO: Maybe don't create the device yet; add a seperate method?
# TODO: Take inspiration from the config.h files ! Also allow using
# direct methods / programming it rather than just the dict as config
self._f = write_uinput_device_info(name)
def __init__(self):
self._f = open_uinput()
if not self._f:
print 'Failed to open uinput'
raise OSError
def expose_event(evt, evk):
evbit = evbits[ev]
def setup(self, name):
write_uinput_device_info(self._f, name)
def expose_event_type(self, evt):
fcntl.ioctl(self._f, UI_SET_EVBIT, evt)
def expose_event(self, evt, evk):
evbit = evbits[evt]
fcntl.ioctl(self._f, evbit, evk)
def fire_event(ev):
def fire_event(self, ev):
"""
"""
os.write(self._f, buffer(ev)[:])
def __del__(self):
free_uinput_device(self._f)
if hasattr(self, '_f'):
free_uinput_device(self._f)

View File

@ -1,19 +1,89 @@
import linux_uinput, ctypes, fcntl, os
import linux_uinput, ctypes, fcntl, os, sys
from cinput import *
def handle_specs(f, s):
print 'ioctl:', fcntl.ioctl(f, UI_SET_EVBIT, EV_KEY)
print 'ioctl:', fcntl.ioctl(f, UI_SET_KEYBIT, KEY_UP)
clone = True
passthrough = lambda x: -x*2
config = {
EV_REL : {
REL_X : {
'type' : EV_REL,
'code' : REL_X,
'value': passthrough
},
REL_Y : {
'type': EV_REL,
'code': REL_Y,
'value' : passthrough
}
},
EV_KEY : {
BTN_LEFT : {
'type' : EV_KEY,
'code' : BTN_LEFT,
'value' : passthrough
}
}
}
d = UInputDevice('Example input device', None)
f = InputDevice(sys.argv[1] if len(sys.argv) == 2 else "/dev/input/event3")
import time
time.sleep(5)
d = UInputDevice()
if clone:
e = f.get_exposed_events()
for k, v in e.iteritems():
t = events[k]
if t == EV_SYN:
continue
d.expose_event_type(t)
for key in v:
tt = event_keys[t][key]
d.expose_event(t, tt)
print k + ':', ', '.join(v)
else:
for evt, v in config.iteritems():
for code, dat in v.iteritems():
d.expose_event_type(dat['type'])
d.expose_event(dat['type'], dat['code'])
d.setup('Example input device' )
def map_ev(ev):
_type = ev.type
if _type in config:
typemaps = config[_type]
if ev.code in typemaps:
info = typemaps[ev.code]
ev.type = info['type']
ev.code = info['code']
ev.value = info['value'](ev.value)
return ev
while True:
ev = f.next_event()
if not clone:
ev = map_ev(ev)
d.fire_event(ev)
try:
#print ev.time.tv_sec, ev.time.tv_usec
s = '%s %s %d' % (rev_events[ev.type], rev_event_keys[ev.type][ev.code], ev.value)
print 'Event type:', s
except KeyError:
pass
# Config
dev = {
"input_devices" : [

View File

@ -7,7 +7,6 @@ from gen import input_constants_dict as icd
for k, v in icd.iteritems():
locals()[k] = v
rdict = lambda x: dict(map(lambda (k, v): (v, k), x.iteritems()))
events = dict(filter(lambda (k, v): k in ["EV_SYN", "EV_KEY", "EV_REL",
@ -15,20 +14,6 @@ events = dict(filter(lambda (k, v): k in ["EV_SYN", "EV_KEY", "EV_REL",
"EV_FF", "EV_PWR", "EV_FF_STATUS"], icd.iteritems()))
rev_events = rdict(events)
# event sets
"""
static const char * const * const names[EV_MAX + 1] = {
[0 ... EV_MAX] = NULL,
[EV_SYN] = events, [EV_KEY] = keys,
[EV_REL] = relatives, [EV_ABS] = absolutes,
[EV_MSC] = misc, [EV_LED] = leds,
[EV_SND] = sounds, [EV_REP] = repeats,
[EV_SW] = switches,
[EV_FF] = force, [EV_FF_STATUS] = forcestatus,
};
"""
filter_event = lambda c: dict(filter(lambda (k, v): c(k), icd.iteritems()))
keys = filter_event(lambda x: x.startswith("KEY_") or x.startswith("BTN_"))
@ -58,11 +43,28 @@ rev_repeats = rdict(repeats)
switches = filter_event(lambda x: x.startswith("SW_"))
rev_switches = rdict(switches)
del rdict
force, forcestatus = {}, {}
rev_force = rdict(force)
rev_forcestatus = rdict(forcestatus)
del rdict
event_keys = {
EV_SYN: syn,
EV_KEY: keys,
EV_REL: rel,
EV_ABS: absaxes,
EV_MSC: misc,
EV_LED: leds,
EV_SND: sounds,
EV_REP: repeats,
EV_SW: switches,
EV_FF: force,
EV_FF_STATUS: forcestatus
}
rev_event_keys = {
EV_SYN: rev_syn,
EV_KEY: rev_keys,
EV_REL: rev_rel,
@ -72,11 +74,10 @@ event_keys = {
EV_SND: rev_sounds,
EV_REP: rev_repeats,
EV_SW: rev_switches,
EV_FF: force,
EV_FF_STATUS: forcestatus
EV_FF: rev_force,
EV_FF_STATUS: rev_forcestatus
}
class timeval(ctypes.Structure):
_fields_ = [("tv_sec", ctypes.c_long), ("tv_usec", ctypes.c_long)]

View File

@ -18,7 +18,7 @@ while True:
try:
print ev.time.tv_sec, ev.time.tv_usec
s = '%s %s %d' % (rev_events[ev.type], event_keys[ev.type][ev.code], ev.value)
s = '%s %s %d' % (rev_events[ev.type], rev_event_keys[ev.type][ev.code], ev.value)
print 'Event type:', s
except KeyError:
pass