diff --git a/py/cinput.py b/py/cinput.py index 7d85531..992b856 100644 --- a/py/cinput.py +++ b/py/cinput.py @@ -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) diff --git a/py/create.py b/py/create.py index 87acab3..cac6525 100644 --- a/py/create.py +++ b/py/create.py @@ -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" : [ diff --git a/py/linux_input.py b/py/linux_input.py index e4f1b2c..85fc091 100644 --- a/py/linux_input.py +++ b/py/linux_input.py @@ -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)] diff --git a/py/read.py b/py/read.py index c857e0e..1847ca1 100644 --- a/py/read.py +++ b/py/read.py @@ -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