#ifndef VMCTL_DRIVER_H #define VMCTL_DRIVER_H #include "vmctl.h" #include "qmp.h" /* driver.h — input-driver vtable, the concrete vmctl handle, and the shared * event-kind enum. The event kind is the SINGLE source of truth that every * driver switches on (never on magic numbers). */ typedef enum { VMCTL_EV_REL, VMCTL_EV_BTN, VMCTL_EV_KEY, VMCTL_EV_SCROLL } vmctl_ev_kind; typedef struct { int (*send)(vmctl_t* v, const vmctl_batch* b); /* deliver an input batch */ void (*close)(vmctl_t* v); /* release driver resources */ } vmctl_driver_ops; struct vmctl { vmctl_driver_ops ops; vmctl_driver driver; qmp_conn* qmp; /* control channel; NULL if none */ int ui_fd_a; /* uinput driver: device A (keyboard); -1 for QMP */ int ui_fd_b; /* uinput driver: device B (relative mouse); -1 */ char ui_evdev_a[64]; /* uinput driver: /dev/input/eventN of A ("" if none) */ char ui_evdev_b[64]; /* uinput driver: /dev/input/eventN of B ("" if none) */ /* Held-state receipt: key/btn down-bits as THIS handle last actuated them * (not guest truth). Written only after a successful send in * vmctl_batch_send; the send path never reads them. Zero-initialised by * calloc at open = all up. Single-threaded (one handle owner): no locks. */ unsigned char keys_held[VMCTL_KEYS_SNAPSHOT_BYTES]; /* evdev-indexed key down-bits */ unsigned btns_held; /* VMCTL_BTN_* 0..7 down-bits */ }; /* driver factories (called from open.c per cfg->driver) */ vmctl_t* vmctl_open_qmp_driver (const vmctl_config* cfg); vmctl_t* vmctl_open_uinput_driver(const vmctl_config* cfg); #endif /* VMCTL_DRIVER_H */