Per-subsystem hook control: install/remove input, focus, audio at runtime
Add a host->hook control channel (protocol v5 -> v6: HookControl in SharedBlock, per-subsystem "disabled" flags, 0 = install so the zero-filled default is unchanged). The worker now reconciles each subsystem every tick: install what's requested-and-missing, remove what's no longer wanted -- so the audio hooks re-attach the ring and republish format on a reinstall, and XInput/focus clear their stale status flags on removal. Injection panel: a checkbox per subsystem (input forwarding / focus spoof / audio render-hook) toggles it at runtime, showing the requested vs actual installed state from the registry, plus DLL heartbeat liveness. The hook-status section now keys off whether a DLL was injected (host-side) rather than the input-hook "attached" flag, so it stays visible with input unhooked. Guards for dependent features: the synthetic-input control is disabled when input forwarding is off, and the Audio panel explains that mirroring uses loopback (echo) when the render-hook is off. Verified against Phantom Brave via coop_audio_probe: starting with audio requested off installs only input+focus (8 hooks, no capture); re-enabling at runtime installs the audio hooks (13) and capture starts immediately. All four tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ namespace coop
|
||||
|
||||
// Bump whenever the layout of SharedBlock or CoopPadState changes. The hook
|
||||
// refuses to attach to a host with a mismatched version.
|
||||
inline constexpr std::uint32_t kProtocolVersion = 5;
|
||||
inline constexpr std::uint32_t kProtocolVersion = 6;
|
||||
|
||||
// 'COOP' little-endian, used to sanity-check the mapping before trusting it.
|
||||
inline constexpr std::uint32_t kProtocolMagic = 0x504F4F43u;
|
||||
@@ -126,6 +126,14 @@ struct HookStatus
|
||||
HookEntry hook_entries[kMaxHookEntries];
|
||||
};
|
||||
|
||||
// Host -> hook control channel. The host requests which hook subsystems should be
|
||||
// installed; the hook reconciles each tick. 0 = install (the zero-filled default,
|
||||
// so a fresh mapping installs everything as before), 1 = remove.
|
||||
struct HookControl
|
||||
{
|
||||
std::atomic<std::uint32_t> subsystem_disabled[HookSubsys_Count];
|
||||
};
|
||||
|
||||
// Top-level shared block. The host is the sole writer of pad state; the hook is
|
||||
// the sole reader. A seqlock (even = stable, odd = write in progress) lets the
|
||||
// reader grab a torn-free snapshot without a kernel lock on the hot path.
|
||||
@@ -140,6 +148,9 @@ struct SharedBlock
|
||||
// Hook -> host diagnostics back-channel.
|
||||
HookStatus status;
|
||||
|
||||
// Host -> hook control (which subsystems to install).
|
||||
HookControl control;
|
||||
|
||||
// Phase 2 appends the shared-texture handle/dimensions control fields here;
|
||||
// keep new members at the end so existing offsets never shift.
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user