<div align="center">
<h1>vncrs</h1>
<p><strong>Stream your Windows desktop with near-zero latency, multi-core dirty tracking, and native ZRLE compression.</strong></p>
<p>
<a href="https://crates.io/crates/vncrs"><img src="https://img.shields.io/crates/v/vncrs.svg?style=flat-square&color=blue" alt="Crates.io"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-green.svg?style=flat-square" alt="License: MIT"></a>
<a href="https://www.rust-lang.org/"><img src="https://img.shields.io/badge/Rust-2021%20Edition-orange.svg?style=flat-square&logo=rust" alt="Rust: 2021"></a>
<a href="https://microsoft.com/windows"><img src="https://img.shields.io/badge/Platform-Windows%2010%2B-0078D6.svg?style=flat-square&logo=windows" alt="Platform: Windows"></a>
<a href="https://github.com/maybewewill/vncrs"><img src="https://img.shields.io/badge/Safety-100%25%20Bounds--Safe-success.svg?style=flat-square" alt="Safety: 100% Safe"></a>
</p>
<p>
<a href="#quick-start">Quick Start</a> ·
<a href="#why-vncrs">Why vncrs</a> ·
<a href="#features">Features</a> ·
<a href="#examples">Examples</a> ·
<a href="#performance">Performance</a> ·
<a href="#extensibility">Extensibility</a>
</p>
</div>
---
## Why vncrs
Traditional VNC servers on Windows (like TigerVNC, TightVNC, or UltraVNC) rely on heavy C++ installers, legacy GDI display hooks, or continuous full-frame CPU diffing that hogs 15–25% of your processor.
`vncrs` solves this with a modern, pure Rust architecture:
- **0ms CPU dirty detection** by reading hardware damage hints directly from the Windows Desktop Window Manager (DWM) compositor.
- **Zero-copy frame swapping** using a buffer ping-pong pool that eliminates gigabytes of memory copies per second.
- **Multi-core Rayon fallback** with 128-bit SIMD chunk diffing when hardware hints are unavailable.
- **Instant embeddability** into any Rust application with a single `cargo add vncrs`.
---
## Features
- **Zero-Copy Capture Pipeline** — Windows Graphics Capture (WGC) frames are swapped via pointer exchange, recycling allocations with zero heap churn and no redundant zeroing memsets.
- **TigerVNC Continuous Updates Push Engine** — Full support for RFB pseudo-encoding `-313` and Fence `-312`. Streams frames continuously at display refresh rate without waiting for client RTT pull requests.
- **Tight Encoding with SIMD JPEG & Palette** — Prioritizes RFB Tight (ID 7) with instant solid fill (`0x80`), SIMD-accelerated JPEG (`0x90`) for video/gradients, and palette deflate for UI/text.
- **Hardware-Driven Dirty Rects** — Consumes native compositor damage regions, cutting dirty scanning CPU usage to nearly 0%.
- **SIMD 32-Byte Diffing & Fast Sampling** — 32-byte chunk vector diffing and 5-point tile fast rejection when hardware compositor hints are absent.
- **Native ZRLE & SIMD Zlib Compression** — Hardware-accelerated `zlib-rs` deflate engine with 128-bit solid tile fast path, achieving up to 95% bandwidth reduction.
- **Rect Coalescing** — Merges adjacent and overlapping damage tiles to minimize protocol packet overhead and zlib stream flushes.
- **Full Input Injection** — Mouse movement, 4-way scrolling, control keys, and full Cyrillic/Unicode keyboard mapping via [`enigo`](https://crates.io/crates/enigo).
- **Hardened Against DoS** — Bounded message parsers (prevents OOM exploits), constant-time challenge auth, and no misaligned pointer casts.
---
## When to Use
- **Use `vncrs` when:** You need high-FPS, low-latency remote desktop streaming on Windows without installing heavy third-party services, or want to embed remote desktop sharing inside your own Rust app or bot.
- **Not for:** Linux/macOS display servers (this crate leverages Windows Graphics Capture and Windows input synthesis APIs).
---
## Quick Start
### 1. Add dependency
```bash
cargo add vncrs
```
### 2. Run minimal server
```rust
use vncrs::{VncServer, VncServerConfig};
use vncrs::capture::windows::WindowsCapture;
use vncrs::input::enigo_input::EnigoInput;
fn main() -> vncrs::Result<()> {
let config = VncServerConfig::new()
.port(5900)
.password("secret")
.name("My Workstation")
.max_fps(60);
let capture = WindowsCapture::new()?;
let input = EnigoInput::new();
let mut server = VncServer::new(capture, input, config);
server.listen()
}
```
### 3. Connect
Connect with any standard VNC viewer:
```bash
vncviewer 127.0.0.1:5900
```
---
## Examples
Three ready-to-run examples are included:
### Simple Server
Minimal server listening on port 5900:
```bash
cargo run --example simple_server
```
### Headless / View-Only Server
Shares your screen with remote input strictly disabled:
```bash
cargo run --example headless
```
### Full CLI Server
Feature-complete command-line server with CLI flags:
```bash
cargo run --example full_server -- --port 5900 --password secret --fps 60 --name "Workstation"
```
| `-p, --port <PORT>` | `5900` | TCP listen port |
| `--password <PASS>` | `None` | Access password (max 8 characters per RFB standard) |
| `-n, --name <NAME>` | `"Rust VNC"` | Display name broadcasted to connecting viewers |
| `--fps <FPS>` | `60` | Max frame rate (1–240 FPS) |
| `--view-only` | `false` | Disallow remote keyboard and mouse input |
| `-v, --verbose` | `false` | Enable structured log output |
---
## Performance
### Encoding Efficiency Matrix
| **Tight** | `7` | **Standard high-FPS streaming, video & 3D (TigerVNC, Remmina, noVNC)** | **Exceptional (~90-98% reduction)** | Ultra-Low (Instant solid fill & SIMD JPEG) |
| **ZRLE** | `16` | UI/Desktop text with lossless requirements | Highest lossless (~95% reduction) | Ultra-Low (128-bit solid tile fast path) |
| **Hextile** | `5` | Low-latency local networks | Moderate (~60% reduction) | Minimal |
| **Zlib** | `6` | Streaming over constrained connections | High (~80% reduction) | Moderate |
| **Raw** | `0` | Loopback / ultra-high bandwidth | 0% (raw BGRA stream) | Zero |
### Architectural Highlights
- **Hardware Compositor Dirty Hints:** Unlike legacy servers that compute pixel-by-pixel diffs on the CPU, `vncrs` reads dirty regions reported by the Windows compositor D3D11 surface.
- **Zero-Copy Ring Pool:** Framebuffers are swapped via `std::mem::swap` between the capture worker thread and the server session loop, preventing megabytes of `memcpy` per frame.
- **Rect Coalescing Engine:** Blends fragmented damage tiles into optimized bounding boxes, drastically cutting down TCP packet headers and zlib stream resets.
---
## Configuration
`VncServerConfig` uses a type-safe builder pattern:
```rust
let config = vncrs::VncServerConfig::new()
.port(5900)
.password("pass1234")
.name("Gaming Rig")
.max_fps(144) // Clamped to [1, 240]
.tile_size(64); // Clamped to [16, 256]
```
### Graceful Programmatic Shutdown
```rust
use std::sync::atomic::Ordering;
let server = vncrs::VncServer::new(capture, input, config);
let running = server.running_flag();
ctrlc::set_handler(move || {
running.store(false, Ordering::Relaxed);
}).ok();
server.listen()?;
```
---
## Extensibility
### Custom `ScreenCapture`
Feed frames from DirectX games, virtual monitors, or custom pipelines:
```rust
pub trait ScreenCapture {
fn width(&self) -> u16;
fn height(&self) -> u16;
fn stride(&self) -> usize;
/// Swap buffer with zero allocations. Returns Ok(true) if a fresh frame is ready.
fn swap_frame(&mut self, buf: &mut Vec<u8>) -> vncrs::Result<bool>;
/// Optional hardware dirty rect hints from compositor
fn take_dirty_hints(&mut self, _out: &mut Vec<CaptureRect>) -> bool { false }
}
```
### Custom `InputHandler`
Direct remote control events to an isolated sandbox or game automation framework:
```rust
pub trait InputHandler {
fn move_mouse(&mut self, x: u16, y: u16);
fn mouse_button(&mut self, button: u8, pressed: bool);
fn scroll(&mut self, direction: ScrollDirection);
fn key_event(&mut self, keysym: u32, down: bool);
}
```
---
## Security
1. **Network Boundary:** Standard VNC (RFB 3.8) challenge-response authentication uses 56-bit DES without transport layer encryption. For untrusted public networks, route through an **SSH tunnel** or **WireGuard / Tailscale VPN**:
```bash
ssh -L 5900:127.0.0.1:5900 user@remote-windows-host
```
2. **View-Only Mode:** Pass `vncrs::input::NoopInput` when only observation is needed to lock out any remote input injection.
3. **Memory Safety:** Every packet parser enforces strict bounds (e.g. 1 MB limit on clipboard text) to neutralize remote buffer allocation attacks.
---
## License
Distributed under the [MIT License](LICENSE).