Files
rustguac/build.rs
T
Dave Kempe 3bf1762d87 v0.9.0: RDP audio, GFX pipeline, video performance
Audio:
- RDP audio output now works through guacamole. Advertise audio/L16
  and audio/L8 mimetypes in the guacd handshake, and explicitly set
  disable-audio=false. Fixed mimetype mismatch that silently prevented
  guacd from creating audio streams.
- Browser AudioContext auto-resumed on user interaction (click/keydown)
  to comply with autoplay policy.

Video performance:
- Per-entry GFX pipeline toggle (enable_gfx) — enables RemoteFX codec
- Per-entry desktop composition toggle (enable_desktop_composition)
- Per-entry force lossless toggle (force_lossless) — PNG-only mode
- WebSocket proxy buffer increased from 8KB to 64KB
- Video Performance section in address book UI for RDP entries

Documentation:
- RDP Video Performance guide with Windows server tuning (AVC444,
  60fps, GPU encoding) and Linux xrdp setup (Debian 13)
- contrib/setup-xrdp-gfx.sh — automated GFX/H.264 setup for xrdp
- contrib/setup-xrdp-audio.sh — automated PulseAudio module build
2026-03-24 20:25:05 +11:00

73 lines
2.1 KiB
Rust

use pulldown_cmark::{html, Options, Parser};
use std::fs;
use std::io::Write;
use std::path::Path;
/// Ordered list of doc files to render.
const DOC_FILES: &[&str] = &[
"overview.md",
"installation.md",
"configuration.md",
"credential-variables.md",
"reports.md",
"rdp-video-performance.md",
"web-sessions.md",
"security.md",
"roles-and-access-control.md",
"integrations.md",
"netbox.md",
"migration.md",
"api.md",
];
fn main() {
println!("cargo::rerun-if-changed=docs/");
let out_dir = std::env::var("OUT_DIR").unwrap();
let out_path = Path::new(&out_dir).join("docs-rendered.rs");
let mut out = fs::File::create(&out_path).expect("Failed to create docs-rendered.rs");
writeln!(out, "pub const DOCS: &[(&str, &str, &str)] = &[").unwrap();
for filename in DOC_FILES {
let path = Path::new("docs").join(filename);
let md = match fs::read_to_string(&path) {
Ok(s) => s,
Err(e) => {
eprintln!("cargo:warning=Could not read {}: {}", path.display(), e);
continue;
}
};
// Derive slug from filename (strip .md)
let slug = filename.trim_end_matches(".md");
// Extract title from first # heading
let title = md
.lines()
.find(|l| l.starts_with("# "))
.map(|l| l.trim_start_matches("# ").trim())
.unwrap_or(slug);
// Render markdown to HTML
let opts =
Options::ENABLE_TABLES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_TASKLISTS;
let parser = Parser::new_ext(&md, opts);
let mut html_output = String::new();
html::push_html(&mut html_output, parser);
// Escape for Rust string literal
let escaped = html_output
.replace('\\', "\\\\")
.replace('"', "\\\"")
.replace('\n', "\\n")
.replace('\r', "");
let title_escaped = title.replace('\\', "\\\\").replace('"', "\\\"");
writeln!(out, " (\"{slug}\", \"{title_escaped}\", \"{escaped}\"),").unwrap();
}
writeln!(out, "];").unwrap();
}