import evdev from bureau import Bureau KEYS = { 0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', 10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'\b', 15: u'\t', 16: u'q', 17: u'w', 18: u'e', 19: u'r', 20: u't', 21: u'y', 22: u'u', 23: u'i', 24: u'o', 25: u'p', 26: u'[', 27: u']', 28: u'\n', 29: u'LCTRL', 30: u'a', 31: u's', 32: u'd', 33: u'f', 34: u'g', 35: u'h', 36: u'j', 37: u'k', 38: u'l', 39: u';', 40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'z', 45: u'x', 46: u'c', 47: u'v', 48: u'b', 49: u'n', 50: u'm', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT' } class TypingPool(Bureau): """ The typing pool is the bureau that converts keyboard, barcode scanner, etc. input to messages and sends them to the responsible bureau. """ name = "Typing Pool" prefix = "TY" version = 0 def __init__(self): Bureau.__init__(self) devices = map(evdev.InputDevice, evdev.list_devices()) self.devices = [] self.active_devices = [] devindex = {} # add anything that smells like a keyboard for dev in devices: devkey = format(dev.info.vendor, '04x') + ":" +\ format(dev.info.product, '04x') devindex[devkey] = dev try: if evdev.ecodes.KEY_A in dev.capabilities()[evdev.ecodes.EV_KEY]: print("usb device:", dev.info) print(dev.fn) self.devices.append(dev) except KeyError as err: print("ignoring non-keyboard device: " + str(dev)) # if we don't have any active KB so tell the user to config one if "active" in self.config: # self.active_devices = list(map(evdev.InputDevice, # self.config["active"]["devices"].split())) cfg_devs = self.config["active"]["devices"].split() print("trying to grab keyboard devs:", cfg_devs) print("device index", devindex) for dev in cfg_devs: if dev in devindex: self.active_devices.append(devindex[dev]) else: print("you need to configure input hardware!") print("add one of the following devices to TY.ini under [active]") print(" devices = 0c45:7403 ") print("available keyboard devices:") for dev in self.devices: print(dev.fn, ":", dev.name, format(dev.info.vendor, '04x') + ":" + format(dev.info.product, '04x')) def run_io(self): val = "" upper = False ctrl = False #TODO: this is crap, needs to be multi-threaded and have one # such loop for each active device self.active_devices[0].grab() # TODO: this is a bit messy / complex. break into one more function. for ev in self.active_devices[0].read_loop(): if ev.type == evdev.ecodes.EV_KEY: data = evdev.categorize(ev) if data.keystate == 1: # key-down if data.scancode == 28: print("sending barcode:", val) self.send(val[0:2], val[2:]) val = "" else: try: new_key = KEYS[data.scancode] if ctrl and (new_key == "j"): self.log.debug("ignoring line-feed") elif new_key == "LSHFT" or new_key == "RSHFT": upper = True elif new_key == "LCTRL" or new_key == "RCTRL": ctrl = True else: if upper: new_key = new_key.upper() val += new_key except KeyError: print("Error invalid keycode:", data.scancode) if data.keystate == 0: # key-up for mod-keys try: new_key = KEYS[data.scancode] if new_key == "LSHFT" or new_key == "RSHFT": upper = False if new_key == "LCTRL" or new_key == "RCTRL": ctrl = False except KeyError: print("Error invalid keycode:", data.scancode) def main(): evd = TypingPool() evd.run() if __name__ == "__main__": evd = TypingPool() evd.run()