absinfo for older evdev versions

pull/14/head
sezanzeb 4 years ago
parent 8e6276492b
commit de9b3cbaef

@ -63,11 +63,11 @@ def accumulate(pending, current):
return pending, current
def abs_max(a, b):
def abs_max(value_1, value_2):
"""Get the value with the higher abs value."""
if abs(a) > abs(b):
return a
return b
if abs(value_1) > abs(value_2):
return value_1
return value_2
def get_values(abs_state, left_purpose, right_purpose):
@ -115,7 +115,18 @@ async def ev_abs_mapper(abs_state, input_device, keymapper_device, mapping):
mapping : Mapping
the mapping object that configures the current injection
"""
max_value = input_device.absinfo(EV_ABS).max
# since input_device.absinfo(EV_ABS).max is too new for ubuntu,
# figure out the max value via the capabilities
absinfos = [
entry[1] for entry in
input_device.capabilities(absinfo=True)[EV_ABS]
if isinstance(entry, tuple) and isinstance(entry[1], evdev.AbsInfo)
]
if len(absinfos) == 0:
return
max_value = absinfos[0].max
if max_value == 0:
return

@ -256,11 +256,12 @@ class KeycodeInjector:
evdev.ecodes.REL_Y,
evdev.ecodes.REL_WHEEL,
]
if capabilities.get(EV_KEY) is None:
capabilities[EV_KEY] = []
# for reasons I don't know, it is also required to have
# any keyboard button in capabilities.
capabilities[EV_KEY].append(ecodes.KEY_0)
keys = capabilities.get(EV_KEY)
if keys is None or len(keys) == 0:
# for reasons I don't know, it is also required to have
# any keyboard button in capabilities. Maybe they intended to
# check for the mouse-button code.
capabilities[EV_KEY] = [ecodes.BTN_MOUSE]
# just like what python-evdev does in from_device
if ecodes.EV_SYN in capabilities:

@ -41,9 +41,9 @@ for name in system_mapping.list_names():
def to_string(ev_type, code, value):
"""A nice to show description of the pressed key."""
try:
name = evdev.ecodes.bytype[ev_type][code]
if isinstance(name, list):
name = name[0]
key_name = evdev.ecodes.bytype[ev_type][code]
if isinstance(key_name, list):
key_name = key_name[0]
if ev_type != evdev.ecodes.EV_KEY:
direction = {
@ -61,9 +61,9 @@ def to_string(ev_type, code, value):
(evdev.ecodes.ABS_HAT2Y, 1): 'D',
}.get((code, value))
if direction is not None:
name += f' {direction}'
key_name += f' {direction}'
return name.replace('KEY_', '')
return key_name.replace('KEY_', '')
except KeyError:
return 'unknown'
@ -180,9 +180,9 @@ class Row(Gtk.ListBoxRow):
previous_key=None
)
def match(self, completion, key, iter):
def match(self, completion, key, tree_iter):
"""Search the avilable names."""
value = store.get_value(iter, 0)
value = store.get_value(tree_iter, 0)
return key in value.lower()
def put_together(self, character):

@ -112,6 +112,9 @@ def log_info():
name = pkg_resources.require('key-mapper')[0].project_name
version = pkg_resources.require('key-mapper')[0].version
logger.info('%s %s', name, version)
evdev_version = pkg_resources.require('evdev')[0].version
logger.info('python-evdev %s', evdev_version)
except pkg_resources.DistributionNotFound as error:
logger.info('Could not figure out the version')
logger.debug(error)

@ -104,8 +104,6 @@ fixtures = {
},
'/dev/input/event30': {
# this device is expected to not have EV_KEY capabilities in tests
# yet. Only when the injector is running EV_KEY stuff is added
'capabilities': {
evdev.ecodes.EV_SYN: [],
evdev.ecodes.EV_ABS: [
@ -114,6 +112,9 @@ fixtures = {
evdev.ecodes.ABS_RX,
evdev.ecodes.ABS_RY,
evdev.ecodes.ABS_HAT0X
],
evdev.ecodes.EV_KEY: [
evdev.ecodes.BTN_A
]
},
'phys': 'usb-0000:03:00.0-3/input1',
@ -228,17 +229,9 @@ class InputDevice:
self.phys = fixtures[path]['phys']
self.name = fixtures[path]['name']
self.fd = self.name
self.capa = copy.deepcopy(fixtures[self.path]['capabilities'])
def absinfo(axis):
return {
evdev.ecodes.EV_ABS: evdev.AbsInfo(
value=None, min=None, fuzz=None, flat=None,
resolution=None, max=MAX_ABS
)
}[axis]
self.absinfo = absinfo
def absinfo(self, *args):
raise Exception('Ubuntus version of evdev doesn\'t support .absinfo')
def grab(self):
pass
@ -280,7 +273,18 @@ class InputDevice:
await asyncio.sleep(0.01)
def capabilities(self, absinfo=True):
return self.capa
result = copy.deepcopy(fixtures[self.path]['capabilities'])
if absinfo and evdev.ecodes.EV_ABS in result:
absinfo_obj = evdev.AbsInfo(
value=None, min=None, fuzz=None, flat=None,
resolution=None, max=MAX_ABS
)
result[evdev.ecodes.EV_ABS] = [
(stuff, absinfo_obj) for stuff in result[evdev.ecodes.EV_ABS]
]
return result
class UInput:
@ -336,6 +340,7 @@ patch_select()
from keymapper.logger import update_verbosity
from keymapper.dev.injector import KeycodeInjector
from keymapper.config import config
from keymapper.getdevices import refresh_devices
from keymapper.state import system_mapping, custom_mapping
from keymapper.dev.keycode_mapper import active_macros
@ -343,21 +348,36 @@ from keymapper.dev.keycode_mapper import active_macros
KeycodeInjector.regrab_timeout = 0.15
_fixture_copy = copy.deepcopy(fixtures)
def cleanup():
"""Reset the applications state."""
os.system('pkill -f key-mapper-service')
if os.path.exists(tmp):
shutil.rmtree(tmp)
config.clear_config()
config.save_config()
system_mapping.populate()
custom_mapping.empty()
clear_write_history()
for key in list(active_macros.keys()):
del active_macros[key]
for key in list(pending_events.keys()):
del pending_events[key]
for path in list(fixtures.keys()):
if path not in _fixture_copy:
del fixtures[path]
for path in list(_fixture_copy.keys()):
if path not in fixtures:
fixtures[path] = _fixture_copy[path]
refresh_devices()
def main():
update_verbosity(True)

@ -86,10 +86,6 @@ class TestDaemon(unittest.TestCase):
self.daemon = None
evdev.InputDevice.grab = self.grab
if fixtures.get(self.new_fixture):
del fixtures[self.new_fixture]
refresh_devices()
cleanup()
def test_daemon(self):

@ -58,11 +58,15 @@ class TestEvAbsMapper(unittest.TestCase):
self.mapping.clear_config()
loop = asyncio.get_event_loop()
for task in asyncio.Task.all_tasks():
task.cancel()
try:
for task in asyncio.Task.all_tasks():
task.cancel()
loop.stop()
loop.close()
except RuntimeError:
pass
loop.stop()
loop.close()
clear_write_history()
def do(self, a, b, c, d, expectation):

@ -21,6 +21,7 @@
import unittest
import time
import copy
import evdev
from evdev.ecodes import EV_REL, EV_KEY, EV_ABS, ABS_HAT0X
@ -38,6 +39,8 @@ from tests.test import InputEvent, pending_events, fixtures, \
class TestInjector(unittest.TestCase):
new_gamepad = '/dev/input/event100'
@classmethod
def setUpClass(cls):
cls.injector = None
@ -59,6 +62,7 @@ class TestInjector(unittest.TestCase):
self.injector.stop_injecting()
self.injector = None
evdev.InputDevice.grab = self.grab
cleanup()
def test_modify_capabilities(self):
@ -168,8 +172,33 @@ class TestInjector(unittest.TestCase):
self.assertNotIn(evdev.ecodes.EV_ABS, capabilities)
self.assertIn(evdev.ecodes.EV_REL, capabilities)
self.assertIn(evdev.ecodes.EV_KEY, capabilities)
self.assertEqual(len(capabilities[evdev.ecodes.EV_KEY]), 1)
def test_adds_ev_key(self):
# for some reason, having any EV_KEY capability is needed to
# be able to control the mouse
# be able to control the mouse. it probably wants the mouse click.
self.injector = KeycodeInjector('gamepad 2', custom_mapping)
path = self.new_gamepad
gamepad_template = copy.deepcopy(fixtures['/dev/input/event30'])
fixtures[path] = {
'name': 'gamepad 2',
'phys': 'abcd',
'capabilities': gamepad_template['capabilities']
}
del fixtures[path]['capabilities'][EV_KEY]
device, abs_to_rel = self.injector._prepare_device(path)
self.assertNotIn(evdev.ecodes.EV_KEY, device.capabilities())
capabilities = self.injector._modify_capabilities(
{},
device,
abs_to_rel
)
self.assertIn(evdev.ecodes.EV_KEY, capabilities)
self.assertEqual(len(capabilities[evdev.ecodes.EV_KEY]), 1)

@ -21,13 +21,43 @@
import unittest
import evdev
from evdev.ecodes import EV_ABS, EV_KEY
from keymapper.getdevices import get_devices
from tests.test import InputDevice, cleanup, fixtures
class TestTest(unittest.TestCase):
def test_stubs(self):
self.assertIn('device 1', get_devices())
def test_fake_capabilities(self):
device = InputDevice('/dev/input/event30')
capabilities = device.capabilities(absinfo=False)
self.assertIsInstance(capabilities, dict)
self.assertIsInstance(capabilities[EV_ABS], list)
self.assertIsInstance(capabilities[EV_ABS][0], int)
capabilities = device.capabilities()
self.assertIsInstance(capabilities, dict)
self.assertIsInstance(capabilities[EV_ABS], list)
self.assertIsInstance(capabilities[EV_ABS][0], tuple)
self.assertIsInstance(capabilities[EV_ABS][0][0], int)
self.assertIsInstance(capabilities[EV_ABS][0][1], evdev.AbsInfo)
self.assertIsInstance(capabilities[EV_ABS][0][1].max, int)
self.assertIsInstance(capabilities, dict)
self.assertIsInstance(capabilities[EV_KEY], list)
self.assertIsInstance(capabilities[EV_KEY][0], int)
def test_restore_fixtures(self):
fixtures[1] = [1234]
del fixtures['/dev/input/event11']
cleanup()
self.assertIsNone(fixtures.get(1))
self.assertIsNotNone(fixtures.get('/dev/input/event11'))
if __name__ == "__main__":
unittest.main()

Loading…
Cancel
Save