fix: complete the docs/→design/ and openapi→api/ rename references
The file moves (docs/ → design/, docs/api/openapi.json → api/openapi.json) landed
in 8897286, but the matching reference updates did not — so mgmt.rs's drift-test
`include_str!("../../../docs/api/openapi.json")` pointed at a path that no longer
exists and the host failed to build. This restores it and updates every reference:
- mgmt.rs include_str! → ../../../api/openapi.json (fixes the build)
- web/orval.config.ts codegen target, web/Dockerfile, .dockerignore
- deb/rpm/Arch packaging install paths
- CLAUDE.md, the .gitea CI workflows, code doc-comments, design-doc cross-links
docs-site route URLs (/docs/...) untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -1,9 +1,9 @@
|
||||
# Root build context is used only by web/Dockerfile, which needs web/ and
|
||||
# docs/api/openapi.json. Allowlist those; keep everything else (target/, .git, crates)
|
||||
# api/openapi.json. Allowlist those; keep everything else (target/, .git, crates)
|
||||
# out of the context upload.
|
||||
*
|
||||
!web
|
||||
!docs/api/openapi.json
|
||||
!api/openapi.json
|
||||
web/node_modules
|
||||
web/.output
|
||||
web/dist
|
||||
|
||||
@@ -24,7 +24,7 @@ on:
|
||||
push:
|
||||
branches: [main]
|
||||
# The flatpak is the CLIENT — only rebuild when the client/core/manifest change, not on every
|
||||
# docs/host push (this is a heavy flatpak-builder run). Tags (v*, the client release) build too.
|
||||
# design/host push (this is a heavy flatpak-builder run). Tags (v*, the client release) build too.
|
||||
paths:
|
||||
- 'clients/linux/**'
|
||||
- 'crates/punktfunk-core/**'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# One-shot provisioning of the WDK + cargo-wdk onto the persistent self-hosted windows-amd64 runner, so
|
||||
# the all-Rust UMDF drivers can build there (docs/windows-host-rewrite.md, M0). The runner has the base
|
||||
# the all-Rust UMDF drivers can build there (design/windows-host-rewrite.md, M0). The runner has the base
|
||||
# Windows SDK + MSVC + LLVM + Rust but NOT the WDK (no km/wdf/iddcx headers) or cargo-wdk.
|
||||
#
|
||||
# Dispatch manually (workflow_dispatch). Idempotent: re-running is a near no-op once provisioned. The
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Windows driver workspace CI — runs on the self-hosted Windows runner (home-windows-1, host mode;
|
||||
# label windows-amd64). Part of the Windows-host rewrite (docs/windows-host-rewrite.md, M0).
|
||||
# label windows-amd64). Part of the Windows-host rewrite (design/windows-host-rewrite.md, M0).
|
||||
#
|
||||
# Stage 1 (this file): PROBE the runner's driver toolchain (WDK / EWDK / cargo-make / LLVM / the
|
||||
# inf2cat/stampinf/devgen/signtool tools) so we know what's provisioned BEFORE writing driver code,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Low-latency desktop/game streaming stack, Linux-first, with a shared Rust protocol core
|
||||
(`punktfunk-core`) exposed over a C ABI and native clients per platform. Full design:
|
||||
[`docs/implementation-plan.md`](docs/implementation-plan.md). Status table: `README.md`.
|
||||
[`design/implementation-plan.md`](design/implementation-plan.md). Status table: `README.md`.
|
||||
|
||||
## Where the work stands
|
||||
|
||||
@@ -104,9 +104,16 @@ Low-latency desktop/game streaming stack, Linux-first, with a shared Rust protoc
|
||||
captures the HDR desktop as FP16/Rgb10a2 (DDA FP16 for the secure desktop), the encoder forces HEVC
|
||||
Main10 + BT.2020 PQ (NVENC ABGR10/P010; AMF/QSV P010 + a swscale Rgb10a2→P010 fallback), the client
|
||||
auto-detects PQ from the HEVC VUI — gated by `PUNKTFUNK_10BIT` + client `VIDEO_CAP_10BIT`; **Windows
|
||||
host only** (the Linux host stays 8-bit, blocked upstream). **AMF/QSV is CI-green but not yet
|
||||
on-glass validated** (no AMD/Intel Windows box in the lab); NVENC is live-validated. Newer/less
|
||||
battle-tested than the Linux host. Packaging: `packaging/windows/`.
|
||||
host only** (the Linux host stays 8-bit, blocked upstream). **Vulkan-game HDR over the virtual
|
||||
display**: NVIDIA/AMD Vulkan ICDs refuse to *advertise* an HDR color space for a surface on an IddCx
|
||||
indirect display (so Vulkan games — Doom: The Dark Ages, id Tech, etc. — say "device does not support
|
||||
HDR"), even though the ICD happily *accepts + presents* a forced HDR swapchain there. A tiny always-on
|
||||
Vulkan **implicit layer** (`packaging/windows/pf-vkhdr-layer/`, `VK_LAYER_PUNKTFUNK_hdr_inject`)
|
||||
injects the `HDR10_ST2084`/scRGB surface formats into `vkGetPhysicalDeviceSurfaceFormats[2]KHR`,
|
||||
self-gated on the display's actual advanced-color state (no-op on SDR / real monitors); bundled +
|
||||
HKLM-registered by the installer. **Live-validated: Doom: The Dark Ages enables HDR over the virtual
|
||||
display.** **AMF/QSV is CI-green but not yet on-glass validated** (no AMD/Intel Windows box in the
|
||||
lab); NVENC is live-validated. Newer/less battle-tested than the Linux host. Packaging: `packaging/windows/`.
|
||||
|
||||
## What's left
|
||||
|
||||
@@ -245,8 +252,8 @@ bash crates/punktfunk-core/tests/c/run.sh # standalone C-ABI link + round-trip
|
||||
```
|
||||
|
||||
Generated artifacts are **checked in** and CI fails on drift: `include/punktfunk_core.h`
|
||||
(cbindgen from `punktfunk-core/src/abi.rs`) and `docs/api/openapi.json` (regenerate with
|
||||
`cargo run -p punktfunk-host -- openapi > docs/api/openapi.json`; spec lives in `mgmt.rs`).
|
||||
(cbindgen from `punktfunk-core/src/abi.rs`) and `api/openapi.json` (regenerate with
|
||||
`cargo run -p punktfunk-host -- openapi > api/openapi.json`; spec lives in `mgmt.rs`).
|
||||
|
||||
CI is Gitea Actions (`.gitea/workflows/`, guide: docs-site `ci.md`): `ci.yml` runs the
|
||||
workspace checks inside the `git.unom.io/unom/punktfunk-rust-ci` image plus web/docs-site
|
||||
|
||||
@@ -361,4 +361,4 @@ ever switched to a logged-in GUI session, re-adding macOS to the job's capture s
|
||||
- Mid-stream renegotiation (resolution change without reconnect) is designed-for but not
|
||||
implemented (the Welcome is one-shot today).
|
||||
- Host-side gamepad injection needs `/dev/uinput` access on the box (udev rule from
|
||||
`docs/linux-setup.md`).
|
||||
`design/linux-setup.md`).
|
||||
|
||||
@@ -276,7 +276,7 @@ pub mod frame {
|
||||
/// These were hand-duplicated as `OFF_*`/`SHM_*` constants in `inject/{gamepad,dualsense}_windows.rs`
|
||||
/// and (as bare literals — `*view.add(140)`) in the standalone `xusb-driver`/`dualsense-driver`
|
||||
/// workspaces, guarded only by "must match" comments — the top ABI-drift hazard the audit flagged
|
||||
/// (`docs/windows-host-rewrite.md` §2.7). Owning them here with `Pod` derives + `offset_of!`
|
||||
/// (`design/windows-host-rewrite.md` §2.7). Owning them here with `Pod` derives + `offset_of!`
|
||||
/// asserts makes a one-sided edit a compile error.
|
||||
///
|
||||
/// The host creates the section (privileged, permissive DACL so the restricted WUDFHost token can
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Input-desktop watcher (Windows) — the authoritative "normal vs secure desktop" signal for the
|
||||
//! two-process secure-desktop design (docs/windows-secure-desktop.md).
|
||||
//! two-process secure-desktop design (design/windows-secure-desktop.md).
|
||||
//!
|
||||
//! Windows switches the *input desktop* to "Winlogon" (the secure desktop) for UAC elevation, the
|
||||
//! lock screen and the login screen, and back to "Default" for the normal session. WGC captures only
|
||||
|
||||
@@ -562,7 +562,7 @@ impl IddPushCapturer {
|
||||
|
||||
/// Block (bounded) until the driver has ATTACHED to the host ring (`DRV_STATUS_OPENED`) **and published
|
||||
/// a first frame**, else fail so the caller can fall back to DDA (audit §5.1 +
|
||||
/// `docs/windows-host-rewrite.md` §2.5 — the GB1 game-capture fix).
|
||||
/// `design/windows-host-rewrite.md` §2.5 — the GB1 game-capture fix).
|
||||
///
|
||||
/// Requiring the first frame — not just the attach — catches the *reconnect-into-a-broken-state* case:
|
||||
/// a fullscreen game can leave the virtual display in a format/size that the driver's `publish()` guard
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Host-side WGC helper relay (Windows two-process secure-desktop design,
|
||||
//! docs/windows-secure-desktop.md — step 4).
|
||||
//! design/windows-secure-desktop.md — step 4).
|
||||
//!
|
||||
//! WGC won't activate under the SYSTEM account, so the SYSTEM host can't capture the normal desktop
|
||||
//! itself. Instead it spawns `punktfunk-host wgc-helper` in the **interactive user session** (so WGC works)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! environment before the host starts, and **for the knobs captured here the environment is constant for the
|
||||
//! process lifetime**, so a lazily-parsed global is equivalent to "parsed once at startup".
|
||||
//!
|
||||
//! **Goal-1 stages 1–2** (`docs/windows-host-rewrite.md` §2.2): stage 1 stood this up; stage 2 migrated the
|
||||
//! **Goal-1 stages 1–2** (`design/windows-host-rewrite.md` §2.2): stage 1 stood this up; stage 2 migrated the
|
||||
//! genuinely-constant operator/dispatch knobs onto it (the dispatch-disagreement bug class: `idd_push`,
|
||||
//! `capture_backend`, `encoder_pref`, `render_adapter`, `no_wgc`, the vdisplay backend select — plus the
|
||||
//! plan-named `secure_dda`/`idd_depth`/`zerocopy`/`ten_bit` and the multi-site `perf`/`compositor`/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Pairing crypto primitives (control plane only — distinct from `punktfunk_core`'s AES-GCM
|
||||
//! data-plane sealing). GameStream pairing uses: AES-128-**ECB** with **no padding**,
|
||||
//! SHA-256 (host appversion major ≥ 7), and RSA-PKCS1v15-SHA256 signatures. See the
|
||||
//! `serverinfo + pairing` section of `docs/research/gamestream-protocol-research.json`.
|
||||
//! `serverinfo + pairing` section of `design/research/gamestream-protocol-research.json`.
|
||||
|
||||
use aes::cipher::generic_array::GenericArray;
|
||||
use aes::cipher::{BlockDecrypt, BlockEncrypt, KeyInit};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! GameStream (P1) control plane — what a stock Moonlight/Artemis client talks to around
|
||||
//! the media streams: mDNS discovery, the nvhttp serverinfo + pairing HTTP(S) API, RTSP,
|
||||
//! and the ENet control stream. `tokio`/`axum` live here (control plane, I/O-bound — never
|
||||
//! the per-frame hot path; that is `punktfunk_core`'s P1 wire codec). See `docs/gamestream-host-plan.md`.
|
||||
//! the per-frame hot path; that is `punktfunk_core`'s P1 wire codec). See `design/gamestream-host-plan.md`.
|
||||
//!
|
||||
//! Status: P1.1 — mDNS `_nvstream._tcp` advertisement + `/serverinfo`. Pairing, RTSP, and
|
||||
//! the media streams follow (see the GameStream host task list / plan).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! The 4-phase GameStream pairing state machine (over HTTP), keyed by `uniqueid`. Proves
|
||||
//! both sides know the PIN (via the SHA-256(salt||pin) AES-ECB key) and own their certs
|
||||
//! (RSA signatures), then pins the client cert. The final `pairchallenge` happens over
|
||||
//! HTTPS (handled in `nvhttp`). Byte-exact spec: `docs/research/…-research.json`.
|
||||
//! HTTPS (handled in `nvhttp`). Byte-exact spec: `design/research/…-research.json`.
|
||||
|
||||
use super::cert::ServerIdentity;
|
||||
use super::crypto;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! `RTP_PACKET(12, big-endian) + reserved[4] + NV_VIDEO_PACKET(16, little-endian) + payload`
|
||||
//! and the frame's bitstream is prefixed with an 8-byte `video_short_frame_header_t`, then
|
||||
//! striped into ≤4 FEC blocks of ≤255 shards. Byte-exact spec:
|
||||
//! `docs/research/gamestream-protocol-research.json` (video plane).
|
||||
//! `design/research/gamestream-protocol-research.json` (video plane).
|
||||
//!
|
||||
//! FEC (P1.5): each block carries `m = ⌈k·pct/100⌉` Reed–Solomon parity shards generated by
|
||||
//! `punktfunk_core::fec::Gf8Coder` (the nanors-compatible Cauchy GF(2⁸) coder). Crucially, RS runs
|
||||
|
||||
@@ -109,7 +109,7 @@ pub(super) struct SwDeviceProfile<'a> {
|
||||
/// `profile.instance`). The returned `HSWDEVICE` owns it — `SwDeviceClose` removes it on drop, so the
|
||||
/// pad appears/disappears with the session and nothing persists.
|
||||
///
|
||||
/// **Game-detection identity** (see `docs/windows-dualsense-game-detection.md`). `HIDD_ATTRIBUTES`
|
||||
/// **Game-detection identity** (see `design/windows-dualsense-game-detection.md`). `HIDD_ATTRIBUTES`
|
||||
/// alone (VID/PID via the IOCTL) satisfies SDL/HIDAPI/RawInput, but a native PS5 path (libScePad-
|
||||
/// style raw HID) classifies the *connection type* by walking from the HID child to its parent
|
||||
/// (`CM_Get_Parent`) and string-matching `"USB"`/`"BTHENUM"` in that parent's
|
||||
|
||||
@@ -389,7 +389,7 @@ fn real_main() -> Result<()> {
|
||||
}
|
||||
// USER-session WGC helper (Windows two-process secure-desktop design): capture the EXISTING
|
||||
// SudoVDA via WGC + NVENC, stream AUs on stdout to the SYSTEM host. Spawned by the host
|
||||
// (CreateProcessAsUser), not run by hand. See docs/windows-secure-desktop.md.
|
||||
// (CreateProcessAsUser), not run by hand. See design/windows-secure-desktop.md.
|
||||
#[cfg(target_os = "windows")]
|
||||
Some("wgc-helper") => {
|
||||
let get = |flag: &str| {
|
||||
@@ -704,7 +704,7 @@ SPIKE OPTIONS:
|
||||
|
||||
NOTES:
|
||||
'portal' needs headless Sway + xdg-desktop-portal-wlr running in this session
|
||||
(see docs/linux-setup.md). 'synthetic' needs no capture session and always runs.
|
||||
(see design/linux-setup.md). 'synthetic' needs no capture session and always runs.
|
||||
Encoded AUs are written to a playable file AND (unless --no-loopback) fed through a
|
||||
punktfunk_core host→client loopback that reassembles and byte-verifies each one.
|
||||
Both 'serve' and 'punktfunk1-host' advertise the native service over mDNS
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! The API is versioned under `/api/v1` and described by an OpenAPI 3.1 document generated
|
||||
//! at compile time with `utoipa` — `punktfunk-host openapi` prints it for client codegen, the
|
||||
//! running server serves it at `/api/v1/openapi.json` plus interactive docs at `/api/docs`,
|
||||
//! and a copy is checked in at `docs/api/openapi.json` (a test fails if it drifts, like the
|
||||
//! and a copy is checked in at `api/openapi.json` (a test fails if it drifts, like the
|
||||
//! cbindgen header).
|
||||
//!
|
||||
//! Security: binds loopback by default, serves HTTPS with the host's identity cert, and requires
|
||||
@@ -164,7 +164,7 @@ fn api_router_parts() -> (Router<Arc<MgmtState>>, utoipa::openapi::OpenApi) {
|
||||
}
|
||||
|
||||
/// The OpenAPI document as pretty JSON — what `punktfunk-host openapi` prints and what is
|
||||
/// checked in at `docs/api/openapi.json` for client codegen.
|
||||
/// checked in at `api/openapi.json` for client codegen.
|
||||
pub fn openapi_json() -> String {
|
||||
let (_, api) = api_router_parts();
|
||||
let mut json = api.to_pretty_json().expect("serialize OpenAPI document");
|
||||
@@ -1663,14 +1663,14 @@ mod tests {
|
||||
serde_json::json!([{}])
|
||||
);
|
||||
|
||||
let checked_in = include_str!("../../../docs/api/openapi.json");
|
||||
let checked_in = include_str!("../../../api/openapi.json");
|
||||
// Compare content, not line-ending style: the generated `json` is LF (serde_json), but git
|
||||
// may check the file out CRLF on Windows.
|
||||
assert_eq!(
|
||||
json.trim().replace('\r', ""),
|
||||
checked_in.trim().replace('\r', ""),
|
||||
"docs/api/openapi.json is stale — regenerate with: \
|
||||
cargo run -p punktfunk-host -- openapi > docs/api/openapi.json"
|
||||
"api/openapi.json is stale — regenerate with: \
|
||||
cargo run -p punktfunk-host -- openapi > api/openapi.json"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2221,7 +2221,7 @@ fn virtual_stream(ctx: SessionContext) -> Result<()> {
|
||||
// Windows two-process secure-desktop path: when the host runs as SYSTEM (required for the secure
|
||||
// desktop + SendInput), WGC can't activate in-process, so we capture the normal desktop via a
|
||||
// helper spawned in the user session and relay its AUs. (Single-process WGC/DDA is used as the
|
||||
// user, and stays the path on Linux.) See docs/windows-secure-desktop.md.
|
||||
// user, and stays the path on Linux.) See design/windows-secure-desktop.md.
|
||||
#[cfg(target_os = "windows")]
|
||||
if plan.topology == crate::session_plan::SessionTopology::TwoProcessRelay {
|
||||
return virtual_stream_relay(ctx);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! `SessionPlan` — the per-session capture / topology / encoder decision, resolved **once** from
|
||||
//! [`HostConfig`](crate::config) (+ the handshake-negotiated bit depth) into a typed, logged value.
|
||||
//!
|
||||
//! **Goal-1 stage 3** (`docs/windows-host-rewrite.md` §2.2): before this, the Windows session decision was
|
||||
//! **Goal-1 stage 3** (`design/windows-host-rewrite.md` §2.2): before this, the Windows session decision was
|
||||
//! re-derived at three call sites — the capture backend inside `capture::capture_virtual_output`, the
|
||||
//! process topology in `punktfunk1::should_use_helper`, and the encode backend in
|
||||
//! `encode::windows_resolved_backend` — each reading [`config`](crate::config) independently, with no
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//! Raw C-ABI FFI (winmm/kernel32/dwmapi/avrt) rather than the `windows` crate so it builds without
|
||||
//! pulling new windows-rs features. No-op on non-Windows. Per-thread effects (MMCSS, execution
|
||||
//! state) auto-revert at thread exit (= session end); the process-wide bits revert at process exit.
|
||||
//! See `docs/host-latency-plan.md` Tier 3A.
|
||||
//! See `design/host-latency-plan.md` Tier 3A.
|
||||
|
||||
// Every `unsafe` block in this file carries a `// SAFETY:` proof; enforce it (unsafe-proof program).
|
||||
#![deny(clippy::undocumented_unsafe_blocks)]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//!
|
||||
//! Control surface: a device-interface-GUID + `CreateFileW` + `DeviceIoControl` IOCTL protocol, with
|
||||
//! the wire contract OWNED by [`pf_driver_proto::control`] (versioned + `#[repr(C)] Pod` structs,
|
||||
//! NOT the SudoVDA ABI). No DLL, no named pipe. See `docs/windows-host-rewrite.md`.
|
||||
//! NOT the SudoVDA ABI). No DLL, no named pipe. See `design/windows-host-rewrite.md`.
|
||||
//!
|
||||
//! This is a faithful clone of [`super::sudovda`] (the shipping fallback) repointed at the new driver:
|
||||
//! same reference-counted/lingering monitor lifecycle, same CCD isolation + active-mode forcing — those
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! USER-session WGC helper (Windows) — part of the two-process secure-desktop design
|
||||
//! (docs/windows-secure-desktop.md).
|
||||
//! (design/windows-secure-desktop.md).
|
||||
//!
|
||||
//! WGC won't activate under the SYSTEM account, but the host must run as SYSTEM for the secure
|
||||
//! desktop. So the SYSTEM host spawns THIS helper in the interactive user session
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ sidebar, and the landing page). It reads [`public/openapi.json`](public/openapi.
|
||||
|
||||
```sh
|
||||
# from the repo root — regenerate the spec, then copy the snapshot in:
|
||||
cargo run -p punktfunk-host -- openapi > docs/api/openapi.json
|
||||
cp docs/api/openapi.json docs-site/public/openapi.json
|
||||
cargo run -p punktfunk-host -- openapi > api/openapi.json
|
||||
cp api/openapi.json docs-site/public/openapi.json
|
||||
```
|
||||
|
||||
## Develop
|
||||
|
||||
@@ -94,7 +94,7 @@ package_punktfunk-host() {
|
||||
install -Dm0644 "$R/scripts/host.env.example" "$pkgdir/usr/share/punktfunk/host.env.example"
|
||||
install -Dm0644 "$R/packaging/bazzite/host.env" "$pkgdir/usr/share/punktfunk/host.env.bazzite"
|
||||
install -Dm0644 "$R/packaging/kde/host.env" "$pkgdir/usr/share/punktfunk/host.env.kde"
|
||||
install -Dm0644 "$R/docs/api/openapi.json" "$pkgdir/usr/share/punktfunk/openapi.json"
|
||||
install -Dm0644 "$R/api/openapi.json" "$pkgdir/usr/share/punktfunk/openapi.json"
|
||||
install -Dm0644 "$R/LICENSE-MIT" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-MIT"
|
||||
install -Dm0644 "$R/LICENSE-APACHE" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-APACHE"
|
||||
install -Dm0644 "$R/README.md" "$pkgdir/usr/share/doc/punktfunk-host/README.md"
|
||||
|
||||
@@ -257,7 +257,7 @@ journalctl --user -u punktfunk-host -f
|
||||
|
||||
> ⚠️ **There is no firewall script or firewall doc in the repo.** The ports below are derived
|
||||
> directly from the code constants (`crates/punktfunk-host/src/gamestream/mod.rs`, `mgmt.rs`) and
|
||||
> the GameStream-host port-map (`docs/gamestream-host-plan.md`). Treat the `firewall-cmd` lines as recommended-but-verified,
|
||||
> the GameStream-host port-map (`design/gamestream-host-plan.md`). Treat the `firewall-cmd` lines as recommended-but-verified,
|
||||
> not a checked-in script.
|
||||
|
||||
**GameStream / Moonlight ports** (fixed; Moonlight derives them from the HTTP base). These only apply
|
||||
|
||||
@@ -57,7 +57,7 @@ install -Dm0644 scripts/headless/punktfunk-sink.conf "$SHAREDIR/headless/punkt
|
||||
install -Dm0644 scripts/host.env.example "$SHAREDIR/host.env.example"
|
||||
install -Dm0644 packaging/bazzite/host.env "$SHAREDIR/host.env.bazzite"
|
||||
install -Dm0644 packaging/kde/host.env "$SHAREDIR/host.env.kde"
|
||||
install -Dm0644 docs/api/openapi.json "$SHAREDIR/openapi.json"
|
||||
install -Dm0644 api/openapi.json "$SHAREDIR/openapi.json"
|
||||
install -Dm0644 LICENSE-MIT "$DOCDIR/LICENSE-MIT"
|
||||
install -Dm0644 LICENSE-APACHE "$DOCDIR/LICENSE-APACHE"
|
||||
install -Dm0644 README.md "$DOCDIR/README.md"
|
||||
|
||||
@@ -224,7 +224,7 @@ install -Dm0644 packaging/kde/host.env %{buildroot}%{_datadir}/%
|
||||
# Bazzite KDE Desktop-mode one-shot setup (KWIN_WAYLAND_NO_PERMISSION_CHECKS + RemoteDesktop grant).
|
||||
install -d %{buildroot}%{_datadir}/%{name}/bazzite
|
||||
install -Dm0755 packaging/bazzite/kde-desktop-setup.sh %{buildroot}%{_datadir}/%{name}/bazzite/kde-desktop-setup.sh
|
||||
install -Dm0644 docs/api/openapi.json %{buildroot}%{_datadir}/%{name}/openapi.json
|
||||
install -Dm0644 api/openapi.json %{buildroot}%{_datadir}/%{name}/openapi.json
|
||||
|
||||
%if %{with web}
|
||||
# --- web console subpackage (punktfunk-web) ---
|
||||
@@ -246,7 +246,7 @@ install -Dm0644 web/web.env.example %{buildroot}%{_datadir}/punkt
|
||||
|
||||
%files
|
||||
%license LICENSE-MIT LICENSE-APACHE
|
||||
%doc README.md docs/implementation-plan.md packaging/README.md
|
||||
%doc README.md design/implementation-plan.md packaging/README.md
|
||||
%{_bindir}/punktfunk-host
|
||||
%{_udevrulesdir}/60-punktfunk.rules
|
||||
%{_prefix}/lib/sysctl.d/99-punktfunk-net.conf
|
||||
|
||||
@@ -76,10 +76,11 @@ read it from `%ProgramData%\punktfunk\web-password`.
|
||||
| `reset-pf-vdisplay.ps1` | **Dev:** recover a wedged driver — stop host → reap ghost monitor nodes → reload the adapter → start host (no reboot). See *Dev iteration* below. |
|
||||
| `redeploy-pf-vdisplay.ps1` | **Dev:** one-shot redeploy — (optional) build → stop host → `deploy-dev.ps1 -Install` → reload adapter → start host. |
|
||||
| `nvenc/nvenc.def`, `nvenc/gen-nvenc-importlib.ps1` | Synthesise `nvencodeapi.lib` for the `--features nvenc` link (llvm-dlltool / lib.exe). |
|
||||
| `pf-vkhdr-layer/` | **HDR Vulkan layer** (standalone `cdylib`): lets Vulkan games (Doom: The Dark Ages, etc.) enable HDR over the virtual display by advertising the HDR surface formats the NVIDIA/AMD ICDs hide on an indirect display. Built by the packer, laid into `{app}\vklayer`, registered under `HKLM64\…\Khronos\Vulkan\ImplicitLayers` (opt-out *Install the HDR Vulkan layer* task). Self-gated on the display's HDR state. See its README. |
|
||||
|
||||
> **Vendored driver:** pf-vdisplay is our **all-Rust IddCx** virtual display (UMDF2), built from
|
||||
> `packaging/windows/drivers/`. It replaced the vendored SudoVDA C++ driver — full story in
|
||||
> [`docs/windows-virtual-display-rust-port.md`](../../docs/windows-virtual-display-rust-port.md). The
|
||||
> [`design/windows-virtual-display-rust-port.md`](../../design/windows-virtual-display-rust-port.md). The
|
||||
> **signed** output (`pf_vdisplay.dll`/`.inf`/`.cat` + `punktfunk-driver.cer`; signer
|
||||
> `punktfunk-ds-test` — the same cert the gamepad drivers ship, Class=Display, HWID `root\pf_vdisplay`)
|
||||
> is checked in under `pf-vdisplay/`. To refresh it after a driver-source change, rebuild + re-sign with
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Unified in-tree workspace for punktfunk's all-Rust UMDF drivers, on microsoft/windows-drivers-rs
|
||||
# (crates.io wdk/wdk-sys/wdk-build — NOT the dev-box ../../crates/wdk* path-deps). Part of the
|
||||
# Windows-host rewrite (docs/windows-host-rewrite.md, M1). pf-vdisplay + the gamepad drivers move here.
|
||||
# Windows-host rewrite (design/windows-host-rewrite.md, M1). pf-vdisplay + the gamepad drivers move here.
|
||||
#
|
||||
# Separate from the main cargo workspace (own [workspace] root) because driver crates are cdylibs built
|
||||
# with the WDK toolchain (cargo-wdk / wdk-build) on Windows only. Path-deps the shared ABI crate
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# pf-vdisplay — the all-Rust UMDF IddCx virtual-display driver (M1 step-2 rewrite onto wdk-sys + the
|
||||
# owned pf-driver-proto ABI). Replaces the vendored-binding oracle at packaging/windows/vdisplay-driver/
|
||||
# (deleted once on-glass parity is reached, per docs/windows-host-rewrite.md §14 STEP 8).
|
||||
# (deleted once on-glass parity is reached, per design/windows-host-rewrite.md §14 STEP 8).
|
||||
[package]
|
||||
name = "pf-vdisplay"
|
||||
edition.workspace = true
|
||||
|
||||
@@ -137,7 +137,7 @@ pub(crate) fn adapter() -> Option<iddcx::IDDCX_ADAPTER> {
|
||||
/// iGPU+dGPU box the OS may otherwise pick the iGPU to render the virtual monitor, so the host's shared
|
||||
/// ring textures (created on the NVENC dGPU) can't be opened → `DRV_STATUS_TEX_FAIL` → the host's 20 s
|
||||
/// black bail. Pinning the render adapter to the encode GPU fixes that. Unconditional — NOT the
|
||||
/// SudoVDA-parity default-off branch (`docs/windows-host-rewrite.md` §2.8). Returns
|
||||
/// SudoVDA-parity default-off branch (`design/windows-host-rewrite.md` §2.8). Returns
|
||||
/// `STATUS_NOT_FOUND` if called before the adapter exists.
|
||||
pub fn set_render_adapter(luid_low: u32, luid_high: i32) -> NTSTATUS {
|
||||
let Some(adapter) = adapter() else {
|
||||
|
||||
@@ -27,7 +27,7 @@ static WATCHDOG_STARTED: AtomicBool = AtomicBool::new(false);
|
||||
/// without a cooperative REMOVE (crash / `TerminateProcess`) left its virtual monitor + swap-chain
|
||||
/// worker + pooled D3D device wedged in WUDFHost until the next host start's CLEAR_ALL, and a
|
||||
/// not-restarted host left the orphan monitor in the desktop topology indefinitely
|
||||
/// (`docs/windows-host-rewrite.md` §2.8). This thread closes that: if no IOCTL arrives for
|
||||
/// (`design/windows-host-rewrite.md` §2.8). This thread closes that: if no IOCTL arrives for
|
||||
/// `WATCHDOG_TIMEOUT_S` while monitors exist, it departs them all.
|
||||
///
|
||||
/// (A WDF `EvtFileClose` on the control handle would be more immediate — the plan's preferred §3.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! pf-vdisplay — the all-Rust UMDF IddCx virtual-display driver (M1 step-2 rewrite, on wdk-sys + the
|
||||
//! owned pf-driver-proto ABI). See docs/windows-host-rewrite.md §14 for the full port plan.
|
||||
//! owned pf-driver-proto ABI). See design/windows-host-rewrite.md §14 for the full port plan.
|
||||
//!
|
||||
//! STEP 2: the IddCx driver SKELETON — DriverEntry → driver_add builds the full `IDD_CX_CLIENT_CONFIG`
|
||||
//! (14 IddCx callbacks + the PnP `EvtDeviceD0Entry`, all stubs) sized via the versioned
|
||||
|
||||
@@ -205,5 +205,5 @@ cat <<'NEXT'
|
||||
export XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-1
|
||||
swaymsg -t get_outputs # confirm HEADLESS-1
|
||||
bash scripts/headless/capture-smoke-test.sh # wf-recorder -> hevc_nvenc -> /tmp/*.mkv
|
||||
5. Then start M0 proper: see docs/linux-setup.md.
|
||||
5. Then start M0 proper: see design/linux-setup.md.
|
||||
NEXT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Provision the Windows Driver Kit (WDK) + cargo-wdk on the self-hosted windows-amd64 runner, so the
|
||||
# all-Rust UMDF drivers (pf-vdisplay + the gamepad drivers, unified on microsoft/windows-drivers-rs)
|
||||
# can build there. See docs/windows-host-rewrite.md (M0).
|
||||
# can build there. See design/windows-host-rewrite.md (M0).
|
||||
#
|
||||
# The runner already has the base Windows SDK 10.0.26100 (um/ headers) + MSVC + LLVM + Rust, but NOT the
|
||||
# WDK — no km/ + wdf/ + um/iddcx headers, no inf2cat/stampinf/devgen. wdk-sys's bindgen needs those.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# ScreenCast portal (xdg-desktop-portal-wlr) and the punktfunk host share one bus. After this
|
||||
# is up, run `prepare-session.sh` from a second shell to set the mode + portal env.
|
||||
#
|
||||
# Prereqs (see docs/linux-setup.md / scripts/bootstrap-ubuntu.sh):
|
||||
# Prereqs (see design/linux-setup.md / scripts/bootstrap-ubuntu.sh):
|
||||
# - nvidia-drm.modeset=Y
|
||||
# - the NVIDIA GL/EGL userspace (libnvidia-gl-NNN) — provides libEGL_nvidia + the GLVND
|
||||
# vendor JSON; without it wlroots can't init EGL on the GPU and falls back to pixman,
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# punktfunk management console — TanStack Start built with Bun, served by the Nitro `bun`
|
||||
# preset bundle. Build context is the REPO ROOT (orval generates the API client from
|
||||
# docs/api/openapi.json, referenced as ../docs/api/openapi.json from web/):
|
||||
# api/openapi.json, referenced as ../api/openapi.json from web/):
|
||||
#
|
||||
# docker build -f web/Dockerfile -t punktfunk-web .
|
||||
#
|
||||
@@ -15,7 +15,7 @@ WORKDIR /repo/web
|
||||
COPY web/package.json web/bun.lock ./
|
||||
RUN bun install --frozen-lockfile --ignore-scripts
|
||||
|
||||
COPY docs/api/openapi.json /repo/docs/api/openapi.json
|
||||
COPY api/openapi.json /repo/api/openapi.json
|
||||
COPY web/ ./
|
||||
# prebuild runs orval (openapi → src/api/gen); the paraglide vite plugin compiles i18n.
|
||||
RUN bun run build
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# punktfunk web — management console
|
||||
|
||||
The browser UI for the punktfunk host's **management REST API** (`crates/punktfunk-host/src/mgmt.rs`,
|
||||
OpenAPI at `docs/api/openapi.json`). It shows live status, host capabilities, paired
|
||||
OpenAPI at `api/openapi.json`). It shows live status, host capabilities, paired
|
||||
clients, the pairing-PIN flow, and session controls.
|
||||
|
||||
Stack: **TanStack Start** (full SSR) on **Bun** via **Nitro v2** (`bun` preset) · **React
|
||||
@@ -88,7 +88,7 @@ Generated code is **not committed** (gitignored) — reproduced from sources:
|
||||
`bun install` (`prepare`) and before `dev`/`build` (`pre*` for orval; the Vite plugin
|
||||
compiles paraglide on dev/build).
|
||||
- After a management-API change, regenerate the spec on the Rust side first:
|
||||
`cargo run -p punktfunk-host -- openapi > docs/api/openapi.json`, then `bun run api:gen`.
|
||||
`cargo run -p punktfunk-host -- openapi > api/openapi.json`, then `bun run api:gen`.
|
||||
|
||||
## Layout
|
||||
|
||||
|
||||
+2
-2
@@ -2,11 +2,11 @@ import { defineConfig } from "orval";
|
||||
|
||||
// Generates a typed React Query client from the host's checked-in OpenAPI document.
|
||||
// Regenerate after any management-API change: `pnpm api:gen` (the Rust side regenerates
|
||||
// docs/api/openapi.json via `cargo run -p punktfunk-host -- openapi`).
|
||||
// api/openapi.json via `cargo run -p punktfunk-host -- openapi`).
|
||||
export default defineConfig({
|
||||
punktfunk: {
|
||||
input: {
|
||||
target: "../docs/api/openapi.json",
|
||||
target: "../api/openapi.json",
|
||||
},
|
||||
output: {
|
||||
mode: "tags-split",
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
/* ── punktfunk brand · violet product chrome ────────────────────────────────
|
||||
Two themes on one violet identity: LIGHT (lavender docs surface — the same
|
||||
palette the docs/Scalar reference uses: white bg, faint-violet cards/borders,
|
||||
palette the design/Scalar reference uses: white bg, faint-violet cards/borders,
|
||||
#6c5bf3 brand) is the :root default; DARK (the violet-tinted app-icon chrome
|
||||
#141019 / #1c1530, #a79ff8 brand) is the `.dark` override. The live console
|
||||
pins `<html class="dark">` so it stays dark by default — removing or toggling
|
||||
|
||||
Reference in New Issue
Block a user