mirror of
https://github.com/sezanzeb/input-remapper
synced 2024-11-04 12:00:16 +00:00
got rid of the confusing xkb keycode offset
This commit is contained in:
parent
d355806c5a
commit
8ac2092e74
@ -33,7 +33,7 @@ from evdev.ecodes import EV_KEY, EV_ABS
|
||||
|
||||
from keymapper.logger import logger
|
||||
from keymapper.getdevices import get_devices
|
||||
from keymapper.state import system_mapping, KEYCODE_OFFSET
|
||||
from keymapper.state import system_mapping
|
||||
from keymapper.dev.keycode_mapper import handle_keycode, \
|
||||
should_map_event_as_btn
|
||||
from keymapper.dev.ev_abs_mapper import ev_abs_mapper, JOYSTICK
|
||||
@ -144,7 +144,7 @@ class KeycodeInjector:
|
||||
needed = False
|
||||
for (ev_type, keycode), _ in self.mapping:
|
||||
# TODO test ev_type
|
||||
if keycode - KEYCODE_OFFSET in capabilities.get(ev_type, []):
|
||||
if keycode in capabilities.get(ev_type, []):
|
||||
needed = True
|
||||
break
|
||||
|
||||
@ -208,7 +208,7 @@ class KeycodeInjector:
|
||||
|
||||
keycode = system_mapping.get(character)
|
||||
if keycode is not None:
|
||||
capabilities[EV_KEY].append(keycode - KEYCODE_OFFSET)
|
||||
capabilities[EV_KEY].append(keycode)
|
||||
|
||||
if abs_to_rel:
|
||||
del capabilities[ecodes.EV_ABS]
|
||||
@ -315,7 +315,7 @@ class KeycodeInjector:
|
||||
'macro writes code:%s value:%d char:%s',
|
||||
keycode, value, character
|
||||
)
|
||||
uinput.write(EV_KEY, keycode - KEYCODE_OFFSET, value)
|
||||
uinput.write(EV_KEY, keycode, value)
|
||||
uinput.syn()
|
||||
|
||||
async def _keycode_loop(self, device, uinput, abs_to_rel):
|
||||
@ -340,8 +340,6 @@ class KeycodeInjector:
|
||||
logger.debug('Parsing macros')
|
||||
macros = {}
|
||||
for (ev_type, keycode), output in self.mapping:
|
||||
keycode -= KEYCODE_OFFSET
|
||||
|
||||
if '(' in output and ')' in output and len(output) >= 4:
|
||||
# probably a macro
|
||||
macros[keycode] = parse(
|
||||
@ -355,7 +353,7 @@ class KeycodeInjector:
|
||||
logger.error('Don\'t know what %s is', output)
|
||||
continue
|
||||
|
||||
code_code_mapping[keycode] = target_keycode - KEYCODE_OFFSET
|
||||
code_code_mapping[keycode] = target_keycode
|
||||
|
||||
logger.debug(
|
||||
'Started injecting into %s, fd %s',
|
||||
|
@ -27,7 +27,6 @@ import asyncio
|
||||
import evdev
|
||||
|
||||
from keymapper.logger import logger
|
||||
from keymapper.state import KEYCODE_OFFSET
|
||||
from keymapper.dev.ev_abs_mapper import JOYSTICK
|
||||
|
||||
|
||||
@ -60,8 +59,7 @@ def handle_keycode(code_code_mapping, macros, event, uinput):
|
||||
Parameters
|
||||
----------
|
||||
code_code_mapping : dict
|
||||
mapping of linux-keycode to linux-keycode. No need to substract
|
||||
anything before writing to the device.
|
||||
mapping of linux-keycode to linux-keycode.
|
||||
macros : dict
|
||||
mapping of linux-keycode to _Macro objects
|
||||
"""
|
||||
@ -72,10 +70,6 @@ def handle_keycode(code_code_mapping, macros, event, uinput):
|
||||
input_keycode = event.code
|
||||
input_type = event.type
|
||||
|
||||
# for logging purposes. It should log the same keycode as xev and gtk,
|
||||
# which is also displayed in the UI.
|
||||
xkb_keycode = input_keycode + KEYCODE_OFFSET
|
||||
|
||||
if input_keycode in macros:
|
||||
if event.value != 1:
|
||||
# only key-down events trigger macros
|
||||
@ -84,7 +78,7 @@ def handle_keycode(code_code_mapping, macros, event, uinput):
|
||||
macro = macros[input_keycode]
|
||||
logger.spam(
|
||||
'got code:%s value:%s, maps to macro %s',
|
||||
xkb_keycode,
|
||||
input_keycode,
|
||||
event.value,
|
||||
macro.code
|
||||
)
|
||||
@ -96,15 +90,15 @@ def handle_keycode(code_code_mapping, macros, event, uinput):
|
||||
target_type = evdev.events.EV_KEY
|
||||
logger.spam(
|
||||
'got code:%s value:%s event:%s, maps to EV_KEY:%s',
|
||||
xkb_keycode,
|
||||
input_keycode,
|
||||
event.value,
|
||||
evdev.ecodes.EV[event.type],
|
||||
target_keycode + KEYCODE_OFFSET
|
||||
target_keycode
|
||||
)
|
||||
else:
|
||||
logger.spam(
|
||||
'got unmapped code:%s value:%s',
|
||||
xkb_keycode,
|
||||
input_keycode,
|
||||
event.value,
|
||||
)
|
||||
target_keycode = input_keycode
|
||||
|
@ -30,7 +30,6 @@ import evdev
|
||||
|
||||
from keymapper.logger import logger
|
||||
from keymapper.getdevices import get_devices, refresh_devices
|
||||
from keymapper.state import KEYCODE_OFFSET
|
||||
from keymapper.dev.keycode_mapper import should_map_event_as_btn
|
||||
|
||||
|
||||
@ -114,11 +113,11 @@ class _KeycodeReader:
|
||||
if should_map_event_as_btn(event.type, event.code):
|
||||
logger.spam(
|
||||
'got code:%s value:%s type:%s',
|
||||
event.code + KEYCODE_OFFSET,
|
||||
event.code,
|
||||
event.value,
|
||||
evdev.ecodes.EV[event.type]
|
||||
)
|
||||
self._pipe[1].send((event.type, event.code + KEYCODE_OFFSET))
|
||||
self._pipe[1].send((event.type, event.code))
|
||||
|
||||
def _read_worker(self):
|
||||
"""Process that reads keycodes and buffers them into a pipe."""
|
||||
|
@ -63,15 +63,14 @@ class Mapping:
|
||||
Everything will be mapped to EV_KEY.
|
||||
new_keycode : int
|
||||
The source keycode, what the mouse would report without any
|
||||
modification. xkb keycode.
|
||||
modification.
|
||||
character : string or string[]
|
||||
A single character known to xkb, Examples: KP_1, Shift_L, a, B.
|
||||
Can also be an array, which is used for reading the xkbmap output
|
||||
completely.
|
||||
A single character known to xkb or linux.
|
||||
Examples: KP_1, Shift_L, a, B, BTN_LEFT.
|
||||
previous_keycode : int or None
|
||||
If None, will not remove any previous mapping. If you recently
|
||||
used 10 for new_keycode and want to overwrite that with 11,
|
||||
provide 5 here. xkb keycode.
|
||||
provide 5 here.
|
||||
"""
|
||||
try:
|
||||
new_keycode = int(new_keycode)
|
||||
@ -98,7 +97,6 @@ class Mapping:
|
||||
Parameters
|
||||
----------
|
||||
keycode : int
|
||||
the xkb keycode
|
||||
ev_type : int
|
||||
one of evdev.events
|
||||
"""
|
||||
|
@ -30,8 +30,8 @@ import evdev
|
||||
from keymapper.mapping import Mapping
|
||||
|
||||
|
||||
# offset between xkb and linux keycodes. linux keycodes are lower
|
||||
KEYCODE_OFFSET = 8
|
||||
# xkb uses keycodes that are 8 higher than those from evdev
|
||||
XKB_KEYCODE_OFFSET = 8
|
||||
|
||||
|
||||
def populate_system_mapping():
|
||||
@ -42,10 +42,10 @@ def populate_system_mapping():
|
||||
mappings = re.findall(r'(\d+) = (.+)\n', xmodmap)
|
||||
for keycode, names in mappings:
|
||||
for name in names.split():
|
||||
mapping[name] = int(keycode)
|
||||
mapping[name] = int(keycode) - XKB_KEYCODE_OFFSET
|
||||
|
||||
for name, ecode in evdev.ecodes.ecodes.items():
|
||||
mapping[name] = ecode + KEYCODE_OFFSET
|
||||
mapping[name] = ecode
|
||||
|
||||
return mapping
|
||||
|
||||
|
@ -149,8 +149,7 @@ class Event:
|
||||
type : int
|
||||
one of evdev.ecodes.EV_*
|
||||
code : int
|
||||
keyboard event code as known to linux. E.g. 2 for the '1' button,
|
||||
which would be 10 in xkb
|
||||
keyboard event code as known to linux. E.g. 2 for the '1' button
|
||||
value : int
|
||||
1 for down, 0 for up, 2 for hold
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
from keymapper.state import custom_mapping, system_mapping, \
|
||||
clear_system_mapping, KEYCODE_OFFSET
|
||||
clear_system_mapping
|
||||
from keymapper.config import config
|
||||
from keymapper.daemon import Daemon, get_dbus_interface, BUS_NAME
|
||||
|
||||
@ -97,7 +97,7 @@ class TestDaemon(unittest.TestCase):
|
||||
config.set_autoload_preset('device 2', preset)
|
||||
|
||||
pending_events['device 2'] = [
|
||||
Event(evdev.events.EV_KEY, keycode_from_1 - KEYCODE_OFFSET, 0),
|
||||
Event(evdev.events.EV_KEY, keycode_from_1, 0),
|
||||
]
|
||||
|
||||
self.daemon = Daemon()
|
||||
@ -108,15 +108,15 @@ class TestDaemon(unittest.TestCase):
|
||||
|
||||
event = uinput_write_history_pipe[0].recv()
|
||||
self.assertEqual(event.type, evdev.events.EV_KEY)
|
||||
self.assertEqual(event.code, keycode_to_1 - KEYCODE_OFFSET)
|
||||
self.assertEqual(event.code, keycode_to_1)
|
||||
self.assertEqual(event.value, 0)
|
||||
|
||||
self.daemon.stop_injecting('device 2')
|
||||
self.assertFalse(self.daemon.is_injecting('device 2'))
|
||||
|
||||
pending_events['device 2'] = [
|
||||
Event(evdev.events.EV_KEY, keycode_from_2 - KEYCODE_OFFSET, 1),
|
||||
Event(evdev.events.EV_KEY, keycode_from_2 - KEYCODE_OFFSET, 0),
|
||||
Event(evdev.events.EV_KEY, keycode_from_2, 1),
|
||||
Event(evdev.events.EV_KEY, keycode_from_2, 0),
|
||||
]
|
||||
|
||||
time.sleep(0.2)
|
||||
@ -126,12 +126,12 @@ class TestDaemon(unittest.TestCase):
|
||||
|
||||
event = uinput_write_history_pipe[0].recv()
|
||||
self.assertEqual(event.type, evdev.events.EV_KEY)
|
||||
self.assertEqual(event.code, keycode_to_2 - KEYCODE_OFFSET)
|
||||
self.assertEqual(event.code, keycode_to_2)
|
||||
self.assertEqual(event.value, 1)
|
||||
|
||||
event = uinput_write_history_pipe[0].recv()
|
||||
self.assertEqual(event.type, evdev.events.EV_KEY)
|
||||
self.assertEqual(event.code, keycode_to_2 - KEYCODE_OFFSET)
|
||||
self.assertEqual(event.code, keycode_to_2)
|
||||
self.assertEqual(event.value, 0)
|
||||
|
||||
|
||||
|
@ -30,12 +30,12 @@ from keymapper.dev.injector import is_numlock_on, toggle_numlock,\
|
||||
ensure_numlock, KeycodeInjector
|
||||
from keymapper.dev.keycode_mapper import handle_keycode
|
||||
from keymapper.state import custom_mapping, system_mapping, \
|
||||
clear_system_mapping, KEYCODE_OFFSET
|
||||
clear_system_mapping
|
||||
from keymapper.mapping import Mapping
|
||||
from keymapper.config import config
|
||||
from keymapper.dev.macros import parse
|
||||
|
||||
from tests.test import uinput_write_history, Event, pending_events, fixtures, \
|
||||
from tests.test import Event, pending_events, fixtures, \
|
||||
clear_write_history, EVENT_READ_TIMEOUT, uinput_write_history_pipe, \
|
||||
MAX_ABS
|
||||
|
||||
@ -81,7 +81,7 @@ class TestInjector(unittest.TestCase):
|
||||
character='a'
|
||||
)
|
||||
|
||||
maps_to = system_mapping['a'] - KEYCODE_OFFSET
|
||||
maps_to = system_mapping['a']
|
||||
|
||||
self.injector = KeycodeInjector('foo', mapping)
|
||||
fake_device = FakeDevice()
|
||||
@ -302,14 +302,14 @@ class TestInjector(unittest.TestCase):
|
||||
# keycode used in X and in the mappings
|
||||
pending_events['device 2'] = [
|
||||
# should execute a macro
|
||||
Event(EV_KEY, 0, 1),
|
||||
Event(EV_KEY, 0, 0),
|
||||
Event(EV_KEY, 8, 1),
|
||||
Event(EV_KEY, 8, 0),
|
||||
# normal keystroke
|
||||
Event(EV_KEY, 1, 1),
|
||||
Event(EV_KEY, 1, 0),
|
||||
Event(EV_KEY, 9, 1),
|
||||
Event(EV_KEY, 9, 0),
|
||||
# just pass those over without modifying
|
||||
Event(EV_KEY, 2, 1),
|
||||
Event(EV_KEY, 2, 0),
|
||||
Event(EV_KEY, 10, 1),
|
||||
Event(EV_KEY, 10, 0),
|
||||
Event(3124, 3564, 6542),
|
||||
]
|
||||
|
||||
@ -334,30 +334,30 @@ class TestInjector(unittest.TestCase):
|
||||
# keystrokes are all over the place.
|
||||
# just check if they are there and if so, remove them from the list.
|
||||
ev_key = EV_KEY
|
||||
self.assertIn((ev_key, code_q - KEYCODE_OFFSET, 1), history)
|
||||
self.assertIn((ev_key, code_q - KEYCODE_OFFSET, 0), history)
|
||||
self.assertIn((ev_key, code_w - KEYCODE_OFFSET, 1), history)
|
||||
self.assertIn((ev_key, code_w - KEYCODE_OFFSET, 0), history)
|
||||
index_q_1 = history.index((ev_key, code_q - KEYCODE_OFFSET, 1))
|
||||
index_q_0 = history.index((ev_key, code_q - KEYCODE_OFFSET, 0))
|
||||
index_w_1 = history.index((ev_key, code_w - KEYCODE_OFFSET, 1))
|
||||
index_w_0 = history.index((ev_key, code_w - KEYCODE_OFFSET, 0))
|
||||
self.assertIn((ev_key, code_q, 1), history)
|
||||
self.assertIn((ev_key, code_q, 0), history)
|
||||
self.assertIn((ev_key, code_w, 1), history)
|
||||
self.assertIn((ev_key, code_w, 0), history)
|
||||
index_q_1 = history.index((ev_key, code_q, 1))
|
||||
index_q_0 = history.index((ev_key, code_q, 0))
|
||||
index_w_1 = history.index((ev_key, code_w, 1))
|
||||
index_w_0 = history.index((ev_key, code_w, 0))
|
||||
self.assertGreater(index_q_0, index_q_1)
|
||||
self.assertGreater(index_w_1, index_q_0)
|
||||
self.assertGreater(index_w_0, index_w_1)
|
||||
del history[index_q_1]
|
||||
index_q_0 = history.index((ev_key, code_q - KEYCODE_OFFSET, 0))
|
||||
index_q_0 = history.index((ev_key, code_q, 0))
|
||||
del history[index_q_0]
|
||||
index_w_1 = history.index((ev_key, code_w - KEYCODE_OFFSET, 1))
|
||||
index_w_1 = history.index((ev_key, code_w, 1))
|
||||
del history[index_w_1]
|
||||
index_w_0 = history.index((ev_key, code_w - KEYCODE_OFFSET, 0))
|
||||
index_w_0 = history.index((ev_key, code_w, 0))
|
||||
del history[index_w_0]
|
||||
|
||||
# the rest should be in order.
|
||||
self.assertEqual(history[0], (ev_key, code_a - KEYCODE_OFFSET, 1))
|
||||
self.assertEqual(history[1], (ev_key, code_a - KEYCODE_OFFSET, 0))
|
||||
self.assertEqual(history[2], (ev_key, input_b - KEYCODE_OFFSET, 1))
|
||||
self.assertEqual(history[3], (ev_key, input_b - KEYCODE_OFFSET, 0))
|
||||
self.assertEqual(history[0], (ev_key, code_a, 1))
|
||||
self.assertEqual(history[1], (ev_key, code_a, 0))
|
||||
self.assertEqual(history[2], (ev_key, input_b, 1))
|
||||
self.assertEqual(history[3], (ev_key, input_b, 0))
|
||||
self.assertEqual(history[4], (3124, 3564, 6542))
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
from keymapper.state import custom_mapping, system_mapping, \
|
||||
clear_system_mapping, KEYCODE_OFFSET
|
||||
clear_system_mapping
|
||||
from keymapper.paths import CONFIG, get_config_path
|
||||
from keymapper.config import config
|
||||
from keymapper.dev.reader import keycode_reader
|
||||
@ -408,8 +408,8 @@ class TestIntegration(unittest.TestCase):
|
||||
system_mapping['a'] = keycode_to
|
||||
|
||||
pending_events['device 2'] = [
|
||||
Event(evdev.events.EV_KEY, keycode_from - KEYCODE_OFFSET, 1),
|
||||
Event(evdev.events.EV_KEY, keycode_from - KEYCODE_OFFSET, 0)
|
||||
Event(evdev.events.EV_KEY, keycode_from, 1),
|
||||
Event(evdev.events.EV_KEY, keycode_from, 0)
|
||||
]
|
||||
|
||||
custom_mapping.save('device 2', 'foo preset')
|
||||
@ -428,12 +428,12 @@ class TestIntegration(unittest.TestCase):
|
||||
|
||||
event = uinput_write_history_pipe[0].recv()
|
||||
self.assertEqual(event.type, evdev.events.EV_KEY)
|
||||
self.assertEqual(event.code, keycode_to - KEYCODE_OFFSET)
|
||||
self.assertEqual(event.code, keycode_to)
|
||||
self.assertEqual(event.value, 1)
|
||||
|
||||
event = uinput_write_history_pipe[0].recv()
|
||||
self.assertEqual(event.type, evdev.events.EV_KEY)
|
||||
self.assertEqual(event.code, keycode_to - KEYCODE_OFFSET)
|
||||
self.assertEqual(event.code, keycode_to)
|
||||
self.assertEqual(event.value, 0)
|
||||
|
||||
def test_stop_injecting(self):
|
||||
@ -446,7 +446,7 @@ class TestIntegration(unittest.TestCase):
|
||||
|
||||
# not all of those events should be processed, since that takes some
|
||||
# time due to time.sleep in the fakes and the injection is stopped.
|
||||
pending_events['device 2'] = [Event(1, keycode_from - KEYCODE_OFFSET, 1)] * 100
|
||||
pending_events['device 2'] = [Event(1, keycode_from, 1)] * 100
|
||||
|
||||
custom_mapping.save('device 2', 'foo preset')
|
||||
|
||||
|
@ -35,10 +35,8 @@ class TestMapping(unittest.TestCase):
|
||||
# not actually a mapping object, just a dict
|
||||
mapping = populate_system_mapping()
|
||||
self.assertGreater(len(mapping), 100)
|
||||
# xkb keycode 10 is typically mapped to '1'
|
||||
self.assertEqual(mapping['1'], 10)
|
||||
# linux keycodes are properly increased to the xkb keycodes
|
||||
self.assertEqual(mapping['KEY_1'], 10)
|
||||
self.assertEqual(mapping['1'], 2)
|
||||
self.assertEqual(mapping['KEY_1'], 2)
|
||||
self.assertEqual(mapping['KEY_LEFTSHIFT'], mapping['Shift_L'])
|
||||
|
||||
def test_clone(self):
|
||||
|
@ -25,7 +25,6 @@ from evdev.events import EV_KEY
|
||||
import time
|
||||
|
||||
from keymapper.dev.reader import keycode_reader
|
||||
from keymapper.state import KEYCODE_OFFSET
|
||||
|
||||
from tests.test import Event, pending_events, EVENT_READ_TIMEOUT
|
||||
|
||||
@ -58,7 +57,7 @@ class TestReader(unittest.TestCase):
|
||||
keycode_reader._pipe[0].send((EV_KEY, 1234))
|
||||
|
||||
time.sleep(EVENT_READ_TIMEOUT * 5)
|
||||
self.assertEqual(keycode_reader.read(), (EV_KEY, CODE_3 + KEYCODE_OFFSET))
|
||||
self.assertEqual(keycode_reader.read(), (EV_KEY, CODE_3))
|
||||
self.assertEqual(keycode_reader.read(), (None, None))
|
||||
|
||||
def test_wrong_device(self):
|
||||
@ -106,7 +105,7 @@ class TestReader(unittest.TestCase):
|
||||
keycode_reader.start_reading('device 1')
|
||||
time.sleep(EVENT_READ_TIMEOUT * 5)
|
||||
|
||||
self.assertEqual(keycode_reader.read(), (EV_KEY, CODE_3 + KEYCODE_OFFSET))
|
||||
self.assertEqual(keycode_reader.read(), (EV_KEY, CODE_3))
|
||||
self.assertEqual(keycode_reader.read(), (None, None))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user