The need for KVM
I like my two big hi-res monitors. I love my keyboard and my mouse. And I connect them to my stationary “main” PC and to several other Windows and Mac laptops, alternatively. I’d like to easily switch where these peripheral devices are connected to, and that’s the traditional role of a KVM switch.
Unfortunately for me, KVM switches that support 4K/60hz resolutions cost hundreds of dollars, there are no KVM switches that support USB-C, and I couldn’t find KVM switches that support multiple high-res monitors either.
So I cheated!
So I decided to implement a mixed hardware/software solution: my monitors (all monitors today really) have more than one input, so I can connect all my computers simultaneously. The idea is:
- Switch USB devices in hardware.
- Detect this switch in software, and switch monitors inputs as needed.
To switch USB devices, I ordered this USB 3.0 two-computer switch from Amazon, that’s $38 Canadian, under $30 USD.
To automatically switch monitor inputs, I wrote some software.
Switching monitor inputs
My plan was:
- Watch for USB device connections/disconnections.
- When a configured device is connected, use DDC/CI to send a command to all connected monitors to switch inputs.
- In case the power management turned the video output off, turn it on again (otherwise the monitors will auto-switch back to the input that actually supplies video output).
I needed this to happen on Windows and on a Mac, and mature cross-platform support for USB low-level control and hot plug, DDC/CI and monitor power management is non-existent. I ended up implementing this two times: once in Swift, for MacOS, and the second time in Rust, for Windows.
Amazingly enough, this works really well: when I press the button on the USB switch, monitor input is changed instantaneously, it feels like a “real” KVM switch! 🎉