|
|
|
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()
|