Windows support: linkctl-panel native GUI control panel#6
Open
jfwoods wants to merge 1 commit into
Open
Conversation
A single lightweight Win32 C executable (zero external dependencies) that replaces both the daemon and the CLI on Windows: - Camera control via DirectShow + kernel streaming: pan/tilt/center through the UVC extension unit (IKsControl/KSP_NODE), zoom through IAMCameraControl. The XU guidExtensionCode is discovered at runtime by parsing the USB config descriptor via the parent hub, so no vendor GUID is hardcoded. - GUI: hold-to-move D-pad (mouse or arrow keys), pan/tilt speed sliders, zoom slider (+/- keys), center gimbal (center -> stop -> zoom reset, matching the CLI), stop, status line with camera state and ESP32 client count, 5s auto-reconnect. - ESP32 keeps working: hand-rolled RFC 6455 WebSocket server on port 9000 (own SHA-1/Base64, arduino subprotocol echo, ping/pong) with JSON dispatch identical to the Mac daemon, advertised over mDNS via Windows built-in DnsServiceRegister (Win10 1809+). - CI builds the panel on windows-latest; releases ship a zip. The portable pieces (ws.c framing/handshake incl. the RFC 6455 worked example, json.c) are unit-tested; full build verified with MinGW-w64. https://claude.ai/code/session_019SjPJMQax1zDYcYSde7rT4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports the project to Windows as a single lightweight native executable,
host/linkctl-panel/— a GUI control panel that replaces both the daemon and the CLI on Windows. Pure Win32 C, zero external dependencies, no installer; the stripped binary is ~100 KB. No viewfinder (MVP) — it's a controller, so the camera stays usable in Teams/OBS/etc. while the panel drives it.Camera control (
camera.c)Windows'
usbvideo.sysowns the camera, so the macOS approach (raw class-specific control transfers via IOKit) is impossible. Instead:IKsControl::KsPropertywith aKSP_NODEtargeting the dev-specific topology node. Windows addresses XUs byguidExtensionCoderather than unit ID, so the GUID is discovered at runtime by reading the camera's USB configuration descriptor through its parent hub (SetupAPI +IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION) and parsing the VC extension-unit descriptor forbUnitID 0x09— nothing vendor-specific is hardcoded. The topology node is found viaIKsTopologyInfo+ a basic-support probe.IAMCameraControl, linearly mapped between the driver-reported range and the 100–400 protocol range.camera_*calls are serialized by an internalCRITICAL_SECTION(GUI thread vs. server thread), mirroring the Mac daemon'scamera_mutexrule.GUI (
gui.c)+/-keys; Center gimbal runs center → stop → zoom reset, the same sequence aslinkctl center(per the drift gotcha); Stop button /Space/Esc--consoleflag attaches a console for the[camera]/[server]logsESP32 keeps working
selectloop; own SHA-1/Base64 for the handshake; echoes thearduinosubprotocol; handles ping/pong/close)pan_tilt,zoom,stop,center,status) and responses match the Mac daemon'sserver.cexactly, including the[0,1,0,1]stop-payload rule and the on-connect status push_insta360ctrl._tcpvia Windows' built-inDnsServiceRegister(Win10 1809+) — no Bonjour installCI / docs
windows-latestCI job (the commented-out placeholder, now real) builds with MSVC and uploads the.exe; the release workflow ships a versioned zipwinioctl.hbeforeusbioctl.h, C-compatible localIKsControldeclarations)Testing
ws.c,json.c) is unit-tested natively — 31 checks including the RFC 6455 §1.3 worked example for the accept key, masked-frame decode, partial-frame handling, and ESP32-shaped JSON commandslinkctl-panel.exe --consolewill show exactly which stage fails if anything does.https://claude.ai/code/session_019SjPJMQax1zDYcYSde7rT4
Generated by Claude Code