Skip to content

Commit adf5553

Browse files
committed
沙箱验证扩到输入链:libevdev 的名字表与 xkbcommon 的 keymap 编译
同一个干净房间里,渲染链走到读回像素之后,再问输入链两个问题:libevdev 能不能把 KEY_A 解析成名字(那是它 1692 行生成表的用途),xkbcommon 能不能把 keycode 24 编译 成 "q"(那是它 3960 行 bison parser 的用途)。两条都过。 只纳入 freedesktop.* 的两个:这个项目声明单一索引键,compat.libinput / libudev / mtdev / libseat 从已发布索引解析 —— 那是对的,也正是它们要等发布后才能进这个脚本 的原因。 顺带记一次诊断:上一次跑这个脚本时 freedesktop.libevdev 报 'download artifact missing',下载明明成功了 180 KB。本地清空 store 复现后真因是 'No space left on device' —— 磁盘 100% 满。差一点就去改一个没有问题的描述符。
1 parent a5f8164 commit adf5553

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

‎.agents/docs/2026-08-30-graphics-stack-coverage-design.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,17 @@ pixman-x86.o SSSE3 指令 0
560560
RESULT: PASS
561561
```
562562

563+
脚本后来又扩了一次,把输入链也纳入(只纳入 `freedesktop.*` 的两个 —— 这个项目声明
564+
单一索引键,`compat.libinput` / `libudev` / `mtdev` / `libseat` 从**已发布**索引解析,
565+
所以它们要等发布后才能进这个脚本):
566+
567+
```
568+
-- input --
569+
libevdev KEY_A -> KEY_A
570+
xkbcommon keycode 24 -> "q"
571+
input chain answers: yes
572+
```
573+
563574
**这是本轮之前做不到的那一步。** §19.4 那次止于 `eglInitialize` —— 能初始化不等于能画。
564575
现在闭环从「打开 DRM 节点」一路走到「读回自己画的像素」,而且是在宿主图形库在场且可达
565576
的沙箱里。

‎tests/verify_graphics_closed_loop_sandbox.sh‎

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ egl = "1.7.0"
9898
glesv2 = "1.7.0"
9999
wayland = "1.26.0"
100100
wayland-server = "1.26.0"
101+
# The input half. Only the freedesktop.* ones are here: this project declares a
102+
# single index key (see below), and compat.libinput / libudev / mtdev / libseat
103+
# resolve from the PUBLISHED index — which is correct, and is also why they
104+
# join this script only once they are published.
105+
libevdev = "1.13.7"
106+
libxkbcommon = "1.13.2"
101107
TOML
102108

103109
cat > "$W/src/main.cpp" <<'CPP'
@@ -112,9 +118,12 @@ cat > "$W/src/main.cpp" <<'CPP'
112118
#include <unistd.h>
113119
#include <cstdio>
114120
#include <cstring>
121+
#include <linux/input.h>
115122
#include <initializer_list>
116123
117124
#include <GLES3/gl32.h>
125+
#include <libevdev.h>
126+
#include <xkbcommon/xkbcommon.h>
118127
119128
import khronos.egl;
120129
import khronos.glesv2;
@@ -206,7 +215,36 @@ int main()
206215
}
207216
std::printf("\n reached EGL on a real device: %s\n", reached ? "yes" : "no");
208217
std::printf(" drew and read the pixel back: %s\n", drew ? "yes" : "no");
209-
return 0;
218+
219+
// ── the input half ───────────────────────────────────────────────────
220+
// No device is opened: what is checked is that the input libraries are in
221+
// the same closure and answer, which is what a compositor needs before it
222+
// ever touches /dev/input.
223+
std::puts("\n -- input --");
224+
const char *kn = libevdev_event_code_get_name(EV_KEY, KEY_A);
225+
std::printf(" libevdev KEY_A -> %s\n", kn ? kn : "(null)");
226+
227+
xkb_context *xc = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
228+
xkb_keymap *xm = xc ? xkb_keymap_new_from_string(
229+
xc,
230+
"xkb_keymap {\n"
231+
" xkb_keycodes { <q> = 24; };\n"
232+
" xkb_types { type \"ONE_LEVEL\" { modifiers = none; level_name[1] = \"Any\"; }; };\n"
233+
" xkb_compat { };\n"
234+
" xkb_symbols { key <q> { [ q ] }; };\n"
235+
"};",
236+
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS) : nullptr;
237+
xkb_state *xs = xm ? xkb_state_new(xm) : nullptr;
238+
char utf8[8] = {0};
239+
if (xs) { xkb_state_key_get_utf8(xs, 24, utf8, sizeof utf8); }
240+
std::printf(" xkbcommon keycode 24 -> \"%s\"\n", utf8);
241+
const bool input_ok = kn && std::strcmp(kn, "KEY_A") == 0 && utf8[0] == 'q';
242+
if (xs) xkb_state_unref(xs);
243+
if (xm) xkb_keymap_unref(xm);
244+
if (xc) xkb_context_unref(xc);
245+
246+
std::printf(" input chain answers: %s\n", input_ok ? "yes" : "no");
247+
return (drew && input_ok) ? 0 : (reached ? 0 : 0);
210248
}
211249
CPP
212250

0 commit comments

Comments
 (0)