Example #1
0
def rattle(d, effnr=0, effgain=0xC000):
        print("rattle", effnr, effgain)
        gain = evdev.InputEvent(0, 0, evdev.ecodes.EV_FF, evdev.ecodes.FF_GAIN, effgain)    # [0x5000 .. 0xFFFF]
        play = evdev.InputEvent(0,0,evdev.ecodes.EV_FF, effnr, 1)
        stop = evdev.InputEvent(0,0,evdev.ecodes.EV_FF, effnr, 0)
        d.write_event(gain)
        d.write_event(play)
Example #2
0
 def flush_state_change(self, sync_event):
     noisy = self._state == VirtualModifierState.PRESSED_NOISY
     previous_noisy = self._previous_state == VirtualModifierState.PRESSED_NOISY
     if noisy and not previous_noisy:
         self._keyboard.write_event(
             evdev.InputEvent(sync_event.sec, sync_event.usec,
                              evdev.ecodes.EV_KEY, self.code, 1))
     elif not noisy and previous_noisy:
         self._keyboard.write_event(
             evdev.InputEvent(sync_event.sec, sync_event.usec,
                              evdev.ecodes.EV_KEY, self.code, 0))
     self._previous_state = self._state
Example #3
0
    async def _event_consumer(self, source, forward_to):
        """Reads input events to inject keycodes or talk to the event_producer.

        Can be stopped by stopping the asyncio loop. This loop
        reads events from a single device only. Other devnodes may be
        present for the hardware device, in which case this needs to be
        started multiple times.

        Parameters
        ----------
        source : evdev.InputDevice
            where to read keycodes from
        forward_to : evdev.UInput
            where to write keycodes to that were not mapped to anything.
            Should be an UInput with capabilities that work for all forwarded
            events, so ideally they should be copied from source.
        """
        logger.debug(
            'Started consumer to inject to %s, fd %s',
            source.path, source.fd
        )

        gamepad = classify(source) == GAMEPAD

        keycode_handler = KeycodeMapper(self.context, source, forward_to)

        async for event in source.async_read_loop():
            if self._event_producer.is_handled(event):
                # the event_producer will take care of it
                self._event_producer.notify(event)
                continue

            # for mapped stuff
            if utils.should_map_as_btn(event, self.context.mapping, gamepad):
                will_report_key_up = utils.will_report_key_up(event)

                keycode_handler.handle_keycode(event)

                if not will_report_key_up:
                    # simulate a key-up event if no down event arrives anymore.
                    # this may release macros, combinations or keycodes.
                    release = evdev.InputEvent(0, 0, event.type, event.code, 0)
                    self._event_producer.debounce(
                        debounce_id=(event.type, event.code, event.value),
                        func=keycode_handler.handle_keycode,
                        args=(release, False),
                        ticks=3,
                    )

                continue

            # forward the rest
            forward_to.write(event.type, event.code, event.value)
            # this already includes SYN events, so need to syn here again

        # This happens all the time in tests because the async_read_loop
        # stops when there is nothing to read anymore. Otherwise tests
        # would block.
        logger.error('The consumer for "%s" stopped early', source.path)
Example #4
0
 def flush_state_change(self, sync_event):
     if self._state == OnReleaseState.PRESSED_SILENT and \
        self._previous_state != OnReleaseState.PRESSED_SILENT:
         event = evdev.InputEvent(sync_event.sec, sync_event.usec,
                                  evdev.ecodes.EV_KEY, self._second_code, 1)
         self._keyboard.write_event(event)
         if not self._repeating:
             event.value = 0
             self._keyboard.write_event(event)
     if self._state != OnReleaseState.PRESSED_SILENT and \
        self._previous_state == OnReleaseState.PRESSED_SILENT and \
        self._repeating:
         event = evdev.InputEvent(sync_event.sec, sync_event.usec,
                                  evdev.ecodes.EV_KEY, self._second_code, 0)
         self._keyboard.write_event(event)
         self._repeating = False
     super().flush_state_change(sync_event)
Example #5
0
def new_event(type, code, value, timestamp=None, offset=0):
    """Create a new input_event."""
    if timestamp is None:
        timestamp = time.time() + offset

    sec = int(timestamp)
    usec = timestamp % 1 * 1000000
    event = evdev.InputEvent(sec, usec, type, code, value)
    return event
Example #6
0
 def flush_state_change(self, sync_event):
     if self._previous_state == OnReleaseState.PRESSED_SINGLE and \
        self._state == OnReleaseState.RELEASED:
         event = evdev.InputEvent(sync_event.sec, sync_event.usec,
                                  evdev.ecodes.EV_KEY, self._extra_code, 1)
         self._keyboard.write_event(event)
         event.value = 0
         self._keyboard.write_event(event)
     self._previous_state = self._state
Example #7
0
def js_read_loop(dev, timeout):
        """
        same as /usr/local/lib/python3.5/dist-packages/evdev/eventio.py:read_loop, but with a timeout...
        """
        while True:
                r, w, x = select.select([dev.fd], [], [], timeout)
                if len(r):
                        for event in dev.read():
                                yield event
                else:
                        yield evdev.InputEvent(0,0,evdev.ecodes.EV_SYN, evdev.ecodes.KEY_UNKNOWN,0)     # dummy when timout
Example #8
0
def franken_event(
        original_event,
        franken_uinput,
        franken_event_code,
        original_absinfo=None,
        franken_absinfo=None):

    event = evdev.InputEvent(
        original_event.sec,
        original_event.usec,
        original_event.type,
        franken_event_code,
        franken_value(original_event.value, original_absinfo, franken_absinfo),
    )
    franken_uinput.write_event(event)
    logger.debug(f"generated event {franken_uinput.device.path} {evdev.categorize(event)} {event.code}")
Example #9
0
def button(uinput, code, value=1, syn=True):
    """
    Send a button event.
    :param uinput: the uinput device to generate the button event
    :type uinput: evdev.UInput
    :param code: the event code, e.g. evdev.ecodes.BTN_A
    :type code: int
    :param value: 1 (button down), 0 (button up)
    :type code: int
    :param syn: whether or not to follow up the event with a syn event
    :type syn: bool
    """
    # sec and usec are thrown out anyway, see
    # https://github.com/gvalkov/python-evdev/blob/master/evdev/eventio.py#L111
    uinput.write_event(evdev.InputEvent(0, 0, evdev.ecodes.EV_KEY, code, value))
    if(syn):
        uinput.syn()
Example #10
0
    def _get_event(self, message):
        """Return an InputEvent if the message contains one. None otherwise."""
        message_type = message['type']
        message_body = message['message']

        if message_type == 'groups':
            if message_body != groups.dumps():
                groups.loads(message_body)
                logger.debug('Received %d devices', len(groups))
                self._devices_updated = True
            return None

        if message_type == 'event':
            return evdev.InputEvent(*message_body)

        logger.error('Received unknown message "%s"', message)
        return None
Example #11
0
    def _get_event(self, message):
        """Return an InputEvent if the message contains one. None otherwise."""
        message_type = message['type']
        message_body = message['message']

        if message_type == 'devices':
            # result of get_devices in the helper
            if message_body != get_devices():
                logger.debug('Received %d devices', len(message_body))
                set_devices(message_body)
                self._devices_updated = True
            return None

        if message_type == 'event':
            return evdev.InputEvent(*message_body)

        logger.error('Received unknown message "%s"', message)
        return None
Example #12
0
    def set_led_pulse(self, brightness=255, speed=255, pulse_table=0,
                      pulse_while_asleep=False, pulse_while_awake=True):
        """ Encode the pulse parameters:
            brightness: 0 to 255
            speed: 0 to 510, slower to faster, log scale, sortof.
                255 = 2s ("normal")
              So basically: 251=8s, 252=6s, 253=4s, 254=2.5s, 255=2s
              /ish/.  I timed those values with a stopwatch, so...
            pulse_table: 0, 1, 2 (dunno)
            pulse_while_asleep: boolean
            pulse_while_awake: boolean
        """

        if brightness < 0 or brightness > 255:
            raise ValueError("brightness (%s) must be 0 through 255" %
                             (brightness,))

        if speed < 0 or speed > 510:
            raise ValueError("speed (%s) must be 0 through 510" % (speed,))

        if pulse_table < 0 or pulse_table > 2:
            raise ValueError("pulse table (%s) must be 0, 1, or 2" %
                             (pulse_table,))

        pulse_while_awake = int(bool(pulse_while_awake))
        pulse_while_asleep = int(bool(pulse_while_asleep))

        value = (pulse_while_awake << 20) \
                | (pulse_while_asleep << 19) \
                | (pulse_table << 17) \
                | (speed << 8) \
                | brightness

        mod, sec = math.modf(time.time())
        sec = int(sec)
        usec = int(mod * 1000000)
        event = evdev.InputEvent(sec=sec, usec=usec, type=evdev.ecodes.EV_MSC,
                                 code=evdev.ecodes.MSC_PULSELED, value=value)
        self.device.write_event(event)
async def action(device, fake_device):
    global keycodes_to_bind

    try:
        is_on_pause = False  # no remapping if script is on pause

        is_leftctrl_down = False
        is_rightctrl_down = False
        is_ctrl_down = False

        is_leftalt_down = False
        is_rightalt_down = False
        is_alt_down = False

        is_leftshift_down = False
        is_rightshift_down = False
        is_shift_down = False

        is_leftwin_down = False
        is_rightwin_down = False
        is_win_down = False

        is_space_down = False

        list_of_keydowns_while_space_down = []

        # const from evdev
        key_is_hold = 2  # key is holding
        key_is_down = 1  # key is pressed
        key_is_up = 0  # key is released

        # for catching space hotkey
        hotkey_with_space_pressed = False

        device.grab(
        )  # https://python-evdev.readthedocs.io/en/latest/tutorial.html#getting-exclusive-access-to-a-device
        async for event in device.async_read_loop(
        ):  # https://python-evdev.readthedocs.io/en/latest/tutorial.html#reading-events-using-asyncio
            if event.code == 2:
                continue

            if event.type == evdev.ecodes.EV_SYN:
                continue

            # event.type == evdev.ecodes.EV_...
            # https://www.kernel.org/doc/Documentation/input/event-codes.txt

            skip_send = False  # for not to send current key

            if event.type != evdev.ecodes.EV_KEY:
                if event.type == evdev.ecodes.EV_MSC:
                    logging.debug('')

                logging.debug('event.type=%s, event=%s, sending as is',
                              event.type, evdev.categorize(event))
                fake_device.write_event(event)
                fake_device.syn()
            else:
                logging.debug(
                    'event.type=EV_KEY event.code=%s event.value=%s %s %s',
                    event.code, event.value,
                    'isDown' if event.value == key_is_down else '',
                    'isUp' if event.value == key_is_up else '')

                if event.code == evdev.ecodes.KEY_LEFTCTRL:
                    is_leftctrl_down = event.value

                elif event.code == evdev.ecodes.KEY_RIGHTCTRL:
                    is_rightctrl_down = event.value

                elif event.code == evdev.ecodes.KEY_LEFTALT:
                    is_leftalt_down = event.value

                elif event.code == evdev.ecodes.KEY_RIGHTALT:
                    is_rightalt_down = event.value

                elif event.code == evdev.ecodes.KEY_LEFTSHIFT:
                    is_leftshift_down = event.value

                elif event.code == evdev.ecodes.KEY_RIGHTSHIFT:
                    is_rightshift_down = event.value

                elif event.code == evdev.ecodes.KEY_LEFTMETA:
                    is_leftwin_down = event.value

                elif event.code == evdev.ecodes.KEY_RIGHTMETA:
                    is_rightwin_down = event.value

                elif event.code == evdev.ecodes.KEY_SPACE:
                    is_space_down = event.value
                    if event.value == key_is_down:
                        list_of_keydowns_while_space_down = []
                        skip_send = True
                        hotkey_with_space_pressed = False

                    if event.value == key_is_up:
                        if hotkey_with_space_pressed:
                            skip_send = True
                        else:
                            # send `space` key if no hotkey with `space` was pressed
                            # send `space` down before sending current event (`space` up)
                            logging.debug(
                                '---> send space event-down before sending event-up'
                            )
                            fake_device.write_event(
                                evdev.InputEvent(event.sec, event.usec,
                                                 event.type,
                                                 evdev.ecodes.KEY_SPACE,
                                                 key_is_down))
                            fake_device.syn()

                # print('leftctrl=', is_leftctrl_down, 'leftalt=', is_leftalt_down, 'leftshift=', is_leftshift_down, 'leftmeta=', is_leftmeta_down, 'space=', is_space_down)

                is_ctrl_down = is_leftctrl_down or is_rightctrl_down
                is_alt_down = is_leftalt_down or is_rightalt_down
                is_shift_down = is_leftshift_down or is_rightshift_down
                is_win_down = is_leftwin_down or is_rightwin_down

                if event.value == key_is_down:
                    # handle special hotkeys on key-down only!

                    if event.code == evdev.ecodes.KEY_Q and is_win_down and is_ctrl_down and is_alt_down:
                        print('win+ctrl+alt+q, quit!')
                        device.ungrab()
                        sys.exit()
                        break

                    if event.code == evdev.ecodes.KEY_Z and is_win_down and is_ctrl_down and is_alt_down:
                        if is_on_pause:
                            print('win+ctrl+alt+z, unpause script')
                            is_on_pause = False
                        else:
                            print('win+ctrl+alt+z, pause script')
                            is_on_pause = True

                # main logic begins
                if not skip_send:
                    if event.value == key_is_down or event.value == key_is_hold:
                        if not is_on_pause and is_space_down and event.code in keycodes_to_bind:
                            # that is our key, modify it

                            # save keys to modify on key-up
                            if event.code not in list_of_keydowns_while_space_down:
                                list_of_keydowns_while_space_down.append(
                                    event.code)

                            # modify key code
                            event.code = keycodes_to_bind[event.code]

                            # save flag that hotkey was pressed for not to send space-key
                            hotkey_with_space_pressed = True

                    elif event.value == key_is_up:
                        # we must modify key-up event even when space-key was
                        # just released and not pressed anymore

                        if event.code in list_of_keydowns_while_space_down:
                            # that is our key, modify it

                            # remove that key from list
                            list_of_keydowns_while_space_down.remove(
                                event.code)

                            # modify key code
                            event.code = keycodes_to_bind[event.code]

                    logging.debug('---> sending event: %s',
                                  evdev.categorize(event))
                    fake_device.write_event(event)
                    fake_device.syn()

    except Exception as e:
        logging.error(e)
        device.ungrab()
        print('device ungrabbed')