コード例 #1
0
    def test_combine_triggers(self):
        reader.start_reading('device 1')

        i = 0

        def next_timestamp():
            nonlocal i
            i += 1
            return time.time() + i

        # based on an observed bug
        send_event_to_reader(new_event(3, 1, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 0, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 2, 1, next_timestamp()))
        self.assertEqual(reader.read(), (EV_ABS, ABS_Z, 1))
        send_event_to_reader(new_event(3, 0, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 5, 1, next_timestamp()))
        self.assertEqual(reader.read(),
                         ((EV_ABS, ABS_Z, 1), (EV_ABS, ABS_RZ, 1)))
        send_event_to_reader(new_event(3, 5, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 0, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 1, 0, next_timestamp()))
        self.assertEqual(reader.read(), None)
        send_event_to_reader(new_event(3, 2, 1, next_timestamp()))
        send_event_to_reader(new_event(3, 1, 0, next_timestamp()))
        send_event_to_reader(new_event(3, 0, 0, next_timestamp()))
        # due to not properly handling the duplicate down event it cleared
        # the combination and returned it. Instead it should report None
        # and by doing that keep the previous combination.
        self.assertEqual(reader.read(), None)
コード例 #2
0
ファイル: window.py プロジェクト: matt-hu/key-mapper
    def on_select_device(self, dropdown):
        """List all presets, create one if none exist yet."""
        self.save_preset()

        if dropdown.get_active_id() == self.selected_device:
            return

        # selecting a device will also automatically select a different
        # preset. Prevent another unsaved-changes dialog to pop up
        custom_mapping.changed = False

        device = dropdown.get_active_id()

        if device is None:
            return

        logger.debug('Selecting device "%s"', device)

        self.selected_device = device
        self.selected_preset = None

        self.populate_presets()

        reader.start_reading(device)

        self.show_device_mapping_status()
コード例 #3
0
    def test_reads_joysticks(self):
        # if their purpose is "buttons"
        custom_mapping.set('gamepad.joystick.left_purpose', BUTTONS)
        push_events(
            'gamepad',
            [
                new_event(EV_ABS, ABS_Y, MAX_ABS),
                # the value of that one is interpreted as release, because
                # it is too small
                new_event(EV_ABS, ABS_X, MAX_ABS // 10)
            ])
        self.create_helper()

        reader.start_reading('gamepad')
        time.sleep(0.2)
        self.assertEqual(reader.read(), (EV_ABS, ABS_Y, 1))
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 1)

        reader._unreleased = {}
        custom_mapping.set('gamepad.joystick.left_purpose', MOUSE)
        push_events('gamepad', [new_event(EV_ABS, ABS_Y, MAX_ABS)])
        self.create_helper()

        reader.start_reading('gamepad')
        time.sleep(0.1)
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 0)
コード例 #4
0
    def test_change_device(self):
        push_events('device 1', [
            new_event(EV_KEY, 1, 1),
        ] * 100)

        push_events('device 2', [
            new_event(EV_KEY, 2, 1),
        ] * 100)

        self.create_helper()

        reader.start_reading('device 1')
        time.sleep(0.1)
        self.assertEqual(reader.read(), Key(EV_KEY, 1, 1))

        reader.start_reading('device 2')

        # it's plausible that right after sending the new read command more
        # events from the old device might still appear. Give the helper
        # some time to handle the new command.
        time.sleep(0.1)
        reader.clear()

        time.sleep(0.1)
        self.assertEqual(reader.read(), Key(EV_KEY, 2, 1))
コード例 #5
0
ファイル: window.py プロジェクト: limehouse/key-mapper
    def on_select_device(self, dropdown):
        """List all presets, create one if none exist yet."""
        self.save_preset()

        if self.group and dropdown.get_active_id() == self.group.key:
            return

        # selecting a device will also automatically select a different
        # preset. Prevent another unsaved-changes dialog to pop up
        custom_mapping.changed = False

        group_key = dropdown.get_active_id()

        if group_key is None:
            return

        logger.debug('Selecting device "%s"', group_key)

        self.group = groups.find(key=group_key)
        self.preset_name = None

        self.populate_presets()

        reader.start_reading(groups.find(key=group_key))

        self.show_device_mapping_status()
コード例 #6
0
    def test_clear(self):
        push_events('device 1', [
            new_event(EV_KEY, CODE_1, 1),
            new_event(EV_KEY, CODE_2, 1),
            new_event(EV_KEY, CODE_3, 1)
        ] * 15)

        self.create_helper()
        reader.start_reading('device 1')
        time.sleep(START_READING_DELAY + EVENT_READ_TIMEOUT * 3)

        reader.read()
        self.assertEqual(len(reader._unreleased), 3)
        self.assertIsNotNone(reader.previous_event)
        self.assertIsNotNone(reader.previous_result)

        # make the helper send more events to the reader
        time.sleep(EVENT_READ_TIMEOUT * 2)
        self.assertTrue(reader._results.poll())
        reader.clear()

        self.assertFalse(reader._results.poll())
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 0)
        self.assertIsNone(reader.get_unreleased_keys())
        self.assertIsNone(reader.previous_event)
        self.assertIsNone(reader.previous_result)
        self.tearDown()
コード例 #7
0
    def test_reading_3(self):
        self.create_helper()
        # a combination of events via Socket with reads inbetween
        reader.start_reading('gamepad')

        send_event_to_reader(new_event(EV_KEY, CODE_1, 1, 1001))
        self.assertEqual(reader.read(), ((EV_KEY, CODE_1, 1)))

        custom_mapping.set('gamepad.joystick.left_purpose', BUTTONS)
        send_event_to_reader(new_event(EV_ABS, ABS_Y, 1, 1002))
        self.assertEqual(reader.read(),
                         ((EV_KEY, CODE_1, 1), (EV_ABS, ABS_Y, 1)))

        send_event_to_reader(new_event(EV_ABS, ABS_HAT0X, -1, 1003))
        self.assertEqual(reader.read(),
                         ((EV_KEY, CODE_1, 1), (EV_ABS, ABS_Y, 1),
                          (EV_ABS, ABS_HAT0X, -1)))

        # adding duplicate down events won't report a different combination.
        # import for triggers, as they keep reporting more down-events before
        # they are released
        send_event_to_reader(new_event(EV_ABS, ABS_Y, 1, 1005))
        self.assertEqual(reader.read(), None)
        send_event_to_reader(new_event(EV_ABS, ABS_HAT0X, -1, 1006))
        self.assertEqual(reader.read(), None)

        send_event_to_reader(new_event(EV_KEY, CODE_1, 0, 1004))
        read = reader.read()
        self.assertEqual(read, None)

        send_event_to_reader(new_event(EV_ABS, ABS_Y, 0, 1007))
        self.assertEqual(reader.read(), None)

        send_event_to_reader(new_event(EV_KEY, ABS_HAT0X, 0, 1008))
        self.assertEqual(reader.read(), None)
コード例 #8
0
    def test_reading_2(self):
        # a combination of events
        push_events('Foo Device 2', [
            new_event(EV_KEY, CODE_1, 1, 10000.1234),
            new_event(EV_KEY, CODE_3, 1, 10001.1234),
            new_event(EV_ABS, ABS_HAT0X, -1, 10002.1234)
        ])

        pipe = multiprocessing.Pipe()

        def refresh():
            # from within the helper process notify this test that
            # refresh was called as expected
            pipe[1].send('refreshed')

        with mock.patch.object(groups, 'refresh', refresh):
            self.create_helper()

        reader.start_reading(groups.find(key='Foo Device 2'))

        # sending anything arbitrary does not stop the helper
        reader._commands.send(856794)
        time.sleep(0.2)
        # but it makes it look for new devices because maybe its list of
        # groups is not up-to-date
        self.assertTrue(pipe[0].poll())
        self.assertEqual(pipe[0].recv(), 'refreshed')

        self.assertEqual(reader.read(), (
            (EV_KEY, CODE_1, 1),
            (EV_KEY, CODE_3, 1),
            (EV_ABS, ABS_HAT0X, -1)
        ))
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 3)
コード例 #9
0
 def test_reading_1(self):
     # a single event
     push_events('Foo Device 2', [new_event(EV_ABS, ABS_HAT0X, 1)])
     push_events('Foo Device 2', [new_event(EV_ABS, REL_X, 1)])  # mouse movements are ignored
     self.create_helper()
     reader.start_reading(groups.find(key='Foo Device 2'))
     time.sleep(0.2)
     self.assertEqual(reader.read(), (EV_ABS, ABS_HAT0X, 1))
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 1)
コード例 #10
0
 def test_wrong_device(self):
     push_events('device 1', [
         new_event(EV_KEY, CODE_1, 1),
         new_event(EV_KEY, CODE_2, 1),
         new_event(EV_KEY, CODE_3, 1)
     ])
     self.create_helper()
     reader.start_reading('device 2')
     time.sleep(EVENT_READ_TIMEOUT * 5)
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 0)
コード例 #11
0
 def test_blacklist(self):
     push_events('device 1', [
         new_event(EV_KEY, BTN_TOOL_DOUBLETAP, 1),
         new_event(EV_KEY, CODE_2, 1),
         new_event(EV_KEY, BTN_TOOL_DOUBLETAP, 1),
     ])
     self.create_helper()
     reader.start_reading('device 1')
     time.sleep(0.1)
     self.assertEqual(reader.read(), (EV_KEY, CODE_2, 1))
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 1)
コード例 #12
0
 def test_reading_ignore_up(self):
     push_events('device 1', [
         new_event(EV_KEY, CODE_1, 0, 10),
         new_event(EV_KEY, CODE_2, 1, 11),
         new_event(EV_KEY, CODE_3, 0, 12),
     ])
     self.create_helper()
     reader.start_reading('device 1')
     time.sleep(0.1)
     self.assertEqual(reader.read(), (EV_KEY, CODE_2, 1))
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 1)
コード例 #13
0
 def test_ignore_value_2(self):
     # this is not a combination, because (EV_KEY CODE_3, 2) is ignored
     push_events(
         'device 1',
         [new_event(EV_ABS, ABS_HAT0X, 1),
          new_event(EV_KEY, CODE_3, 2)])
     self.create_helper()
     reader.start_reading('device 1')
     time.sleep(0.2)
     self.assertEqual(reader.read(), (EV_ABS, ABS_HAT0X, 1))
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 1)
コード例 #14
0
 def test_blacklisted_events(self):
     push_events('Foo Device 2', [
         new_event(EV_KEY, BTN_TOOL_DOUBLETAP, 1),
         new_event(EV_KEY, CODE_2, 1),
         new_event(EV_KEY, BTN_TOOL_DOUBLETAP, 1),
     ])
     self.create_helper()
     reader.start_reading(groups.find(key='Foo Device 2'))
     time.sleep(0.1)
     self.assertEqual(reader.read(), (EV_KEY, CODE_2, 1))
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 1)
コード例 #15
0
 def test_keymapper_devices(self):
     # Don't read from keymapper devices, their keycodes are not
     # representative for the original key. As long as this is not
     # intentionally programmed it won't even do that. But it was at some
     # point.
     push_events('key-mapper device 2', [
         new_event(EV_KEY, CODE_1, 1),
         new_event(EV_KEY, CODE_2, 1),
         new_event(EV_KEY, CODE_3, 1)
     ])
     self.create_helper()
     reader.start_reading('device 2')
     time.sleep(EVENT_READ_TIMEOUT * 5)
     self.assertEqual(reader.read(), None)
     self.assertEqual(len(reader._unreleased), 0)
コード例 #16
0
    def test_terminate(self):
        self.create_helper()
        reader.start_reading('device 1')

        push_events('device 1', [new_event(EV_KEY, CODE_3, 1)])
        time.sleep(START_READING_DELAY + EVENT_READ_TIMEOUT)
        self.assertTrue(reader._results.poll())

        reader.terminate()
        reader.clear()
        time.sleep(EVENT_READ_TIMEOUT)

        # no new events arrive after terminating
        push_events('device 1', [new_event(EV_KEY, CODE_3, 1)])
        time.sleep(EVENT_READ_TIMEOUT * 3)
        self.assertFalse(reader._results.poll())
コード例 #17
0
    def test_reading_2(self):
        # a combination of events
        push_events('device 1', [
            new_event(EV_KEY, CODE_1, 1, 10000.1234),
            new_event(EV_KEY, CODE_3, 1, 10001.1234),
            new_event(EV_ABS, ABS_HAT0X, -1, 10002.1234)
        ])
        self.create_helper()
        reader.start_reading('device 1')

        # sending anything arbitrary does not stop the helper
        reader._commands.send(856794)

        time.sleep(0.2)

        self.assertEqual(reader.read(),
                         ((EV_KEY, CODE_1, 1), (EV_KEY, CODE_3, 1),
                          (EV_ABS, ABS_HAT0X, -1)))
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 3)
コード例 #18
0
ファイル: test_test.py プロジェクト: limehouse/key-mapper
    def test_push_events(self):
        """Test that push_event works properly between helper and reader.

        Using push_events after the helper is already forked should work,
        as well as using push_event twice
        """
        def create_helper():
            # this will cause pending events to be copied over to the helper
            # process
            def start_helper():
                helper = RootHelper()
                helper.run()

            self.helper = multiprocessing.Process(target=start_helper)
            self.helper.start()
            time.sleep(0.1)

        def wait_for_results():
            # wait for the helper to send stuff
            for _ in range(10):
                time.sleep(EVENT_READ_TIMEOUT)
                if reader._results.poll():
                    break

        event = new_event(EV_KEY, 102, 1)
        create_helper()
        reader.start_reading(groups.find(key='Foo Device 2'))
        time.sleep(START_READING_DELAY)

        push_events('Foo Device 2', [event])
        wait_for_results()
        self.assertTrue(reader._results.poll())

        reader.clear()
        self.assertFalse(reader._results.poll())

        # can push more events to the helper that is inside a separate
        # process, which end up being sent to the reader
        push_events('Foo Device 2', [event])
        wait_for_results()
        self.assertTrue(reader._results.poll())
コード例 #19
0
    def test_switch_device(self):
        push_events('device 2', [new_event(EV_KEY, CODE_1, 1)])
        push_events('device 1', [new_event(EV_KEY, CODE_3, 1)])
        self.create_helper()

        reader.start_reading('device 2')
        self.assertFalse(reader._results.poll())
        self.assertEqual(reader.device_name, 'device 2')
        time.sleep(EVENT_READ_TIMEOUT * 5)

        self.assertTrue(reader._results.poll())
        reader.start_reading('device 1')
        self.assertEqual(reader.device_name, 'device 1')
        self.assertFalse(reader._results.poll())  # pipe resets

        time.sleep(EVENT_READ_TIMEOUT * 5)
        self.assertTrue(reader._results.poll())

        self.assertEqual(reader.read(), (EV_KEY, CODE_3, 1))
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 1)
コード例 #20
0
    def test_change_wheel_direction(self):
        # not just wheel, anything that suddenly reports a different value.
        # as long as type and code are equal its the same key, so there is no
        # way both directions can be held down.
        self.assertEqual(reader.read(), None)
        self.create_helper()
        self.assertEqual(reader.read(), None)
        reader.start_reading('device 1')
        self.assertEqual(reader.read(), None)

        send_event_to_reader(new_event(EV_REL, REL_WHEEL, 1))
        self.assertEqual(reader.read(), (EV_REL, REL_WHEEL, 1))
        self.assertEqual(len(reader._unreleased), 1)
        self.assertEqual(reader.read(), None)

        send_event_to_reader(new_event(EV_REL, REL_WHEEL, -1))
        self.assertEqual(reader.read(), (EV_REL, REL_WHEEL, -1))
        # notice that this is no combination of two sides, the previous
        # entry in unreleased has to get overwritten. So there is still only
        # one element in it.
        self.assertEqual(len(reader._unreleased), 1)
        self.assertEqual(reader.read(), None)
コード例 #21
0
    def test_reading_wheel(self):
        # will be treated as released automatically at some point
        self.create_helper()
        reader.start_reading('device 1')

        send_event_to_reader(new_event(EV_REL, REL_WHEEL, 0))
        self.assertIsNone(reader.read())

        send_event_to_reader(new_event(EV_REL, REL_WHEEL, 1))
        result = reader.read()
        self.assertIsInstance(result, Key)
        self.assertEqual(result, (EV_REL, REL_WHEEL, 1))
        self.assertEqual(result, ((EV_REL, REL_WHEEL, 1), ))
        self.assertNotEqual(result, ((EV_REL, REL_WHEEL, 1), (1, 1, 1)))
        self.assertEqual(result.keys, ((EV_REL, REL_WHEEL, 1), ))

        # it won't return the same event twice
        self.assertEqual(reader.read(), None)

        # but it is still remembered unreleased
        self.assertEqual(len(reader._unreleased), 1)
        self.assertEqual(reader.get_unreleased_keys(), (EV_REL, REL_WHEEL, 1))
        self.assertIsInstance(reader.get_unreleased_keys(), Key)

        # as long as new wheel events arrive, it is considered unreleased
        for _ in range(10):
            send_event_to_reader(new_event(EV_REL, REL_WHEEL, 1))
            self.assertEqual(reader.read(), None)
            self.assertEqual(len(reader._unreleased), 1)

        # read a few more times, at some point it is treated as unreleased
        for _ in range(4):
            self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 0)
        self.assertIsNone(reader.get_unreleased_keys())
        """combinations"""

        send_event_to_reader(new_event(EV_REL, REL_WHEEL, 1, 1000))
        send_event_to_reader(new_event(EV_KEY, KEY_COMMA, 1, 1001))
        combi_1 = ((EV_REL, REL_WHEEL, 1), (EV_KEY, KEY_COMMA, 1))
        combi_2 = ((EV_KEY, KEY_COMMA, 1), (EV_KEY, KEY_A, 1))
        read = reader.read()
        self.assertEqual(read, combi_1)
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 2)
        self.assertEqual(reader.get_unreleased_keys(), combi_1)

        # don't send new wheel down events, it should get released again
        i = 0
        while len(reader._unreleased) == 2:
            read = reader.read()
            if i == 100:
                raise AssertionError('Did not release the wheel')
            i += 1
        # and only the comma remains. However, a changed combination is
        # only returned when a new key is pressed. Only then the pressed
        # down keys are collected in a new Key object.
        self.assertEqual(read, None)
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 1)
        self.assertEqual(reader.get_unreleased_keys(), combi_1[1])

        # press down a new key, now it will return a different combination
        send_event_to_reader(new_event(EV_KEY, KEY_A, 1, 1002))
        self.assertEqual(reader.read(), combi_2)
        self.assertEqual(len(reader._unreleased), 2)

        # release all of them
        send_event_to_reader(new_event(EV_KEY, KEY_COMMA, 0))
        send_event_to_reader(new_event(EV_KEY, KEY_A, 0))
        self.assertEqual(reader.read(), None)
        self.assertEqual(len(reader._unreleased), 0)
        self.assertEqual(reader.get_unreleased_keys(), None)