diff --git a/cinput.py b/cinput.py index 24e6a66..c67184c 100644 --- a/cinput.py +++ b/cinput.py @@ -90,7 +90,7 @@ class InputDevice(object): return copy_event(estr) def get_fd(self): - return fd + return self._f def __del__(self): diff --git a/input-read b/input-read index 965ead8..cb2a60e 100755 --- a/input-read +++ b/input-read @@ -1,7 +1,9 @@ #!/usr/bin/env python import linux_uinput, ctypes, fcntl, os, sys +import select + from cinput import * -from mapper import KeyMapper, parse_conf +from mapper import KeyMapper, parse_conf, pretty_conf_print try: import cPickle as pickle @@ -27,46 +29,71 @@ if len(input_file) == 0: parser.print_help() exit(0) -# TODO: Support multiple input files + epoll; InputDevices? -f = InputDevice(input_file[0]) +fs = map(InputDevice, input_file) -config = parse_conf(f) -m = KeyMapper(config) +config = {} +for idx, f in enumerate(fs): + c = parse_conf(f, idx) + + config.update(c) + +pretty_conf_print(config) + +p = select.epoll() +for f in fs: + p.register(f.get_fd(), select.EPOLLIN) if args.dump: - print 'Version:', f.get_version() - print f.get_name() + for f in fs: + print 'Version:', f.get_version() + print f.get_name() - d = f.get_exposed_events() - for k, v in d.iteritems(): - print k + ':', ', '.join(v) + d = f.get_exposed_events() + for k, v in d.iteritems(): + print k + ':', ', '.join(v) else: p = pickle.Pickler(sys.stdout) + p.dump(len(fs)) + p.dump(config) sys.stdout.flush() +i = 0 while True: - # TODO: Poll multiple files ; add file description (not descriptor...) - # f, ev = fs.next_event() - ev = f.next_event() + events = p.poll() - if args.dump: - 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 + for e in events: + fd, ev_mask = e + + if not ev_mask & select.EPOLLIN: + continue + + # Lets undo that epoll speedup ;-) + for idx, _ in enumerate(fs): + if _.get_fd() == fd: + f = _ + i = idx + + ev = f.next_event() + + if args.dump: + try: + print i, 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 - else: - if not args.compat: - p.dump(ev) else: - # Use this rather than the line above if you use an old python version (also - # edit create.py) - p.dump((ev.time.tv_sec, ev.time.tv_usec, ev.type, ev.code, ev.value)) + if not args.compat: + p.dump((i, ev)) + else: + # Use this rather than the line above if you use an old python version (also + # edit create.py) + p.dump((i, (ev.time.tv_sec, ev.time.tv_usec, ev.type, ev.code, + ev.value))) - sys.stdout.flush() + sys.stdout.flush() diff --git a/mapper.py b/mapper.py index 14926a4..fe95688 100644 --- a/mapper.py +++ b/mapper.py @@ -1,7 +1,8 @@ +# encoding: utf-8 import cinput # XXX: Also parse name, etc -def parse_conf(f): +def parse_conf(f, devname): conf = {} e = f.get_exposed_events() for k, v in e.iteritems(): @@ -9,12 +10,12 @@ def parse_conf(f): if t == cinput.EV_SYN: continue - conf[t] = {} + conf[(devname, t)] = {} for key in v: tt = cinput.event_keys[t][key] - conf[t][tt] = { - 'type' : t, + conf[(devname, t)][tt] = { + 'type' : (devname, t), 'code' : tt, 'value' : None #'value' : lambda x: x @@ -22,6 +23,19 @@ def parse_conf(f): return conf + +def pretty_conf_print(c): + for k, v in c.iteritems(): + print 'Input:', k[0], 'Type:', cinput.rev_events[k[1]] + for kk, vv in v.iteritems(): + n_ev_d, n_ev_t = vv['type'] + print ' ' * 4, + print cinput.rev_event_keys[k[1]][kk], + print ' → ([%d, %s], %s)' % (n_ev_d, + cinput.rev_events[n_ev_t], + cinput.rev_event_keys[n_ev_t][vv['code']]) + + class KeyMapper(object): def __init__(self, config): self._config = config