示例#1
0
async def tcp_client():
    reader, writer = await asyncio.open_connection(srv, 8888)
    writer.write(pickle_data(["client_devices", devs]))
    while True:
        try:
            data = unpickle_data(await reader.readline())
        except EOFError:
            print("Connection lost...")
            break
        if data[0] == "srv_dev":
            address = writer.get_extra_info('peername')
            address_dns = socket.gethostbyaddr(address[0])
            device = data[2]
            cap = device.capabilities()
            del cap[0]
            devices.append(
                evdev.UInput(cap,
                             name=device.name + f' (via {address_dns[0]})',
                             vendor=device.info.vendor,
                             product=device.info.product))
            print(f"Created UInput device {device.name} (via {srv})")
        if data[0] == "srv_dev_event":
            if not data[0]:
                break
            devices[data[1]].write_event(data[2])
示例#2
0
def main():
    """
        Handles events for all keyboard devices.
    """

    #Create a virtual keyboard device, which will be used to _send_ the resultant key-presses.
    output_device = evdev.UInput(events=None, name='Vim-Clutch Foot-Pedal')

    #And get a list of all foot-pedal devices which should be monitored for events.
    input_devices = compatible_devices()

    #Create generic press and release handlers which are closed over the output device.
    press_callback = lambda input_device, event : press_handler(output_device, input_device, event)
    release_callback = lambda input_device, event : release_handler(output_device, input_device, event)

    #For each foot-pedal detected.
    for device in input_devices:

        #Attain sole ownership of the device, so its events don't populate back up to X.
        device.grab()

        #And register handlers for the device's events.
        ClutchEventDispatcher(device, press_callback, release_callback)

    #Add a handler which releases devices on SIGTERM.
    signal.signal(signal.SIGTERM, lambda : cleanup(output_device, input_devices))

    #And loop indefinitely, handling "asynchronous" press events.
    try:
        asyncore.loop()

    #Allow the program to be closed by CTRL+C.
    except KeyboardInterrupt:
        cleanup(output_device, input_devices)
示例#3
0
def main():
    with evdev.UInput(
        evdev.util.find_ecodes_by_regex(r"KEY_([A-Z0-9]|SPACE|LEFTSHIFT|ENTER)$")
    ) as ui:
        escape = False
        for letter in sys.argv[1]:
            if letter == " ":
                key = evdev.ecodes.KEY_SPACE
            elif letter == "\\":
                escape = True
                continue
            elif escape and letter == "r":
                escape = False
                key = evdev.ecodes.KEY_ENTER
            else:
                key = evdev.ecodes.ecodes["KEY_" + letter.upper()]
            if letter.isupper():
                ui.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 1)

            ui.write(evdev.ecodes.EV_KEY, key, 1)
            ui.write(evdev.ecodes.EV_KEY, key, 0)
            time.sleep(0.05)
            ui.syn()

            if letter.isupper():
                ui.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 0)
        ui.syn()
示例#4
0
    def __init__(self, mouse, keyboards, **kwargs):
        self.mouse = evdev.InputDevice(mouse)
        self.keyboards = [evdev.InputDevice(kbd) for kbd in keyboards]
        self.mouse.grab()

        #get mouse capabilities to forward to absolute device
        caps = self.mouse.capabilities()
        del caps[evdev.ecodes.EV_SYN]

        #modify capabilities to delete relative axes and add absolute axes
        caps[enums.EV_REL].remove(enums.REL_X)
        caps[enums.EV_REL].remove(enums.REL_Y)
        caps[enums.EV_ABS] = [(enums.ABS_X, (0, 0, resolution[0], 0, 0, 0)),
                              (enums.ABS_Y, (0, 0, resolution[1], 0, 0, 0))]

        #merge keyboard and mouse capabilities for transfer
        self.capabilities = dict(caps)
        for kbd in self.keyboards:
            kcap = kbd.capabilities()
            for k, v in kcap.items():
                if k == evdev.ecodes.EV_SYN:
                    continue
                elif k not in self.capabilities:
                    self.capabilities[k] = v
                else:
                    self.capabilities[k].extend(v)

        self.dev = evdev.UInput(caps)

        super(LinuxServer, self).__init__(resolution, **kwargs)
示例#5
0
def main():
    logging.basicConfig(level=logging.INFO)

    rules = [Rule.from_string(s) for s in DEFAULT_RULES]
    assert len(rules) > 0
    rules_by_last_event = {}
    for rule in rules:
        key = rule.patterns[-1]
        rules_by_last_event.setdefault(key, []).append(rule)

    uinput = evdev.UInput(name='evcape', phys='evcape')
    logger.info("created uinput device {0.device.fn}".format(uinput))

    keyboard_monitor = KeyboardMonitor(ignored_devices=[uinput.device.fn])

    # our buffer is as long as the longest sequence in rules
    window_size = max([len(rule.patterns) for rule in rules])
    buffer = collections.deque(maxlen=window_size)

    # put keypresses into a buffer and try to match rules
    with uinput, keyboard_monitor:
        for event in keyboard_monitor:
            lookup_key = (event.value, event.code)
            buffer.append(lookup_key)
            possibly_matching_rules = rules_by_last_event.get(lookup_key)
            if not possibly_matching_rules:
                continue
            for rule in possibly_matching_rules:
                buffer_slice = list(buffer)[-len(rule.patterns):]
                if rule.patterns != buffer_slice:
                    continue
                for value, code in rule.actions:
                    uinput.write(evdev.ecodes.EV_KEY, code, value)
                uinput.syn()
示例#6
0
def main():
    with evdev.UInput() as ui:
        escape = False
        for letter in sys.argv[1]:
            if letter == ' ':
                key = evdev.ecodes.KEY_SPACE
            elif letter == '\\':
                escape = True
                continue
            elif escape and letter == 'r':
                escape = False
                key = evdev.ecodes.KEY_ENTER
            else:
                key = evdev.ecodes.ecodes['KEY_' + letter.upper()]
            if letter.isupper():
                ui.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 1)

            ui.write(evdev.ecodes.EV_KEY, key, 1)
            ui.write(evdev.ecodes.EV_KEY, key, 0)
            time.sleep(.05)
            ui.syn()

            if letter.isupper():
                ui.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 0)
        ui.syn()
示例#7
0
 def __init__(self):
     self._fds = {}
     self._delayed = []
     self._logger = logging.getLogger()
     self._poll = None
     self._uinput = None
     try:
         signal.signal(signal.SIGHUP, signal.SIG_IGN)
         info = evmapy.util.get_app_info()
         app_with_user = (info['name'], info['user'].pw_name)
         # Create the control socket
         self._controller = evmapy.controller.Controller(self)
         # Try to open /dev/uinput, failing gracefully
         try:
             self._uinput = evdev.UInput(name='%s (%s)' % app_with_user)
         except evdev.uinput.UInputError as exc:
             self._logger.warning(
                 "injecting keypresses will not be possible: %s", str(exc))
         # Start processing events from all configured devices
         self._poll = select.poll()
         self._scan_devices()
         # Start monitoring the control socket
         self._fds[self._controller.fileno()] = self._controller
         self._poll.register(self._controller, select.POLLIN)
     except evmapy.controller.SocketInUseError:
         error_msg = "%s is already running as %s" % app_with_user
         self._logger.error(error_msg)
         exit(1)
     except:
         self._logger.exception("unhandled exception while initializing:")
         raise
示例#8
0
 async def connect(self, server):
     caps = await super(LinuxClient, self).connect(server, resolution)
     #caps may be None if user rejects server cert request
     if caps is not None:
         self.capabilities = dict((int(k), v) for k, v in caps.items())
         self.dev = evdev.UInput(self.capabilities)
         logger.debug(f'Received capabilities: {self.capabilities}')
         await self.handle_event()
示例#9
0
 def __init__(self, routes=None, double_click=-1):
     self.current_route = None
     self.routes = routes
     self.active = False
     self.double_click = int(double_click)
     if self.routes is None:
         self.routes = []
     self.ui = evdev.UInput()
示例#10
0
    def __init__(self):
        self.pulse = pulsectl.Pulse('nanokontrol')
        self.input = evdev.UInput()

        self.session_bus = dbus.SessionBus()
        self.gsproxy = self.session_bus.get_object('org.gnome.Shell',
                                                   '/org/gnome/Shell')
        self.gsinterface = dbus.Interface(self.gsproxy, 'org.gnome.Shell')
示例#11
0
 def press_power_button(self):
     """
     Simulate a power key press event
     """
     uinput = evdev.UInput(name='push-autopilot-power-button',
                           devnode='/dev/autopilot-uinput')
     # One press and release to turn screen off (locking unity)
     uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_POWER, 1)
     uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_POWER, 0)
     uinput.syn()
示例#12
0
def write_events(output_events):
    device = evdev.UInput({
        ecodes.EV_KEY: ecodes.keys,
        ecodes.EV_REL: [ecodes.REL_X, ecodes.REL_Y],
    }, name="apemouse")

    while True:
        for event in output_events.get():
            device.write(event.type, event.code, event.value)
        device.syn()
示例#13
0
    def make_uinput(name, device_config):
        # either predefined or custom
        try:
            capabilities = frankengamepad.config.PREDEFINED_CAPABILITIES[device_config["type"]]
        except KeyError:
            capabilities = {}  # TODO based on device_config["type"]["capabilities"]

        capabilities = {k: v for k, v in capabilities.items()
                if k not in {evdev.ecodes.EV_SYN, evdev.ecodes.EV_FF}}
        # Could set vendor etc but some games don't like it
        return evdev.UInput(capabilities, name=name)
示例#14
0
    def __init__(self, hw_kbd, hw_mouse, name, notify_key=None):
        self.name = name
        self.kbd = evdev.UInput.from_device(hw_kbd, name=f'{name}-virt-kbd')
        self.mouse = evdev.UInput(VirtualInputGroup.MOUSE_CAP, name=f'{name}-virt-mouse')
        self.notify_key = notify_key

        # active keys and mouse buttons
        self.active_keys = set()

        self.mouse_move_x = 0
        self.mouse_move_y = 0
 def mainloop(self):
     kodi_client = KodiClient(HOST, PORT)
     devices = get_mediakey_devices()
     with grab_all(devices):
         capabilities = all_capabilities(devices)
         with evdev.UInput(capabilities,
                           name='DElauncher4Kodi-uinput') as ui:
             self.ready.set()
             for event in self.read_events(devices):
                 if not kodi_client.handle_event(event):
                     ui.write_event(event)
                     ui.syn()
示例#16
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("rules",
                        nargs="*",
                        metavar="rule",
                        default=DEFAULT_RULES)
    parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT)
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO)

    timeout = args.timeout / 1000
    logger.info("using timeout {}ms".format(args.timeout))

    for s in args.rules:
        logger.info("adding rule {!r}".format(s))
    rules = [Rule.from_string(s) for s in args.rules]
    assert len(rules) > 0
    rules_by_last_event = {}
    for rule in rules:
        key = rule.patterns[-1]
        rules_by_last_event.setdefault(key, []).append(rule)

    uinput = evdev.UInput(name="evcape")
    logger.info("created uinput device {0.device.path}".format(uinput))

    keyboard_monitor = KeyboardMonitor(ignored_devices=[uinput.device.path])

    # the buffer is as long as the longest sequence in rules
    window_size = max([len(rule.patterns) for rule in rules])
    buffer = collections.deque(maxlen=window_size)

    # put keypresses into a buffer and try to match rules
    previous_event_timestamp = 0.0
    with uinput, keyboard_monitor:
        for event in keyboard_monitor:
            lookup_key = (event.value, event.code)
            buffer.append(lookup_key)
            ts_diff = event.timestamp() - previous_event_timestamp
            previous_event_timestamp = event.timestamp()
            if ts_diff >= timeout:
                continue
            possibly_matching_rules = rules_by_last_event.get(lookup_key)
            if not possibly_matching_rules:
                continue
            for rule in possibly_matching_rules:
                offset = -len(rule.patterns)
                buffer_slice = list(buffer)[offset:]
                if rule.patterns != buffer_slice:
                    continue
                for value, code in rule.actions:
                    uinput.write(evdev.ecodes.EV_KEY, code, value)
                uinput.syn()
示例#17
0
def run():
    print('This program tests uinput by typing "catCAT"')

    ui = evdev.UInput()
    write(ui, 'cat')
    print("Pressing KEY_LEFTSHIFT")
    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, KEY_PRESS)
    write(ui, 'cat')
    print("Releasing KEY_LEFTSHIFT")
    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, KEY_RELEASE)
    ui.syn()
    ui.close()
def main():
    """
        Handles events for all keyboard devices.
    """

    #Create a virtual keyboard device, which will be used to _send_ the resultant key-presses.
    output_device = evdev.UInput(events=None, name='Emacs-Clutch Foot-Pedal')

    #And get a list of all foot-pedal devices which should be monitored for events.
    input_devices = compatible_devices()

    #Create generic press and release handlers which are closed over the output device.
    press_callback = lambda input_device, event: press_handler(
        output_device, input_device, event)
    release_callback = lambda input_device, event: release_handler(
        output_device, input_device, event)

    #For each foot-pedal detected.
    #TODO: review if it matters that it is looking for more than one device to
    #      grab, when [usually] we will only want to use 1 pedal;
    #      and if we have more than one pedal, we may not want that pedal
    #      to be grabbed by this program; should warn user at least if
    #      more than one device and ask to proceed and recommend unplugging
    #      any unused device that shouldn't be grabbed
    for device in input_devices:

        #Attain sole ownership of the device, so its events don't populate back up to X.
        device.grab()

        #And register handlers for the device's events.
        ClutchEventDispatcher(device, press_callback, release_callback)

    #Add a handler which releases devices on SIGTERM.
    signal.signal(signal.SIGTERM,
                  lambda: cleanup(output_device, input_devices))

    #And loop indefinitely, handling "asynchronous" press events.
    try:
        while True:
            time.sleep(TIME_SLEEP)
            asyncore.loop(count=1)

    #Allow the program to be closed by CTRL+C.
    except KeyboardInterrupt:
        cleanup(output_device, input_devices)
        print('\ncleanup on CTRL-C complete')
示例#19
0
    def __init__(self):
        res = self.get_resolution()

        allowed_events = {
            evdev.ecodes.EV_ABS:
            ((evdev.ecodes.ABS_MT_POSITION_X, (0, res[0], 0, 0)),
             (evdev.ecodes.ABS_MT_POSITION_Y, (0, res[1], 0, 0)),
             (evdev.ecodes.ABS_MT_TOUCH_MAJOR, (0, 30, 0, 0)),
             (evdev.ecodes.ABS_MT_TRACKING_ID, (0, 65535, 0, 0)),
             (evdev.ecodes.ABS_MT_PRESSURE,
              (0, 255, 0, 0)), (evdev.ecodes.ABS_MT_SLOT, (0, 9, 0, 0))),
            evdev.ecodes.EV_KEY: [
                evdev.ecodes.BTN_TOUCH,
            ]
        }

        self.ui = evdev.UInput(events=allowed_events, name="autopilot-finger")
def main():
    device_path = get_device_name_from_cli() or get_device_from_user_input()

    time.sleep(1)  # waiting for key-up events after pressing previous Enter

    try:
        device = evdev.InputDevice(device_path)
    except:
        sys.exit('ERROR: Wrong device name: ' + device_path +
                 ', try run without arguments')

    print('Device selected:', device)
    print('')
    print('Start listening for events...')

    fake_device = evdev.UInput()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(action(device, fake_device))
示例#21
0
def hps360pen(select_from_list: bool):
    """
    hps360pen is a sample tool to map HP Spectre x360 ap00xxxx stock pen buttons.

    For now, only the pen's bottom button is supported and is mapped to emulate the right mouse button.
    """
    devices = [evd.InputDevice(path) for path in evd.list_devices()]
    devices = [Device(id=idx, name=device.name, evdev=device) for idx, device in enumerate(devices)]

    if select_from_list:

        click.echo(message="Select the HP PEN device from the the list below")

        for device in devices:
            click.echo(f"[{device.id}] - '{device.name}'")

        selection = click.prompt(text='Your selection', type=click.IntRange(min=0, max=len(list(devices))-1), )

        device = devices[selection]
    else:
        click.echo(message="Looking for default HP ELAN PEN signature...")
        for dev in devices:
            if dev.name == HP_ELAN_PEN:
                device = dev
                break
        else:
            click.echo(message=f"Unable to find '{HP_ELAN_PEN}' event device.")
            return -1

    click.echo(message=f"Listening events for input device '{device.name} at '{device.evdev.path}'")

    capabilities = {  # evdev input capabilities for simulating mouse click
        evd.ecodes.EV_KEY: (evd.ecodes.BTN_LEFT, evd.ecodes.BTN_RIGHT, evd.ecodes.BTN_MIDDLE),
    }

    with evd.UInput(capabilities) as ui:
        for event in device.evdev.read_loop():
            if event.code == 321:  # BTN_PEN_BOTTOM
                ui.write(evd.ecodes.EV_KEY, evd.ecodes.BTN_RIGHT, event.value)
                ui.syn()
            elif event.code == 331:  # BTN_PEN_UPPER
                pass
示例#22
0
    def _write_keyb_events(self):

        dev_obj = evdev.UInput()
        """
		write keyb bytes to the device file
		"""
        if self.device and self.device_file:

            # okay... everything exists. we are g to g
            try:
                for keyb_event in self.device.read_loop():

                    # check to make sure the byte is a key-code
                    if keyb_event.type == evdev.ecodes.EV_KEY:

                        dev_obj.write(keyb_event.type, keyb_event.code,
                                      keyb_event.value)

            except (OSError, Exception) as error_messge:
                sys.stdout.write("%s" % str(error_messge))
示例#23
0
    if not ks.finished():
        return

    currentStateOptions = STATE_MAP.get(currentState)
    for item in currentStateOptions:
        if item.judge(ks.keycode, ks.keystate):
            currentState = item.nextState
            logState.append(currentState)
            for act in item.action:
                act(ks.keycode, ks.keystate)
            break

    ks.reset()

dev = evdev.InputDevice('/dev/input/event3')
ui = evdev.UInput()

def main():
    global dev
    global ui

    ks = keystroke()

    dev.grab()

    for event in dev.read_loop():
        kev = evdev.categorize(event)
        ks.input(kev)

        handle(ks)
示例#24
0
            input_devices[device].grab()
            capabilities[device] = input_devices[device].capabilities()
            del capabilities[device][0]
            pickle.dump(capabilities[device], open(p,'wb'))
        # read stored capabilities otherwise
        elif os.path.exists(p):
            with open(p,'rb') as fp:
                capabilities[device] = pickle.load(open(p,'rb'))

    if not capabilities:
        exit(0)
    

    # create host devices
    host_devices = {
        key:evdev.UInput(cap)
        for (key,cap) in capabilities.items()
    }

    # create guest devices
    guest_devices = {
        key:evdev.UInput(cap)
        for (key,cap) in capabilities.items()
    }

    #prepare host device paths
    host_device_paths = [
        os.path.join("/dev/input/by-id", "host-%s" % device)
        for device in config['inputs']
    ]
示例#25
0
def start():
    path = os.path.join(os.path.dirname(__file__), "config.yaml")
    # Loading tablet configuration
    with open(path, "r") as f:
        config = yaml.load(f, Loader=yaml.FullLoader)

    # Get the required ecodes from configuration
    required_ecodes = []
    for k, v in config["actions"].items():
        if isinstance(v, list):
            required_ecodes.extend(v)
        else:
            required_ecodes.append(v)

    temp = []
    for c in required_ecodes:
        temp.extend([evdev.ecodes.ecodes[x] for x in c.split("+")])
    required_ecodes = temp

    pen_events = {
        evdev.ecodes.EV_KEY:
        required_ecodes,
        evdev.ecodes.EV_ABS: [
            #AbsInfo input: value, min, max, fuzz, flat
            (evdev.ecodes.ABS_X,
             evdev.AbsInfo(0, 0, config['pen']['max_x'], 0, 0,
                           config["pen"]["resolution_x"])),
            (evdev.ecodes.ABS_Y,
             evdev.AbsInfo(0, 0, config['pen']['max_y'], 0, 0,
                           config["pen"]["resolution_y"])),
            (evdev.ecodes.ABS_PRESSURE,
             evdev.AbsInfo(0, 0, config['pen']['max_pressure'], 0, 0, 0))
        ],
    }

    # Find the device
    dev = usb.core.find(idVendor=config["vendor_id"],
                        idProduct=config["product_id"])
    # Select end point for reading second interface [2] for actual data
    # I don't know what [0] and [1] are used for
    ep = dev[0].interfaces()[2].endpoints()[0]
    # Reset the device (don't know why, but till it works don't touch it)
    dev.reset()

    # Drop default kernel driver from all devices
    for j in [0, 1, 2]:
        if dev.is_kernel_driver_active(j):
            dev.detach_kernel_driver(j)

    # Set new configuration
    dev.set_configuration()

    vpen = evdev.UInput(events=pen_events,
                        name=config["xinput_name"],
                        version=0x3)

    pressed = -1

    # Infinite loop
    while True:
        try:
            data = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize)
            if data[1] in [192, 193]:  # Pen actions
                pen_x = config['pen']['max_x'] - (data[5] * 255 + data[4])
                pen_y = data[3] * 255 + data[2]
                pen_pressure = data[7] * 255 + data[6]
                vpen.write(evdev.ecodes.EV_ABS, evdev.ecodes.ABS_X, pen_x)
                vpen.write(evdev.ecodes.EV_ABS, evdev.ecodes.ABS_Y, pen_y)
                vpen.write(evdev.ecodes.EV_ABS, evdev.ecodes.ABS_PRESSURE,
                           pen_pressure)
                if data[1] == 192:  # Pen touch
                    vpen.write(evdev.ecodes.EV_KEY, evdev.ecodes.BTN_TOUCH, 0)
                else:
                    vpen.write(evdev.ecodes.EV_KEY, evdev.ecodes.BTN_TOUCH, 1)
            elif data[0] == 2:  # Tablet button actions
                # press types: 0 - up; 1 - down; 2 - hold
                press_type = 1
                if data[1] == 2:  # First button
                    pressed = 0
                elif data[1] == 4:  # Second button
                    pressed = 1
                elif data[3] == 44:  # Third button
                    pressed = 2
                elif data[3] == 43:  # Fourth button
                    pressed = 3
                else:
                    press_type = 0
                key_codes = config["actions"]["tablet_buttons"][pressed].split(
                    "+")
                for key in key_codes:
                    act = evdev.ecodes.ecodes[key]
                    vpen.write(evdev.ecodes.EV_KEY, act, press_type)
            # Flush
            vpen.syn()
        except usb.core.USBError as e:
            if e.args[0] == 19:
                vpen.close()
                raise Exception('Device has been disconnected')
示例#26
0
def create_virtual_keyboard():
    global virtual_keyboard
    # accepts only KEY_* events by default, which is perfect
    virtual_keyboard = e.UInput(name="virtual uinput keyboard")
示例#27
0
    def open_uinput(self):
        assert (self.capabilities != None)
        self.uinput = evdev.UInput(self.capabilities, name=self.name)

        print("opened uinput", self.name)
示例#28
0
import evdev
import time
import asyncio
from EventHandler import EventHandler
from InputHandler import InputHandler
from ProgramHandler import ProgramHandler
import KeyPressHandler

from evdev.ecodes import *

device = InputHandler("/dev/input/by-path/platform-i8042-serio-0-event-kbd",
                      grabbed=True)
e = evdev.ecodes
uinput = evdev.UInput()


@device.eventHandler(KEY_A)
async def foo(event):
    ProgramHandler("cat /home/popcorn9499/iommuGroups.sh")

    if event.value == KeyPressHandler.KEY_STATE.KEY_DOWN:
        key = KeyPressHandler.KeyPress(keys=[KEY_LEFTCTRL, KEY_M])
        await key.keyPress(keyState=KeyPressHandler.KEY_STATE.KEY_TOGGLE,
                           pressDuration=0.1)


@device.eventHandler(KEY_B)
async def bar(event):
    print("This is bar's first handler")
    print(evdev.categorize(event))
示例#29
0
 def __init__(self, *args, **kwargs):
     super(Controller, self).__init__(*args, **kwargs)
     self._layout = LAYOUT
     self._dev = evdev.UInput()
示例#30
0
    def _start_injecting(self):
        """The injection worker that keeps injecting until terminated.

        Stuff is non-blocking by using asyncio in order to do multiple things
        somewhat concurrently.

        Use this function as starting point in a process. It creates
        the loops needed to read and map events and keeps running them.
        """
        # create a new event loop, because somehow running an infinite loop
        # that sleeps on iterations (ev_abs_mapper) in one process causes
        # another injection process to screw up reading from the grabbed
        # device.
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        numlock_state = is_numlock_on()

        loop = asyncio.get_event_loop()
        coroutines = []

        logger.info('Starting injecting the mapping for "%s"', self.device)

        paths = get_devices()[self.device]['paths']

        # Watch over each one of the potentially multiple devices per hardware
        for path in paths:
            source, abs_to_rel = self._prepare_device(path)
            if source is None:
                continue

            # each device needs own macro instances to add a custom handler
            logger.debug('Parsing macros for %s', path)
            macros = {}
            for key, output in self.mapping:
                if is_this_a_macro(output):
                    macro = parse(output, self.mapping)
                    if macro is None:
                        continue

                    for permutation in key.get_permutations():
                        macros[permutation.keys] = macro

            if len(macros) == 0:
                logger.debug('No macros configured')

            # certain capabilities can have side effects apparently. with an
            # EV_ABS capability, EV_REL won't move the mouse pointer anymore.
            # so don't merge all InputDevices into one UInput device.
            uinput = evdev.UInput(name=f'{DEV_NAME} {self.device}',
                                  phys=DEV_NAME,
                                  events=self._modify_capabilities(
                                      macros, source, abs_to_rel))

            logger.spam('Injected capabilities for "%s": %s', path,
                        uinput.capabilities(verbose=True))

            def handler(*args, uinput=uinput):
                # this ensures that the right uinput is used for macro_write,
                # because this is within a loop
                self._macro_write(*args, uinput)

            for macro in macros.values():
                macro.set_handler(handler)

            # actual reading of events
            coroutines.append(
                self._event_consumer(macros, source, uinput, abs_to_rel))

            # mouse movement injection based on the results of the
            # event consumer
            if abs_to_rel:
                self.abs_state[0] = 0
                self.abs_state[1] = 0
                coroutines.append(
                    ev_abs_mapper(self.abs_state, source, uinput,
                                  self.mapping))

        if len(coroutines) == 0:
            logger.error('Did not grab any device')
            return

        coroutines.append(self._msg_listener(loop))

        # set the numlock state to what it was before injecting, because
        # grabbing devices screws this up
        set_numlock(numlock_state)

        try:
            loop.run_until_complete(asyncio.gather(*coroutines))
        except RuntimeError:
            # stopped event loop most likely
            pass
        except OSError as error:
            logger.error(str(error))

        if len(coroutines) > 0:
            logger.debug('asyncio coroutines ended')