Skip to content
This repository has been archived by the owner on Dec 30, 2021. It is now read-only.

Hacking

ivanjermakov edited this page Sep 13, 2020 · 1 revision

Hacking

For a better understanding, see How it works section.

Evdev wrapper

KBMAP wrap evdev in two aspects:

  • physical keyboard functions (keyboard.py)
  • uinput event injection (host.py)

keyboard.py

keyboard.py is responsible for:

  • Grabbing and ungrabbing device
  • Listening for key events
  • Getting device by name

host.py

host.py is responsible for:

CLI entry

KBMAP using Click library to create CLI. CLI entry is in kbmap.py.

Mapper

All key mapping is performed by map_device() function. Function do:

  • Config load
  • Finding device by name
  • Grabbing device
  • Subscribing to device events and redirecting them to the handle_event function

Configuration load

Configuration management is performed by config.py.

Event handling

Event handling is performed by handle_event() function.

key vs action vs code

See Terminology. Basically, key lookup produce a key. It's either an action or a code. Action is handled with help of polymorphism (each action has handle() function), where code is handled with write_code() function.

Actions

Each action has handle function. It is invoked anytime that action is found during key lookup.

Some of the layer actions, such as LM action, need to perform additional behavior when some key pressed on its layer, while action is activated. This handled by handle_layer_key() function and invoked in write_code() function. Active layer actions are called activators.

Basic algorithm

  • Map event key code to position on physical layout. Position is just an index
  • Key lookup by position (see Key lookup)
  • Perform action handling (in case key is an action) or code injection (in case key is a code)

Action specific handling

Kbmap toggle action is additionally handled in handle_event function. If kbmap is disabled, device code is written directly to uinput.

Tap actions (Mod tap and Layer tap) need last_press_timestamps in order to determine how much time passed after the key activation.

Layer actions need active_layers to work properly. active_layers hold the state of layers. When new layer is activated, it override active_layers[layer_index] with itself.

Layer actions need active_keys_pressed to determine which keys to release when layer is disabled.

Key lookup

Active key is a key at pos on the highest active layer which is not KC_TRANSPARENT. Layers with higher index has greater precedence. Base layer (with index 0) is always active. If no key found, LookupError raised.

Logging

Logging is performed by log.py. Logger write messages to standard output through click.echo(). Global variable debug_enabled will determine whether debug() messages will be written.