mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-09 20:27:41 +08:00
chore(gdb): add LVIndev wrapper with gen_indev_consts and dump indev command
This commit is contained in:
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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())
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user