Skip to content

Commit 0587f98

Browse files
committed
upgrade the input detection module to look for keyboard like devices
set a threshold at 50 keys as certain devices may have key event capabilities but are not a proper keyboard. Signed-off-by: Zen <[email protected]>
1 parent 61a7035 commit 0587f98

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

src/ugrd/kmod/input.py

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,58 @@
1-
__version__ = "0.1.0"
1+
__version__ = "0.2.0"
2+
3+
from pathlib import Path
24

3-
from zenlib.util import contains
45
from zenlib.util import colorize as c_
6+
from zenlib.util import contains
7+
8+
9+
def _count_bits(hex_str):
10+
"""Counts the number of bits set in a hexadecimal string."""
11+
count = 0
12+
for char in hex_str:
13+
try:
14+
count += bin(int(char, 16)).count("1")
15+
except ValueError:
16+
# Handle non-hexadecimal characters
17+
pass
18+
return count
519

620

721
@contains("kmod_autodetect_input")
822
def autodetect_input(self):
9-
""" Adds _input_device_kmods to "_kmod_auto" if they are in /proc/modules"""
10-
with open("/proc/modules", "r") as f:
11-
modules = f.read()
23+
"""Looks through /sys/class/input/input*/capabilities/,
24+
looks for the "key" capability, checks how many keys are defined.
25+
If more than keyboard_key_threshold keys are defined, it assumes that the device is a keyboard.
26+
adds the resolved path of device/driver to _kmod_auto.
27+
28+
If the input device path has "/usb" in it, enable the ugrd.kmod.usb module.
29+
"""
30+
found_keyboard = False
31+
for input_dev in Path("/sys/class/input").glob("input*"):
32+
key_cap_path = input_dev / "capabilities" / "key"
33+
if key_cap_path.exists():
34+
keyboard_name = (input_dev / "name").read_text().strip()
35+
enabled_keys = _count_bits(key_cap_path.read_text().splitlines()[0].strip())
36+
if enabled_keys < self.keyboard_key_threshold:
37+
self.logger.debug(
38+
f"[{input_dev.name}:{c_(keyboard_name, 'blue')}] Not enough keys detected: {c_(enabled_keys, 'yellow')} < {self.keyboard_key_threshold}"
39+
)
40+
continue
41+
keyboard_driver = (input_dev / "device" / "driver").resolve().name
42+
self.logger.info(f"[{c_(keyboard_name, 'blue')}] Detected driver: {c_(keyboard_driver, 'cyan')}")
43+
self._kmod_auto = [keyboard_driver]
44+
found_keyboard = True
45+
46+
if "ugrd.kmod.usb" in self["modules"]:
47+
continue
1248

13-
for input_kmod in self["_input_device_kmods"]:
14-
if input_kmod in modules:
15-
self["_kmod_auto"] = input_kmod
16-
self.logger.info(f"Autodetected input device kernel module: {c_(input_kmod, 'cyan')}")
49+
# Check for USB devices if the USB module is not already enabled
50+
for part in input_dev.parts:
51+
if part.startswith("usb") and "ugrd.kmod.usb" not in self["modules"]:
52+
self.logger.info(f"Detected USB device, enabling ugrd.kmod.usb: {c_(input_dev.name, 'cyan')}")
53+
self["modules"] = "ugrd.kmod.usb"
54+
break
1755

56+
# Maybe raise an exception once detection is more well tested
57+
if not found_keyboard:
58+
self.logger.warning(f"Unable to detect a keyboard with keyboard_key_threshold is set to: {c_(self.keyboard_key_threshold, 'yellow')}")

src/ugrd/kmod/input.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
kmod_autodetect_input = true
2-
_input_device_kmods = [ "hid_apple", "hid_generic", "usbhid" ]
2+
keyboard_key_threshold = 25
33

44
[imports.build_enum]
55
"ugrd.kmod.input" = [ "autodetect_input" ]
@@ -9,4 +9,4 @@ _input_device_kmods = [ "hid_apple", "hid_generic", "usbhid" ]
99

1010
[custom_parameters]
1111
kmod_autodetect_input = "bool" # Whether or not to detect input devices
12-
_input_device_kmods = "NoDupFlatList" # List of input device kernel modules
12+
keyboard_key_threshold = "int" # Number of keys on a keyboard device to be detected as a keyboard

0 commit comments

Comments
 (0)