chore(gdb): add LVIndev wrapper with gen_indev_consts and dump indev command

This commit is contained in:
Benign X
2026-03-06 03:51:30 +08:00
committed by VIFEX
parent b93ef79422
commit 435b8c7b51
10 changed files with 256 additions and 2 deletions
+4
View File
@@ -38,6 +38,8 @@ from .lvgl import (
LVTimer,
LVImageDecoder,
LVFsDrv,
LVIndev,
INDEV_TYPE_NAMES,
)
from . import cmds as cmds
@@ -79,4 +81,6 @@ __all__ = [
"LVTimer",
"LVImageDecoder",
"LVFsDrv",
"LVIndev",
"INDEV_TYPE_NAMES",
]
+2 -1
View File
@@ -1,6 +1,6 @@
import gdb
from .core import DumpObj
from .core import DumpObj, DumpIndev
from .display import DumpDisplayBuf
from .draw import InfoDrawUnit, DumpDrawTask
from .misc import (
@@ -38,6 +38,7 @@ DumpAnim()
DumpTimer()
DumpImageDecoder()
DumpFsDrv()
DumpIndev()
DumpDrawTask()
# Infos
@@ -1,5 +1,7 @@
from .lv_obj import DumpObj
from .lv_indev import DumpIndev
__all__ = [
"DumpObj",
"DumpIndev",
]
+16
View File
@@ -0,0 +1,16 @@
import gdb
from lvglgdb.lvgl import curr_inst
from lvglgdb.lvgl.core.lv_indev import LVIndev
class DumpIndev(gdb.Command):
"""dump all input devices"""
def __init__(self):
super(DumpIndev, self).__init__(
"dump indev", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
)
def invoke(self, args, from_tty):
LVIndev.print_entries(curr_inst().indevs())
+11 -1
View File
@@ -1,4 +1,12 @@
from .core import LVObject, ObjStyle, curr_inst, dump_obj_info, dump_obj_styles
from .core import (
LVObject,
ObjStyle,
curr_inst,
dump_obj_info,
dump_obj_styles,
LVIndev,
INDEV_TYPE_NAMES,
)
from .display import LVDisplay
from .draw import (
LVDrawBuf,
@@ -84,4 +92,6 @@ __all__ = [
"LVTimer",
"LVImageDecoder",
"LVFsDrv",
"LVIndev",
"INDEV_TYPE_NAMES",
]
@@ -1,5 +1,6 @@
from .lv_obj import LVObject, ObjStyle, dump_obj_info, dump_obj_styles
from .lv_global import curr_inst
from .lv_indev import LVIndev, INDEV_TYPE_NAMES
__all__ = [
"LVObject",
@@ -7,4 +8,6 @@ __all__ = [
"curr_inst",
"dump_obj_info",
"dump_obj_styles",
"LVIndev",
"INDEV_TYPE_NAMES",
]
@@ -73,6 +73,12 @@ class LVGL:
for timer in LVList(self.lv_global.timer_state.timer_ll, "lv_timer_t"):
yield LVTimer(timer)
def indevs(self):
from .lv_indev import LVIndev
for indev in LVList(self.lv_global.indev_ll, "lv_indev_t"):
yield LVIndev(indev)
def image_decoders(self):
from ..misc.lv_image_decoder import LVImageDecoder
+109
View File
@@ -0,0 +1,109 @@
from prettytable import PrettyTable
from lvglgdb.value import Value, ValueInput
from .lv_indev_consts import INDEV_TYPE_NAMES
class LVIndev(Value):
"""LVGL input device wrapper"""
def __init__(self, indev: ValueInput):
super().__init__(Value.normalize(indev, "lv_indev_t"))
@property
def type(self) -> int:
return int(self.super_value("type"))
@property
def type_name(self) -> str:
return INDEV_TYPE_NAMES.get(self.type, f"UNKNOWN({self.type})")
@property
def state(self) -> int:
return int(self.super_value("state"))
@property
def enabled(self) -> bool:
return bool(int(self.super_value("enabled")))
@property
def long_press_time(self) -> int:
return int(self.super_value("long_press_time"))
@property
def scroll_limit(self) -> int:
return int(self.super_value("scroll_limit"))
@property
def scroll_throw(self) -> int:
return int(self.super_value("scroll_throw"))
@property
def long_press_repeat_time(self) -> int:
return int(self.super_value("long_press_repeat_time"))
@property
def read_cb(self) -> Value:
return self.super_value("read_cb")
@property
def read_timer(self) -> Value:
return self.super_value("read_timer")
@property
def disp(self) -> Value:
return self.super_value("disp")
@property
def group(self) -> Value:
return self.super_value("group")
@property
def cursor(self) -> Value:
return self.super_value("cursor")
@property
def user_data(self) -> Value:
return self.super_value("user_data")
@property
def driver_data(self) -> Value:
return self.super_value("driver_data")
@staticmethod
def print_entries(indevs):
"""Print input devices as a PrettyTable."""
table = PrettyTable()
table.field_names = [
"#",
"type",
"enabled",
"state",
"read_cb",
"long_press_time",
"scroll_limit",
"group",
]
table.align = "l"
for i, indev in enumerate(indevs):
cb_str = indev.read_cb.format_string(symbols=True)
grp = int(indev.group)
grp_str = f"0x{grp:x}" if grp else "-"
table.add_row(
[
i,
indev.type_name,
indev.enabled,
indev.state,
cb_str,
indev.long_press_time,
indev.scroll_limit,
grp_str,
]
)
if not table.rows:
print("No input devices.")
else:
print(table)
@@ -0,0 +1,14 @@
"""
Auto-generated indev constants from LVGL headers.
Do not edit manually. Regenerate with:
python3 scripts/gen_indev_consts.py
"""
INDEV_TYPE_NAMES = {
0: "NONE",
1: "POINTER",
2: "KEYPAD",
3: "BUTTON",
4: "ENCODER",
}
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""
Generate indev constant tables from LVGL header files.
Parses lv_indev.h for indev type enum.
Usage:
python3 scripts/gen_indev_consts.py
"""
import re
from pathlib import Path
SCRIPT_DIR = Path(__file__).parent
GDB_ROOT = SCRIPT_DIR.parent
LVGL_SRC = GDB_ROOT.parent.parent / "src"
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "core" / "lv_indev_consts.py"
INDEV_H = LVGL_SRC / "indev" / "lv_indev.h"
def parse_enum(path: Path, enum_type: str, prefix: str) -> dict[int, str]:
"""Parse a C enum from a header file."""
text = path.read_text()
pattern = rf"\}}\s*{re.escape(enum_type)}\s*;"
m = re.search(rf"typedef\s+enum\s*\{{(.*?){pattern}", text, re.DOTALL)
if not m:
raise RuntimeError(f"Cannot find {enum_type} enum in {path}")
entries = {}
current_val = 0
for line in m.group(1).splitlines():
line = line.strip().rstrip(",")
if (
not line
or line.startswith("/*")
or line.startswith("//")
or line.startswith("*")
or line.startswith("#")
):
continue
match = re.match(rf"({re.escape(prefix)}\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
if match:
name = match.group(1)
current_val = int(match.group(2), 0)
else:
match = re.match(rf"({re.escape(prefix)}\w+)", line)
if not match:
continue
name = match.group(1)
short = name.removeprefix(prefix)
entries[current_val] = short
current_val += 1
return entries
def generate(indev_types: dict[int, str]) -> str:
"""Generate Python source for the indev constants module."""
lines = [
'"""',
"Auto-generated indev constants from LVGL headers.",
"",
"Do not edit manually. Regenerate with:",
" python3 scripts/gen_indev_consts.py",
'"""',
"",
"INDEV_TYPE_NAMES = {",
]
for k in sorted(indev_types):
lines.append(f' {k}: "{indev_types[k]}",')
lines.append("}")
lines.append("")
return "\n".join(lines)
def main():
indev_types = parse_enum(INDEV_H, "lv_indev_type_t", "LV_INDEV_TYPE_")
src = generate(indev_types)
OUTPUT.write_text(src)
print(f"Generated {OUTPUT} ({len(indev_types)} indev types)")
if __name__ == "__main__":
main()