feat(abi): expose the host-resolved compositor to clients
ci / docs-site (push) Successful in 30s
apple / swift (push) Successful in 1m13s
ci / bench (push) Successful in 1m39s
ci / web (push) Successful in 30s
ci / rust (push) Successful in 2m3s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
deb / build-publish (push) Successful in 2m24s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 4m46s
docker / deploy-docs (push) Successful in 17s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 4m23s
ci / docs-site (push) Successful in 30s
apple / swift (push) Successful in 1m13s
ci / bench (push) Successful in 1m39s
ci / web (push) Successful in 30s
ci / rust (push) Successful in 2m3s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
deb / build-publish (push) Successful in 2m24s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 4m46s
docker / deploy-docs (push) Successful in 17s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 4m23s
Add punktfunk_connection_compositor() (mirrors punktfunk_connection_gamepad): a client getter for the compositor the host actually resolved for the session, read from Welcome.compositor and threaded through NativeClient.resolved_compositor. The Apple/Linux clients use it to enable the client-side cursor by default on gamescope sessions, whose PipeWire capture carries no cursor (verified upstream). Header regenerated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1294,6 +1294,35 @@ pub unsafe extern "C" fn punktfunk_connection_gamepad(
|
||||
})
|
||||
}
|
||||
|
||||
/// The compositor backend the host actually resolved for this session (one of the
|
||||
/// `PUNKTFUNK_COMPOSITOR_*` values; the `Welcome`'s echo of the [`punktfunk_connect_ex`]
|
||||
/// preference). `PUNKTFUNK_COMPOSITOR_AUTO` = an older host that didn't say. Clients use it for
|
||||
/// compositor-specific behavior — e.g. a client-side cursor by default on
|
||||
/// `PUNKTFUNK_COMPOSITOR_GAMESCOPE`, whose PipeWire capture carries no cursor. Safe any time after
|
||||
/// connect.
|
||||
///
|
||||
/// # Safety
|
||||
/// `c` is a valid connection handle; `compositor` is writable (NULL is skipped).
|
||||
#[cfg(feature = "quic")]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn punktfunk_connection_compositor(
|
||||
c: *const PunktfunkConnection,
|
||||
compositor: *mut u32,
|
||||
) -> PunktfunkStatus {
|
||||
guard(|| {
|
||||
let c = match unsafe { c.as_ref() } {
|
||||
Some(c) => c,
|
||||
None => return PunktfunkStatus::NullPointer,
|
||||
};
|
||||
unsafe {
|
||||
if !compositor.is_null() {
|
||||
*compositor = c.inner.resolved_compositor.to_u8() as u32;
|
||||
}
|
||||
}
|
||||
PunktfunkStatus::Ok
|
||||
})
|
||||
}
|
||||
|
||||
/// The video encoder bitrate (kilobits per second) the host actually configured for this session
|
||||
/// — the [`punktfunk_connect_ex3`] request clamped to the host's range, or its default when `0`
|
||||
/// was requested. `0` = an older host that didn't report it. Safe any time after connect.
|
||||
|
||||
@@ -36,10 +36,10 @@ enum CtrlRequest {
|
||||
}
|
||||
|
||||
/// What the worker reports to [`NativeClient::connect`] once the handshake lands: the negotiated
|
||||
/// mode, the host-resolved gamepad backend, the host's certificate fingerprint, the resolved
|
||||
/// encoder bitrate (kbps), and the host↔client clock offset (ns, host minus client; 0 = no skew
|
||||
/// correction / an old host that didn't answer the handshake).
|
||||
type Negotiated = (Mode, GamepadPref, [u8; 32], u32, i64);
|
||||
/// mode, the host-resolved compositor backend, the host-resolved gamepad backend, the host's
|
||||
/// certificate fingerprint, the resolved encoder bitrate (kbps), and the host↔client clock offset
|
||||
/// (ns, host minus client; 0 = no skew correction / an old host that didn't answer the handshake).
|
||||
type Negotiated = (Mode, CompositorPref, GamepadPref, [u8; 32], u32, i64);
|
||||
|
||||
/// Accumulated state of an in-flight / finished speed test. The data-plane pump folds each
|
||||
/// received [`FLAG_PROBE`] access unit in; the control task records the host's [`ProbeResult`]
|
||||
@@ -135,6 +135,10 @@ pub struct NativeClient {
|
||||
/// SHA-256 fingerprint of the certificate the host actually presented. A TOFU caller
|
||||
/// (`pin = None`) persists this and passes it as the pin from then on.
|
||||
pub host_fingerprint: [u8; 32],
|
||||
/// The compositor backend the host actually resolved for this session ([`Welcome::compositor`]).
|
||||
/// `Auto` = an older host that didn't say. Clients use it for compositor-specific behavior (e.g.
|
||||
/// drawing a client-side cursor by default on gamescope, whose capture carries no cursor).
|
||||
pub resolved_compositor: CompositorPref,
|
||||
/// The virtual gamepad backend the host actually resolved ([`Welcome::gamepad`]).
|
||||
/// `Auto` = an older host that didn't say (assume X-Box 360, no DualSense feedback).
|
||||
pub resolved_gamepad: GamepadPref,
|
||||
@@ -228,8 +232,14 @@ impl NativeClient {
|
||||
})
|
||||
.map_err(PunktfunkError::Io)?;
|
||||
|
||||
let (negotiated, resolved_gamepad, fingerprint, resolved_bitrate_kbps, clock_offset_ns) =
|
||||
match ready_rx.recv_timeout(timeout) {
|
||||
let (
|
||||
negotiated,
|
||||
resolved_compositor,
|
||||
resolved_gamepad,
|
||||
fingerprint,
|
||||
resolved_bitrate_kbps,
|
||||
clock_offset_ns,
|
||||
) = match ready_rx.recv_timeout(timeout) {
|
||||
Ok(Ok(t)) => t,
|
||||
Ok(Err(e)) => return Err(e),
|
||||
Err(_) => {
|
||||
@@ -252,6 +262,7 @@ impl NativeClient {
|
||||
worker: Some(worker),
|
||||
mode: mode_slot,
|
||||
host_fingerprint: fingerprint,
|
||||
resolved_compositor,
|
||||
resolved_gamepad,
|
||||
resolved_bitrate_kbps,
|
||||
clock_offset_ns,
|
||||
@@ -661,6 +672,7 @@ async fn worker_main(args: WorkerArgs) {
|
||||
send,
|
||||
recv,
|
||||
welcome.mode,
|
||||
welcome.compositor,
|
||||
welcome.gamepad,
|
||||
fingerprint,
|
||||
welcome.bitrate_kbps,
|
||||
@@ -674,6 +686,7 @@ async fn worker_main(args: WorkerArgs) {
|
||||
mut ctrl_send,
|
||||
mut ctrl_recv,
|
||||
negotiated,
|
||||
resolved_compositor,
|
||||
resolved_gamepad,
|
||||
fingerprint,
|
||||
resolved_bitrate_kbps,
|
||||
@@ -687,6 +700,7 @@ async fn worker_main(args: WorkerArgs) {
|
||||
};
|
||||
let _ = ready_tx.send(Ok((
|
||||
negotiated,
|
||||
resolved_compositor,
|
||||
resolved_gamepad,
|
||||
fingerprint,
|
||||
resolved_bitrate_kbps,
|
||||
|
||||
@@ -801,6 +801,19 @@ PunktfunkStatus punktfunk_connection_mode(const PunktfunkConnection *c,
|
||||
PunktfunkStatus punktfunk_connection_gamepad(const PunktfunkConnection *c, uint32_t *gamepad);
|
||||
#endif
|
||||
|
||||
#if defined(PUNKTFUNK_FEATURE_QUIC)
|
||||
// The compositor backend the host actually resolved for this session (one of the
|
||||
// `PUNKTFUNK_COMPOSITOR_*` values; the `Welcome`'s echo of the [`punktfunk_connect_ex`]
|
||||
// preference). `PUNKTFUNK_COMPOSITOR_AUTO` = an older host that didn't say. Clients use it for
|
||||
// compositor-specific behavior — e.g. a client-side cursor by default on
|
||||
// `PUNKTFUNK_COMPOSITOR_GAMESCOPE`, whose PipeWire capture carries no cursor. Safe any time after
|
||||
// connect.
|
||||
//
|
||||
// # Safety
|
||||
// `c` is a valid connection handle; `compositor` is writable (NULL is skipped).
|
||||
PunktfunkStatus punktfunk_connection_compositor(const PunktfunkConnection *c, uint32_t *compositor);
|
||||
#endif
|
||||
|
||||
#if defined(PUNKTFUNK_FEATURE_QUIC)
|
||||
// The video encoder bitrate (kilobits per second) the host actually configured for this session
|
||||
// — the [`punktfunk_connect_ex3`] request clamped to the host's range, or its default when `0`
|
||||
|
||||
Reference in New Issue
Block a user