mirror of
https://dev.lirent.ru/Vatrog/vm-automation-signaling.git
synced 2026-06-25 20:36:36 +03:00
d6c45ddb04
The uinput devices the input adapter creates were never forwarded into the guest: the input-linux bridge was external (manual monitor object_add), so it was lost on every reconfigure and whenever the kernel-assigned device numbers changed. Make the vmhost seam -- which already owns the VM's single QMP connection -- add the input-linux objects itself on reaching READY (A=keyboard +abs with grab_all, B=mouse) and object_del them on teardown. The input adapter publishes the uinput evdev paths into a per-endpoint home; discovery attaches input before vmhost so the paths are ready. No second QMP socket or connection. Also move the mouse buttons (incl. middle) and the wheel onto device B, so B is a complete relative mouse and A is keyboard+abs only. Bump 0.3.8.
62 lines
3.2 KiB
C
62 lines
3.2 KiB
C
/* test_uinputlayout.c — DECLARATIVE uinput capability split (pure, no /dev/uinput).
|
|
*
|
|
* Verifies the ptr_mode -> A/B role mapping that drives both device creation and the hot-path
|
|
* button/wheel carrier selection: in PTR_BOTH A is keyboard+abs and B is rel+buttons+wheel, and
|
|
* the button/wheel carrier is B; single-pointer modes keep buttons+wheel on the sole device.
|
|
* The actuation ioctls remain armed-only (they need a real /dev/uinput); this covers the logic
|
|
* that decides the layout, which is the part that single-mode regressions would break. */
|
|
#include "vmctl.h"
|
|
#include "uinput_layout.h"
|
|
#include <stdio.h>
|
|
|
|
static int g_fail = 0;
|
|
#define CHECK(cond, msg) do { \
|
|
if (!(cond)) { printf(" FAIL: %s\n", (msg)); g_fail = 1; } \
|
|
} while (0)
|
|
|
|
int main(void) {
|
|
uinput_role a, b; int btn_on_b;
|
|
|
|
/* PTR_BOTH: A = keyboard + absolute pointer, no buttons/wheel; B = relative pointer +
|
|
* buttons + wheel; carrier is B. This is the requested layout (mouse buttons incl. middle
|
|
* and the wheel moved off A onto B). */
|
|
vmctl_uinput_layout(VMCTL_PTR_BOTH, &a, &b, &btn_on_b);
|
|
CHECK(a.present && b.present, "BOTH: two devices");
|
|
CHECK(a.want_keyboard, "BOTH: A has keyboard");
|
|
CHECK(!a.rel_motion, "BOTH: A is absolute");
|
|
CHECK(!a.want_buttons, "BOTH: A has NO mouse buttons");
|
|
CHECK(!a.want_wheel, "BOTH: A has NO wheel");
|
|
CHECK(!b.want_keyboard, "BOTH: B has no keyboard");
|
|
CHECK(b.rel_motion, "BOTH: B is relative");
|
|
CHECK(b.want_buttons, "BOTH: B has mouse buttons");
|
|
CHECK(b.want_wheel, "BOTH: B has wheel");
|
|
CHECK(btn_on_b == 1, "BOTH: button/wheel carrier is B");
|
|
|
|
/* PTR_REL: single relative device A carries motion + buttons + wheel (no B). */
|
|
vmctl_uinput_layout(VMCTL_PTR_REL, &a, &b, &btn_on_b);
|
|
CHECK(a.present && !b.present, "REL: single device A");
|
|
CHECK(a.rel_motion, "REL: A is relative");
|
|
CHECK(a.want_buttons, "REL: A has buttons");
|
|
CHECK(a.want_wheel, "REL: A has wheel");
|
|
CHECK(a.want_keyboard, "REL: A has keyboard");
|
|
CHECK(btn_on_b == 0, "REL: carrier is A");
|
|
|
|
/* PTR_ABS: single absolute device A carries abs + buttons + wheel (the only device). */
|
|
vmctl_uinput_layout(VMCTL_PTR_ABS, &a, &b, &btn_on_b);
|
|
CHECK(a.present && !b.present, "ABS: single device A");
|
|
CHECK(!a.rel_motion, "ABS: A is absolute");
|
|
CHECK(a.want_buttons, "ABS: A has buttons (sole device)");
|
|
CHECK(a.want_wheel, "ABS: A has wheel (sole device)");
|
|
CHECK(btn_on_b == 0, "ABS: carrier is A");
|
|
|
|
/* evdev export contract: a NULL handle reports "not a uinput handle" (-1). The populated
|
|
* path (real /dev/input/eventN) is armed-only — it needs a created uinput device. */
|
|
{
|
|
char ea[64], eb[64];
|
|
CHECK(vmctl_uinput_evdev(NULL, ea, eb) == -1, "evdev export: NULL handle -> -1");
|
|
}
|
|
|
|
printf("uinputlayout tests: %s\n", g_fail ? "FAIL" : "PASS");
|
|
return g_fail ? 1 : 0;
|
|
}
|